分析交易策略产生反向交易信号的原因
下面的交易策略交易逻辑:以macd前一日的日线定方向,以15分钟为周期日线是多头方向等15分钟macd死叉后绿柱开始缩短进场买入做多,第2次死叉后绿柱开始缩短加仓,最多持有3手。同理做空,采取跟踪止盈、严格止损、持仓的方向与日线方向不一致时全部平仓。从实测结果看存在日内15分钟开仓与日线相反的情况。因为日内只存在要么做多要么做空。//------------------------------------------------------------------------// 简称: macdDual// 名称: MACD双周期交易系统(日线方向+15分钟柱变化开仓+第2次死叉加仓)// 类别: 策略应用// 类型: 用户应用// 输出: Void//------------------------------------------------------------------------Params Numeric FastLength(12); Numeric SlowLength(26); Numeric SignalLength(9); Bool UseStopLoss(true); Numeric StopLossPct(3); Bool UseProfitRetrace(true); Numeric ProfitRetracePct(1.6); Numeric InitLots(1); Numeric AddLots(1); Numeric MaxPosition(3); // 开仓柱条件选择:0=严格(柱缩短且为负/正),1=宽松(柱不创新低/新高) Integer EntryMode(1);Vars // 15分钟MACD变量 Numeric AvgFast15; Numeric AvgSlow15; Numeric DIF15; Numeric DEA15; Numeric MACDHist15; // 15分钟上一根MACD值 Numeric prevDIF15; Numeric prevDEA15; Numeric prevMACDHist15; // 日线MACD变量 Numeric AvgFastDay; Numeric AvgSlowDay; Numeric DIFDay; Numeric DEADay; // 持仓期间最高/最低价 Numeric HighestAfterEntry; Numeric LowestAfterEntry; // 当前持仓手数(正多负空) Numeric currentLots; // 死叉/金叉计数 Integer deathCrossCount; Integer goldenCrossCount; // 上一根日线趋势状态 Bool prevDayTrendUp; Bool prevDayTrendDown; // 本Bar是否已交易 Bool tradeThisBar; // 上一次15分钟bar时间 Numeric last15BarTime;Defs Numeric calcAvg(Numeric a, Numeric b) { return (a + b) / 2; }Events OnInit() { currentLots = 0; deathCrossCount = 0; goldenCrossCount = 0; prevDayTrendUp = false; prevDayTrendDown = false; HighestAfterEntry = 0; LowestAfterEntry = 0; prevDIF15 = 0; prevDEA15 = 0; prevMACDHist15 = 0; last15BarTime = 0; } OnBar(ArrayRef<Integer> indexs) { // ===== 判断是否为新15分钟bar ===== Numeric current15BarTime = Time; If(current15BarTime == last15BarTime) { Return; // 非新bar(可能是日线更新触发) } last15BarTime = current15BarTime; tradeThisBar = false; // 同步实际持仓 If(currentLots == 0 && MarketPosition != 0) { If(MarketPosition == 1) currentLots = Abs(CurrentContracts()); Else If(MarketPosition == -1) currentLots = -Abs(CurrentContracts()); } Else If(currentLots != 0 && MarketPosition == 0) { currentLots = 0; HighestAfterEntry = 0; LowestAfterEntry = 0; } // 计算日线MACD(使用Data[1]) AvgFastDay = XAverage(Data[1].Close, FastLength); AvgSlowDay = XAverage(Data[1].Close, SlowLength); DIFDay = AvgFastDay - AvgSlowDay; DEADay = XAverage(DIFDay, SignalLength); // 计算15分钟MACD AvgFast15 = XAverage(Close, FastLength); AvgSlow15 = XAverage(Close, SlowLength); DIF15 = AvgFast15 - AvgSlow15; DEA15 = XAverage(DIF15, SignalLength); MACDHist15 = DIF15 - DEA15; // 输出指标 PlotNumeric("DIF15", DIF15); PlotNumeric("DEA15", DEA15); PlotNumeric("MACD15", MACDHist15); PlotNumeric("DIFDay", DIFDay); PlotNumeric("DEADay", DEADay); // 日线趋势判断 Bool dayTrendUp = DIFDay > DEADay; Bool dayTrendDown = DIFDay < DEADay; // 输出日线趋势状态(用数值便于观察:1=金叉,-1=死叉,0=其他) If(dayTrendUp) PlotNumeric("DayTrend", 1); Else If(dayTrendDown) PlotNumeric("DayTrend", -1); Else PlotNumeric("DayTrend", 0); // 检测日线趋势反转 If(prevDayTrendUp && dayTrendDown) { deathCrossCount = 0; } Else If(prevDayTrendDown && dayTrendUp) { goldenCrossCount = 0; } // 检测15分钟金叉/死叉并计数 Bool goldenCross15 = (prevDIF15 <= prevDEA15 && DIF15 > DEA15); Bool deathCross15 = (prevDIF15 >= prevDEA15 && DIF15 < DEA15); If(goldenCross15) goldenCrossCount = goldenCrossCount + 1; If(deathCross15) deathCrossCount = deathCrossCount + 1; // 输出计数(用于调试) PlotNumeric("DeathCrossCnt", deathCrossCount); PlotNumeric("GoldenCrossCnt", goldenCrossCount); // 更新持仓期间最高/最低价 If(MarketPosition == 1 && currentLots > 0) { If(HighestAfterEntry == 0) HighestAfterEntry = High; Else HighestAfterEntry = Max(HighestAfterEntry, High); } Else If(MarketPosition == -1 && currentLots < 0) { If(LowestAfterEntry == 0) LowestAfterEntry = Low; Else LowestAfterEntry = Min(LowestAfterEntry, Low); } Else { HighestAfterEntry = 0; LowestAfterEntry = 0; } // ===== 止损止盈 ===== Bool exitTriggered = false; If(MarketPosition == 1 && currentLots > 0) { Numeric avgEntry = AvgEntryPrice(); If(UseStopLoss) { Numeric stopPrice = avgEntry * (1 - StopLossPct / 100); If(Low <= stopPrice) { Sell(currentLots, Open); currentLots = 0; exitTriggered = true; tradeThisBar = true; } } If(!exitTriggered && UseProfitRetrace && HighestAfterEntry > 0) { Numeric profitTarget = HighestAfterEntry * (1 - ProfitRetracePct / 100); If(Low <= profitTarget) { Sell(currentLots, Open); currentLots = 0; exitTriggered = true; tradeThisBar = true; } } } Else If(MarketPosition == -1 && currentLots < 0) { Numeric avgEntry = AvgEntryPrice(); If(UseStopLoss) { Numeric stopPrice = avgEntry * (1 + StopLossPct / 100); If(High >= stopPrice) { BuyToCover(Abs(currentLots), Open); currentLots = 0; exitTriggered = true; tradeThisBar = true; } } If(!exitTriggered && UseProfitRetrace && LowestAfterEntry > 0) { Numeric profitTarget = LowestAfterEntry * (1 + ProfitRetracePct / 100); If(High >= profitTarget) { BuyToCover(Abs(currentLots), Open); currentLots = 0; exitTriggered = true; tradeThisBar = true; } } } // ===== 日线趋势反转平仓 ===== If(!tradeThisBar && MarketPosition == 1 && dayTrendDown) { Sell(currentLots, Open); currentLots = 0; tradeThisBar = true; } Else If(!tradeThisBar && MarketPosition == -1 && dayTrendUp) { BuyToCover(Abs(currentLots), Open); currentLots = 0; tradeThisBar = true; } // ===== 开仓与加仓 ===== // 定义柱缩短判断(根据EntryMode) Bool greenShorten = false; Bool redShorten = false; If(EntryMode == 0) // 严格:柱为负且变大 / 柱为正且变小 { greenShorten = (MACDHist15 < 0 && MACDHist15 > prevMACDHist15); redShorten = (MACDHist15 > 0 && MACDHist15 < prevMACDHist15); } Else // 宽松:柱不创新低/新高 { greenShorten = (MACDHist15 > prevMACDHist15); // 只要柱变大,无论正负 redShorten = (MACDHist15 < prevMACDHist15); // 只要柱变小,无论正负 } // 开多:日线金叉,15分钟绿柱缩短(或宽松条件) If(!tradeThisBar && dayTrendUp && MarketPosition == 0 && currentLots == 0) { If(greenShorten) { Buy(InitLots, Open); currentLots = InitLots; HighestAfterEntry = High; tradeThisBar = true; } } // 开空:日线死叉,15分钟红柱缩短(或宽松条件) Else If(!tradeThisBar && dayTrendDown && MarketPosition == 0 && currentLots == 0) { If(redShorten) { SellShort(InitLots, Open); currentLots = -InitLots; LowestAfterEntry = Low; tradeThisBar = true; } } // 加多:日线金叉,15分钟第2次死叉后绿柱缩短,持仓<3 If(!tradeThisBar && dayTrendUp && MarketPosition == 1 && Abs(currentLots) < MaxPosition) { If(deathCrossCount >= 2 && greenShorten) { Buy(AddLots, Open); currentLots = currentLots + AddLots; tradeThisBar = true; } } // 加空:日线死叉,15分钟第2次金叉后红柱缩短,持仓<3 Else If(!tradeThisBar && dayTrendDown && MarketPosition == -1 && Abs(currentLots) < MaxPosition) { If(goldenCrossCount >= 2 && redShorten) { SellShort(AddLots, Open); currentLots = currentLots - AddLots; tradeThisBar = true; } } // 保存15分钟MACD历史值及日线趋势状态 prevDIF15 = DIF15; prevDEA15 = DEA15; prevMACDHist15 = MACDHist15; prevDayTrendUp = dayTrendUp; prevDayTrendDown = dayTrendDown; } OnTimer(Integer id, Integer intervalMillsecs) { } OnExit() { }