calculateValue method
dynamic
calculateValue()
Implementation
calculateValue() {
if (datas == null) return;
if (datas!.isEmpty) return;
// 如果用户配置了要显示DMI,则先计算DMI
// if (secondaryStates.contains(SecondaryState.DMI)) {
// _computeDMI(datas!); // period可自定义
// }
// 如果用户勾选了DMI, 就内部计算DMI
// if (secondaryStates.contains(SecondaryState.DMI)) {
// _computeDMIAdvanced(
// datas!,
// period: 14,
// useAdxr: true, // 要不要计算ADXR
// adxrPeriod: 14,
// smoothMethod: 'ema', // 这里演示"双重平滑"
// );
// }
maxScrollX = getMinTranslateX().abs();
setTranslateXFromScrollX(scrollX);
mStartIndex = indexOfTranslateX(xToTranslateX(0));
mStopIndex = indexOfTranslateX(xToTranslateX(mWidth));
for (int i = mStartIndex; i <= mStopIndex; i++) {
var item = datas![i];
getMainMaxMinValue(item, i);
getVolMaxMinValue(item);
// getSecondaryMaxMinValue(item);
// 3)更新每个 SecondaryState 的最大最小值
for (final st in secondaryStates) {
double oldMax = mSecondaryMaxMap[st] ?? double.minPositive;
double oldMin = mSecondaryMinMap[st] ?? double.maxFinite;
double newMax = oldMax;
double newMin = oldMin;
if (st == SecondaryState.VOLATILITY) {
double? val = item.volIndicator;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.ENVELOPES) {
// 3条线: envMid, envUp, envDn
if (item.envMid != null && item.envMid!.isFinite) {
if (item.envMid! > newMax) newMax = item.envMid!;
if (item.envMid! < newMin) newMin = item.envMid!;
}
if (item.envUp != null && item.envUp!.isFinite) {
if (item.envUp! > newMax) newMax = item.envUp!;
if (item.envUp! < newMin) newMin = item.envUp!;
}
if (item.envDn != null && item.envDn!.isFinite) {
if (item.envDn! > newMax) newMax = item.envDn!;
if (item.envDn! < newMin) newMin = item.envDn!;
}
} else if (st == SecondaryState.MFI) {
double? mfiVal = item.mfi;
if (mfiVal != null && mfiVal.isFinite) {
if (mfiVal > newMax) newMax = mfiVal;
if (mfiVal < newMin) newMin = mfiVal;
}
} else if (st == SecondaryState.MOMENTUM) {
double? val = item.momentum;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.DEMARKER) {
double? demVal = item.dem;
if (demVal != null && demVal.isFinite) {
if (demVal > newMax) newMax = demVal;
if (demVal < newMin) newMin = demVal;
}
} else if (st == SecondaryState.WPR) {
double? wVal = item.wpr;
if (wVal != null && wVal.isFinite) {
// 常见 wVal在 -100..0
// 但为了兼容,还是正常比较
if (wVal > newMax) newMax = wVal;
if (wVal < newMin) newMin = wVal;
}
} else if (st == SecondaryState.STOCHASTIC) {
// stochK, stochD
double? kVal = item.stochK;
double? dVal = item.stochD;
if (kVal != null && kVal.isFinite) {
if (kVal > newMax) newMax = kVal;
if (kVal < newMin) newMin = kVal;
}
if (dVal != null && dVal.isFinite) {
if (dVal > newMax) newMax = dVal;
if (dVal < newMin) newMin = dVal;
}
} else if (st == SecondaryState.STDDEV) {
double? val = item.stdDev;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.ADX) {
double? adxVal = item.adx;
if (adxVal != null && adxVal.isFinite) {
if (adxVal > newMax) newMax = adxVal;
if (adxVal < newMin) newMin = adxVal;
}
} else if (st == SecondaryState.VIX) {
double? v = item.vix;
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
} else if (st == SecondaryState.ADL) {
double? v = item.adl;
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
} else if (st == SecondaryState.OBV) {
// 这里可纳入obvEma(更平滑) or obv(原始) 作为坐标
double? val = item.obvEma; // 优先看平滑
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.VWAP) {
double? v = item.vwap;
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
} else if (st == SecondaryState.HV) {
double? hvVal = item.hv;
if (hvVal != null && hvVal.isFinite) {
if (hvVal > newMax) newMax = hvVal;
if (hvVal < newMin) newMin = hvVal;
}
} else if (st == SecondaryState.ATR) {
double? a = item.atr;
if (a != null && a.isFinite) {
if (a > newMax) newMax = a;
if (a < newMin) newMin = a;
}
} else if (st == SecondaryState.SUPER_TREND) {
final List<double?> vals = [
item.superTrend,
item.superTrendUpper,
item.superTrendLower,
];
for (final v in vals) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.STC) {
final double? val = item.stc;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.QQE) {
final List<double?> vals = [item.qqe, item.qqeSignal];
for (final v in vals) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.WAVE_TREND) {
final List<double?> vals = [item.waveTrend1, item.waveTrend2];
for (final v in vals) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.CMO) {
final double? val = item.cmo;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.EOM) {
final double? val = item.eom;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.PVI_NVI) {
final List<double?> vals = [item.pvi, item.nvi];
for (final v in vals) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.VORTEX) {
// item.viPlus, item.viMinus
double? viplus = item.viPlus;
double? viminus = item.viMinus;
if (viplus != null && viplus.isFinite) {
if (viplus > newMax) newMax = viplus;
if (viplus < newMin) newMin = viplus;
}
if (viminus != null && viminus.isFinite) {
if (viminus > newMax) newMax = viminus;
if (viminus < newMin) newMin = viminus;
}
} else if (st == SecondaryState.AROON) {
// item.aroonUp, item.aroonDown, item.aroonOsc
double? up = item.aroonUp;
double? down = item.aroonDown;
double? osc = item.aroonOsc; // 若calcOsc=true
// 依次更新
if (up != null && up.isFinite) {
if (up > newMax) newMax = up;
if (up < newMin) newMin = up;
}
if (down != null && down.isFinite) {
if (down > newMax) newMax = down;
if (down < newMin) newMin = down;
}
if (osc != null && osc.isFinite) {
if (osc > newMax) newMax = osc;
if (osc < newMin) newMin = osc;
}
} else if (st == SecondaryState.SAR) {
// 只存一条 psar
final psarVal = item.psar;
if (psarVal != null && psarVal.isFinite) {
if (psarVal > newMax) newMax = psarVal;
if (psarVal < newMin) newMin = psarVal;
}
} else if (st == SecondaryState.ICHIMOKU) {
// 5条线: Tenkan, Kijun, SpanA, SpanB, Chikou
final lines = [
item.ichimokuTenkan,
item.ichimokuKijun,
item.ichimokuSpanA,
item.ichimokuSpanB,
item.ichimokuChikou,
];
for (var val in lines) {
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
}
} else if (st == SecondaryState.TSI) {
// TSI + 信号线
if (item.tsi != null && item.tsiSignal != null) {
if (item.tsi!.isFinite) {
newMax = newMax > item.tsi! ? newMax : item.tsi!;
newMin = newMin < item.tsi! ? newMin : item.tsi!;
}
if (item.tsiSignal!.isFinite) {
newMax = newMax > item.tsiSignal! ? newMax : item.tsiSignal!;
newMin = newMin < item.tsiSignal! ? newMin : item.tsiSignal!;
}
}
} else if (st == SecondaryState.PPO) {
// 这里给PPO主线 + PPO信号线 做max/min
if (item.ppo != null && item.ppoSignal != null) {
double ppoVal = item.ppo!;
double ppoSig = item.ppoSignal!;
if (ppoVal.isFinite) {
newMax = newMax > ppoVal ? newMax : ppoVal;
newMin = newMin < ppoVal ? newMin : ppoVal;
}
if (ppoSig.isFinite) {
newMax = newMax > ppoSig ? newMax : ppoSig;
newMin = newMin < ppoSig ? newMin : ppoSig;
}
}
} else if (st == SecondaryState.TRIX) {
// 和MACD/KDJ类似,获取TRIX和其Signal线的值
if (item.trix != null && item.trixSignal != null) {
// 这里只示例主线/信号线各一个
// 如果你自己还想多画别的线,可以都加进reduce
newMax = [oldMax, item.trix!, item.trixSignal!]
.reduce((a, b) => a > b ? a : b);
newMin = [oldMin, item.trix!, item.trixSignal!]
.reduce((a, b) => a < b ? a : b);
}
} else if (st == SecondaryState.DMI) {
// pdi, mdi, adx, adxr
if (item.pdi != null && item.mdi != null && item.adx != null) {
// 这里假设你还需要adxr,可以一起写,否则省略
newMax = [
oldMax,
item.pdi!,
item.mdi!,
item.adx!,
if (item.adxr != null) item.adxr!
].reduce((a, b) => a > b ? a : b);
newMin = [
oldMin,
item.pdi!,
item.mdi!,
item.adx!,
if (item.adxr != null) item.adxr!
].reduce((a, b) => a < b ? a : b);
}
} else if (st == SecondaryState.MACD) {
// item.macd, item.dif, item.dea
if (item.macd != null && item.dif != null && item.dea != null) {
newMax = [oldMax, item.macd!, item.dif!, item.dea!, item.osma!]
.reduce((a, b) => a > b ? a : b);
newMin = [oldMin, item.macd!, item.dif!, item.dea!, item.osma!]
.reduce((a, b) => a < b ? a : b);
}
// double? val = item.osma;
// if (val != null && val.isFinite) {
// if (val > newMax) newMax = val;
// if (val < newMin) newMin = val;
// }
} else if (st == SecondaryState.KDJ) {
// item.k, item.d, item.j
if (item.k != null && item.d != null && item.j != null) {
newMax = [oldMax, item.k!, item.d!, item.j!]
.reduce((a, b) => a > b ? a : b);
newMin = [oldMin, item.k!, item.d!, item.j!]
.reduce((a, b) => a < b ? a : b);
}
} else if (st == SecondaryState.RSI) {
// item.rsi
if (item.rsi != null) {
newMax = newMax > item.rsi! ? newMax : item.rsi!;
newMin = newMin < item.rsi! ? newMin : item.rsi!;
}
} else if (st == SecondaryState.WR) {
// WR 通常范围 [-100, 0], 也可自行判定
newMax = newMax > 0 ? newMax : 0;
newMin = newMin < -100 ? newMin : -100;
} else if (st == SecondaryState.CCI) {
if (item.cci != null) {
newMax = math.max(newMax, item.cci!);
newMin = math.min(newMin, item.cci!);
}
} else if (st == SecondaryState.CMF) {
final val = item.cmf;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.CHAIKIN_OSC) {
final val = item.chaikinOscillator;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.KLINGER) {
final values = [item.kvo, item.kvoSignal];
for (final v in values) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.VPT) {
final val = item.vpt;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.FORCE) {
final val = item.forceIndex;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.ROC) {
final values = [item.roc, item.rocSignal];
for (final v in values) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.ULTIMATE) {
final val = item.ultimateOsc;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.CONNORS_RSI) {
final val = item.connorsRsi;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.STOCH_RSI) {
final values = [item.stochRsiK, item.stochRsiD];
for (final v in values) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.RVI) {
final values = [item.rvi, item.rviSignal];
for (final v in values) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.DPO) {
final val = item.dpo;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.KAMA) {
final val = item.kama;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.HMA) {
final val = item.hma;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.KELTNER) {
final values = [
item.keltnerUpper,
item.keltnerMiddle,
item.keltnerLower,
];
for (final v in values) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.DONCHIAN) {
final values = [
item.donchianUpper,
item.donchianMiddle,
item.donchianLower,
];
for (final v in values) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.BOLL_BANDWIDTH) {
final val = item.bollBandwidth;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.CHAIKIN_VOLATILITY) {
final val = item.chaikinVolatility;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.HV_PERCENTILE) {
final val = item.hvPercentile;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.ATR_PERCENTILE) {
final val = item.atrPercentile;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.ELDER_RAY) {
final values = [item.elderBull, item.elderBear];
for (final v in values) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.ICHIMOKU_SPAN) {
final val = item.ichimokuSpanDiff;
if (val != null && val.isFinite) {
if (val > newMax) newMax = val;
if (val < newMin) newMin = val;
}
} else if (st == SecondaryState.PIVOT) {
final values = [
item.pivot,
item.pivotR1,
item.pivotR2,
item.pivotR3,
item.pivotS1,
item.pivotS2,
item.pivotS3,
];
for (final v in values) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
} else if (st == SecondaryState.GANN_FAN) {
final values = [item.gann1x1, item.gann1x2, item.gann2x1];
for (final v in values) {
if (v != null && v.isFinite) {
if (v > newMax) newMax = v;
if (v < newMin) newMin = v;
}
}
}
// 回写到 Map
mSecondaryMaxMap[st] = newMax;
mSecondaryMinMap[st] = newMin;
// print('[getSecondaryMaxMinValue] Max: $newMax, Min: $newMin');
}
}
}