请高手帮忙看看,付费没问题。
//------------------------------------------------------------------------ // 简称: FractalTrendStrategy // 名称: 顶底分型+趋势排列过滤策略 // 类别: 公式应用 // 类型: 用户应用 // 输出: Void //买回来日期:2026年4月26日------------------------------------------------------------------------ Params Numeric length(20); // 趋势均线周期(备用,本策略主要用排列条件) Numeric atrLen(14); // ATR周期 Numeric riskRatio(2); // 初始止损ATR倍数 Numeric trailingRatio(1); // 移动止损ATR倍数 Numeric minProfit(1.5); // 最小盈亏比 Numeric fractalLen(3); // 分型比较K线数(固定3) Numeric trendBars(2); // 趋势排列所需的连续K线数量(例如5) Numeric lots(1); // 固定手数 Vars Series<Numeric> ma60; //先声明60均线变量 Numeric ma144; //先声明60均线变量 Numeric ma169; //先声明60均线变量 Numeric MinTick; Numeric FixBuyLow; //永久存当时开仓那根1号K的低 Numeric FixSellHigh; //永久存当时开仓那根1号K的高 Numeric i; // 循环计数器 Series<Numeric> atr; // 平均真实波幅 Global Numeric EntryBar; // 分型标识 Series<bool> isTopFractal; Series<bool> isBottomFractal; // 趋势排列条件 Bool priorUpTrend; // 分型前N根K线高点依次抬高 Bool priorDownTrend; // 分型前N根K线低点依次降低 // 交易状态 Global Numeric stopLoss; Bool isLastBarOfDay; // 我只加了这一个变量 Global Numeric MaxProfit; Numeric MinPoint; // 一个最小变动单位,也就是一跳 Global Numeric MyEntryPrice; // 开仓价格,本例为开仓均价,可设置为某次入场价 Series<Numeric> HighestAfterEntry; // 开仓后出现的最高价 Series<Numeric> LowestAfterEntry; // 开仓后出现的最低价 Global Numeric MyExitPrice; // 平仓价格 Integer j(0); Events OnInit() { Range[0:DataCount - 1] { AddDataFlag(Enum_Data_RolloverBackWard()); AddDataFlag(Enum_Data_RolloverRealPrice()); AddDataFlag(Enum_Data_AutoSwapPosition()); AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); SetSlippage(Enum_Rate_PointPerHand, 2); } } OnReady() { SetBackBarMaxCount(1 + 676); } OnBar(ArrayRef<Integer> indexs) { //60均线 黄线 ma60 = AverageFC(Close, 60); PlotNumeric("MA60", ma60,0, Yellow); // 1. 计算ATR atr = AvgTrueRange(atrLen); if (atr == 0) return; // 2. 识别基础分型(基于前一根K线[1]与[0]、[2]比较) //isTopFractal = (High[1] > High[0]) && (High[1] > High[2]); isTopFractal = (High[1] > High[0] && High[1] > High[2]) && (Low[1] > Low[0] && Low[1] > Low[2]); //isBottomFractal = (Low[1] < Low[0]) && (Low[1] < Low[2]); isBottomFractal = (Low[1] < Low[0] && Low[1] < Low[2]) && (High[1] < High[0] && High[1] < High[2]); if (isTopFractal) { PlotString("顶分型标记", "顶", H[1] + 0.5*atr + 20, Red, 1); // 顶字标在[1]的高点,前一根K } if (isBottomFractal) { PlotString("底分型标记", "底", L[1]- 0.25*atr, Green, 1); // 底字标在[1]的低点,前一根K } If(BarsSinceEntry == 0) // 条件满足:开仓Bar { HighestAfterEntry = Close; LowestAfterEntry = Close; // 赋初值为当前最新价格 If(MarketPosition <> 0) // 有持仓时执行以下代码 { // 开仓Bar,将开仓价和当时的收盘价的较大值保留到HighestAfterEntry HighestAfterEntry = Max(HighestAfterEntry,AvgEntryPrice); // 开仓Bar,将开仓价和当时的收盘价的较小值保留到LowestAfterEntry LowestAfterEntry = Min(LowestAfterEntry,AvgEntryPrice); } }Else // 非开仓Bar时进行以下运算 { // 记录下当前Bar的最高点,用于下一个Bar的跟踪止损判断 HighestAfterEntry = Max(HighestAfterEntry,High); // 记录下当前Bar的最低点,用于下一个Bar的跟踪止损判断 LowestAfterEntry = Min(LowestAfterEntry,Low); } Commentary("HighestAfterEntry = "+Text(HighestAfterEntry)); Commentary("LowestAfterEntry = "+Text(LowestAfterEntry)); MinPoint = MinMove*PriceScale; MyEntryPrice = AvgEntryPrice; If(MarketPosition == 1 And BarsSinceEntry >= 1) // 有多仓的情况 { //If(HighestAfterEntry[1] >= MyEntryPrice + TrailingStart1*MinPoint) // 第一级跟踪止损的条件表达式 { Numeric break_pri=highestAfterEntry[1] - atr[1] * trailingRatio;//HighestAfterEntry[1]-(HighestAfterEntry[1]-MyEntryPrice)*0.01*TrailingStop1_percent; PlotNumeric("多单移动止损线",break_pri,0,green); If(Low <= break_pri) // - TrailingStop1*MinPoint)// { MyExitPrice = break_pri; // - TrailingStop1*MinPoint;// // 如果该Bar开盘价即跳空触发,则用开盘价代替 If(Open < MyExitPrice) MyExitPrice = Open; Sell(0,MyExitPrice); Commentary("移动止损平多"); } } } Else If(MarketPosition == -1 And BarsSinceEntry >= 1) // 有空仓的情况 { // 第二级跟踪止损的条件表达式 { Numeric break_pri=LowestAfterEntry[1] + atr[1] * trailingRatio; //LowestAfterEntry[1]+(MyEntryPrice-LowestAfterEntry[1])*0.01*TrailingStop1_percent; PlotNumeric("空单移动止损线",break_pri,0,red); If(High >= break_pri) // + TrailingStop1*MinPoint)// { MyExitPrice = break_pri; // + TrailingStop1*MinPoint;// If(Open > MyExitPrice) MyExitPrice = Open; BuyToCover(0,MyExitPrice); Commentary("移动止损平空"); } } } //——————————————————————————————————————————————————————————————————————————————————————————————移动止损 // 4. 入场信号 // 多头:底分型 + 分型前低点依次降低(下降趋势后反转) + 当前价格突破分型高点 // 注意:原意是“下降趋势后出现底分型”做多,所以检查 priorDownTrend //if (isBottomFractal && MarketPosition == 0 && priorDownTrend) { if (isBottomFractal[j] && MarketPosition == 0 && Close[j]>ma60[j] && ma60[j]>ma60[j+1]) { // 条件:现价突破1号K最高点 if(High[0] >= High[1]) { FixBuyLow = Low[1]; //当场锁死,下标再飘,这个值不变 Buy(lots, max(o,High[1])); EntryBar = CurrentBar; stopLoss = FixBuyLow; } } if (isTopFractal[j] && MarketPosition == 0 && Close[j]<ma60[j] && ma60[j]<ma60[j+1]) { if(Low[0] <= Low[1]) { FixSellHigh = High[1]; SellShort(lots, min(o,Low[1])); EntryBar = CurrentBar; stopLoss = FixSellHigh; } } // 5. 持仓管理(初始止损、移动止损、止盈) if (MarketPosition == 1) { if(CurrentBar == EntryBar) return; if (Low <= stopLoss)// || Low <= trailStop) { Sell(0,min(o,stopLoss)); } } else if (MarketPosition == -1) { if(CurrentBar == EntryBar) return; if (High >= stopLoss) { BuyToCover(0,max(o,stopLoss)); } } }