研究一个月了总是信号闪烁,谁懂这种煎熬呀
//------------------------------------------------------------------------// 简称: 三周期共振// 数据源顺序: Data[0]=15分钟 Data[1]=1小时 Data[2]=1日//------------------------------------------------------------------------// 过滤体系(全部去除MACD):// 日线: MA60多头 + KDJ(J>D) + ADX>adxThreshold// 1小时: MA60多头 + KDJ(J>D) + ADX>adxThreshold// 15分钟: MA60多头 + J上穿D金叉(穿越) ← 不用MACD不用ADX// 不闪: 判断全用[1]定型值 + 委托价全Data[0].Open// 同根K线单动作: bar序号锁gLastActionBar, 盘中每tick锁有效// ADX: TBQ老版无内建函数, 按开拓者社区Wilder算法手写//------------------------------------------------------------------------Params Numeric maLen(60); Numeric kdjLen(9); Numeric trailPct(1.0); Numeric adxLen(14); Numeric adxThreshold(20);Vars Series<Numeric> ma60m; Series<Numeric> hhNm; Series<Numeric> llNm; Series<Numeric> rsvm; Series<Numeric> kdm; Series<Numeric> ddm; Series<Numeric> jjm; Series<Numeric> ma60h; Series<Numeric> hhNh; Series<Numeric> llNh; Series<Numeric> rsvh; Series<Numeric> kdh; Series<Numeric> ddh; Series<Numeric> jjh; Series<Numeric> ma60d; Series<Numeric> hhNd; Series<Numeric> llNd; Series<Numeric> rsvd; Series<Numeric> kdd; Series<Numeric> ddd; Series<Numeric> jjd; // 1小时 ADX 计算 Numeric upMoveH; Numeric dnMoveH; Numeric plusDmH; Numeric minusDmH; Numeric trvH; Numeric sfH; Numeric dxValH; Numeric iH; Numeric sumPlusH; Numeric sumMinusH; Numeric sumTrH; Series<Numeric> avgPlusDH; Series<Numeric> avgMinusDH; Series<Numeric> trValH; Series<Numeric> diPlusH; Series<Numeric> diMinusH; Series<Numeric> cumDxH; Series<Numeric> adxH; // 日线 ADX 计算 Numeric upMoveD; Numeric dnMoveD; Numeric plusDmD; Numeric minusDmD; Numeric trvD; Numeric sfD; Numeric dxValD; Numeric iD; Numeric sumPlusD; Numeric sumMinusD; Numeric sumTrD; Series<Numeric> avgPlusDD; Series<Numeric> avgMinusDD; Series<Numeric> trValD; Series<Numeric> diPlusD; Series<Numeric> diMinusD; Series<Numeric> cumDxD; Series<Numeric> adxD; Bool d1L; Bool d1S; Bool h1L; Bool h1S; Bool m15L; Bool m15S; Bool upC; Bool dnC; Bool openL; Bool openS; Global Numeric gLongHigh(0); Global Numeric gShortLow(0); Global Numeric gLastActionBar(-1);Events OnInit() { AddDataFlag(Enum_Data_RolloverBackWard()); AddDataFlag(Enum_Data_RolloverRealPrice()); AddDataFlag(Enum_Data_AutoSwapPosition()); AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); SetInitCapital(100000); } OnBar(ArrayRef<Integer> indexs) { ma60m = AverageFC(Data[0].Close, maLen); hhNm = Highest(Data[0].High, kdjLen); llNm = Lowest(Data[0].Low, kdjLen); rsvm = 50; If(hhNm - llNm > 0) rsvm = (Data[0].Close - llNm) / (hhNm - llNm) * 100; kdm = SMA(rsvm, 3, 1); ddm = SMA(kdm, 3, 1); jjm = 3 * kdm - 2 * ddm; ma60h = AverageFC(Data[1].Close, maLen); hhNh = Highest(Data[1].High, kdjLen); llNh = Lowest(Data[1].Low, kdjLen); rsvh = 50; If(hhNh - llNh > 0) rsvh = (Data[1].Close - llNh) / (hhNh - llNh) * 100; kdh = SMA(rsvh, 3, 1); ddh = SMA(kdh, 3, 1); jjh = 3 * kdh - 2 * ddh; ma60d = AverageFC(Data[2].Close, maLen); hhNd = Highest(Data[2].High, kdjLen); llNd = Lowest(Data[2].Low, kdjLen); rsvd = 50; If(hhNd - llNd > 0) rsvd = (Data[2].Close - llNd) / (hhNd - llNd) * 100; kdd = SMA(rsvd, 3, 1); ddd = SMA(kdd, 3, 1); jjd = 3 * kdd - 2 * ddd; // ===================== 1小时 ADX (Wilder) ===================== sfH = 1.0 / adxLen; upMoveH = Data[1].High - Data[1].High[1]; dnMoveH = Data[1].Low[1] - Data[1].Low; plusDmH = 0; minusDmH = 0; If(upMoveH > dnMoveH And upMoveH > 0) plusDmH = upMoveH; If(dnMoveH > upMoveH And dnMoveH > 0) minusDmH = dnMoveH; trvH = Max(Data[1].High - Data[1].Low, Max(Abs(Data[1].High - Data[1].Close[1]), Abs(Data[1].Low - Data[1].Close[1]))); If(Data[1].CurrentBar == adxLen) { sumPlusH = 0; sumMinusH = 0; sumTrH = 0; For iH = 0 To adxLen - 1 { upMoveH = Data[1].High[iH] - Data[1].High[iH + 1]; dnMoveH = Data[1].Low[iH + 1] - Data[1].Low[iH]; plusDmH = 0; minusDmH = 0; If(upMoveH > dnMoveH And upMoveH > 0) plusDmH = upMoveH; If(dnMoveH > upMoveH And dnMoveH > 0) minusDmH = dnMoveH; sumPlusH = sumPlusH + plusDmH; sumMinusH = sumMinusH + minusDmH; sumTrH = sumTrH + Max(Data[1].High[iH] - Data[1].Low[iH], Max(Abs(Data[1].High[iH] - Data[1].Close[iH + 1]), Abs(Data[1].Low[iH] - Data[1].Close[iH + 1]))); } avgPlusDH = sumPlusH / adxLen; avgMinusDH = sumMinusH / adxLen; trValH = sumTrH / adxLen; } Else If(Data[1].CurrentBar > adxLen) { avgPlusDH = avgPlusDH[1] + sfH * (plusDmH - avgPlusDH[1]); avgMinusDH = avgMinusDH[1] + sfH * (minusDmH - avgMinusDH[1]); trValH = trValH[1] + sfH * (trvH - trValH[1]); } If(trValH > 0) { diPlusH = 100 * avgPlusDH / trValH; diMinusH = 100 * avgMinusDH / trValH; } Else { diPlusH = 0; diMinusH = 0; } If(diPlusH + diMinusH > 0) dxValH = 100 * Abs(diPlusH - diMinusH) / (diPlusH + diMinusH); Else dxValH = 0; cumDxH = Cum(dxValH); If(Data[1].CurrentBar > 0) { If(Data[1].CurrentBar <= adxLen) adxH = cumDxH / Data[1].CurrentBar; Else adxH = adxH[1] + sfH * (dxValH - adxH[1]); } // ===================== 日线 ADX (Wilder) ===================== sfD = 1.0 / adxLen; upMoveD = Data[2].High - Data[2].High[1]; dnMoveD = Data[2].Low[1] - Data[2].Low; plusDmD = 0; minusDmD = 0; If(upMoveD > dnMoveD And upMoveD > 0) plusDmD = upMoveD; If(dnMoveD > upMoveD And dnMoveD > 0) minusDmD = dnMoveD; trvD = Max(Data[2].High - Data[2].Low, Max(Abs(Data[2].High - Data[2].Close[1]), Abs(Data[2].Low - Data[2].Close[1]))); If(Data[2].CurrentBar == adxLen) { sumPlusD = 0; sumMinusD = 0; sumTrD = 0; For iD = 0 To adxLen - 1 { upMoveD = Data[2].High[iD] - Data[2].High[iD + 1]; dnMoveD = Data[2].Low[iD + 1] - Data[2].Low[iD]; plusDmD = 0; minusDmD = 0; If(upMoveD > dnMoveD And upMoveD > 0) plusDmD = upMoveD; If(dnMoveD > upMoveD And dnMoveD > 0) minusDmD = dnMoveD; sumPlusD = sumPlusD + plusDmD; sumMinusD = sumMinusD + minusDmD; sumTrD = sumTrD + Max(Data[2].High[iD] - Data[2].Low[iD], Max(Abs(Data[2].High[iD] - Data[2].Close[iD + 1]), Abs(Data[2].Low[iD] - Data[2].Close[iD + 1]))); } avgPlusDD = sumPlusD / adxLen; avgMinusDD = sumMinusD / adxLen; trValD = sumTrD / adxLen; } Else If(Data[2].CurrentBar > adxLen) { avgPlusDD = avgPlusDD[1] + sfD * (plusDmD - avgPlusDD[1]); avgMinusDD = avgMinusDD[1] + sfD * (minusDmD - avgMinusDD[1]); trValD = trValD[1] + sfD * (trvD - trValD[1]); } If(trValD > 0) { diPlusD = 100 * avgPlusDD / trValD; diMinusD = 100 * avgMinusDD / trValD; } Else { diPlusD = 0; diMinusD = 0; } If(diPlusD + diMinusD > 0) dxValD = 100 * Abs(diPlusD - diMinusD) / (diPlusD + diMinusD); Else dxValD = 0; cumDxD = Cum(dxValD); If(Data[2].CurrentBar > 0) { If(Data[2].CurrentBar <= adxLen) adxD = cumDxD / Data[2].CurrentBar; Else adxD = adxD[1] + sfD * (dxValD - adxD[1]); } // ===================== 信号判断(全部[1]定型) ===================== If(Data[0].CurrentBar > maLen + kdjLen + 5 And Data[1].CurrentBar > adxLen And Data[2].CurrentBar > adxLen And Data[2].CurrentBar > maLen + kdjLen + 5) { // 大周期: MA60多头 + J>D + ADX>阈值 d1L = (Data[2].Close[1] > ma60d[1]) And (jjd[1] > ddd[1]) And (adxD[1] > adxThreshold); d1S = (Data[2].Close[1] < ma60d[1]) And (jjd[1] < ddd[1]) And (adxD[1] > adxThreshold); h1L = (Data[1].Close[1] > ma60h[1]) And (jjh[1] > ddh[1]) And (adxH[1] > adxThreshold); h1S = (Data[1].Close[1] < ma60h[1]) And (jjh[1] < ddh[1]) And (adxH[1] > adxThreshold); // 小周期: MA60 + J金叉穿越(不用MACD不用ADX) upC = (jjm[1] > ddm[1]) And (jjm[2] <= ddm[2]); dnC = (jjm[1] < ddm[1]) And (jjm[2] >= ddm[2]); m15L = (Data[0].Close[1] > ma60m[1]) And upC; m15S = (Data[0].Close[1] < ma60m[1]) And dnC; openL = d1L And h1L And m15L; openS = d1S And h1S And m15S; // ===== bar序号锁: 本根K线已操作过 → 不再做任何动作 ===== If(gLastActionBar != Data[0].CurrentBar) { // ===== 平仓(回撤止盈): 收盘确认后本根K线开盘价执行 ===== If(MarketPosition == 1) { If(gLongHigh <= 0) gLongHigh = Data[0].Close[1]; If(Data[0].Close[1] > gLongHigh) gLongHigh = Data[0].Close[1]; If(Data[0].Close[1] <= gLongHigh * (1 - trailPct / 100)) { Sell(1, Data[0].Open); gLongHigh = 0; gLastActionBar = Data[0].CurrentBar; } } Else gLongHigh = 0; If(MarketPosition == -1) { If(gShortLow <= 0) gShortLow = Data[0].Close[1]; If(Data[0].Close[1] < gShortLow) gShortLow = Data[0].Close[1]; If(Data[0].Close[1] >= gShortLow * (1 + trailPct / 100)) { BuyToCover(1, Data[0].Open); gShortLow = 0; gLastActionBar = Data[0].CurrentBar; } } Else gShortLow = 0; // ===== 开仓: 仅当本根K线还没操作过 ===== If(gLastActionBar != Data[0].CurrentBar) { If(openL And MarketPosition != 1) { If(MarketPosition == -1) BuyToCover(1, Data[0].Open); Buy(1, Data[0].Open); gLongHigh = 0; gLastActionBar = Data[0].CurrentBar; } If(openS And MarketPosition != -1) { If(MarketPosition == 1) Sell(1, Data[0].Open); SellShort(1, Data[0].Open); gShortLow = 0; gLastActionBar = Data[0].CurrentBar; } } } } }