//------------------------------------------------------------------------
// 简称: 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));
}
}
}付费项目看置顶帖的付费开发帖子发私密贴