我有个策略偶尔出现了一次信号闪烁(在生猪加权5分钟周期,5月25日早上9点账户开了多头,提示是这个策略开仓的,但是k线上这里并没有信号),我检查了几遍代码也没有找到问题
请老师帮忙检查一下代码
//------------------------------------------------------------------------
// 简称: MultiBreak_WYD4
// 名称: 跨小周期突破(WYD)4
// 类别: 公式应用
// 类型: 用户应用
// 输出: Void
//------------------------------------------------------------------------
/*
原策略:
入场:破前10日高点作多
止损:止损1个ATR
出场1:反向破前5日低点且利润回吐25%出
出场2:反向破前1日低点且利润回吐60%出
仓位:固定金额/ATR
2026.1.14修改如下:
(1) 入场:破前 10 日高点入场 ()
(2) 止损:1 个 ATR,盈利 1 个 ATR以后 把止损移到入场点。 ()
超过固定金额N也强制平仓止损 ()
(3) 出场:
=反向破前 5 日低点且利润回吐 25%出 ()
=反向破前 1 日低点且利润回吐 50%出 ()
(4) 手数:固定金额N/ 1 个 ATR ()
当天开仓,当天可以止损,当天止损后同向不再开仓,反向满足条件可以再开,策略中所有参数弄成可调 ()
*/
Params
Numeric N(10); //进场突破周期数
Numeric L1(5); //反向突破止损周期1
Numeric L2(1); //反向突破止损周期2
Numeric R1(0.25); //反向突破1时利润回吐1
Numeric R2(0.50); //反向突破2时利润回吐2
Numeric Amount(3000); //仓位金额
Numeric LossAtr(1); //止损ATR倍数
Numeric LossAmount(1000);//亏损金额
Numeric WinAtr(1); //保本ATR倍数
Numeric LengthAtr(14); //ATR周期数
String Period("1d"); // 大周期均线周期,h小时,m分钟,比如4小时请设置为4h
Integer RolloverBackWard(1); // 是否后复权
Vars
Series<Numeric> High1;
Series<Numeric> Low1;
Series<Numeric> High2;
Series<Numeric> Low2;
Series<Numeric> HH;
Series<Numeric> LL;
Series<Numeric> HH1;
Series<Numeric> LL1;
Series<Numeric> HH2;
Series<Numeric> LL2;
Series<Numeric> ATR;
Series<Numeric> myPrice;
Series<Numeric> lossPrice; //反向突破止损价格
Series<Numeric> takingPrice1; //回吐止损价格1
Series<Numeric> takingPrice2; //回吐止损价格2
Numeric Lots(1); //开仓手数
Series<Numeric> minPoint;
Series<Numeric> minPointPrice;
Series<Numeric> takingRate; //利润回吐比例
Series<Numeric> HighAfterEntry;
Series<Numeric> LowAfterEntry;
Global Integer IsSubs;
Series<String> Contract;
Series<Numeric> todayLong;
Series<Numeric> todayShort;
Defs
//此处添加公式函数
Events
//此处实现事件函数
//初始化事件函数,策略运行期间,首先运行且只有一次
OnInit()
{
//除权换月
//AddDataFlag(Enum_Data_RolloverBackWard()); //设置后复权
//AddDataFlag(Enum_Data_RolloverRealPrice()); //设置映射真实价格
//AddDataFlag(Enum_Data_AutoSwapPosition()); //设置自动换仓
//SetSlippage(Enum_Rate_PointPerHand,1); //设置滑点为1跳/手
//SetOrderPriceOffset(2); //设置委托价为叫买/卖价偏移2跳
//SetOrderMap2MainSymbol(); //设置委托映射到主力
Range[0:DataCount-1]
{
// 设置数据标志
If (RolloverBackWard==1)
{
AddDataFlag(Enum_Data_RolloverBackWard()); // 后复权
AddDataFlag(Enum_Data_RolloverRealPrice()); // 映射真实价格
AddDataFlag(Enum_Data_AutoSwapPosition()); // 自动换仓
AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); // 忽略换仓信号计算
SetSwapPosVolType(2); // 换月时头寸:2=等持仓量
}
}
}
OnBarOpen(ArrayRef<Integer> indexs)
{
//初始化跨周期K线数据
If (CurrentBar==0 And IsSubs==0)
{
//获取合约名称
Contract=Symbol();
//订阅均线1的60分钟K线数据
If (RolloverBackWard==1)
{
SubscribeBar(Contract,Period,BeginDateTime, 0, Enum_Data_RolloverBackWard());
//Data1.AddDataFlag(Enum_Data_FullPeriod());
}Else
{
SubscribeBar(Contract,Period,BeginDateTime, 0, Enum_Data_FullPeriod);
}
IsSubs=1;
}
Range[0:0]
{
If (BarsSinceToday==0)
{
todayLong=0;
todayShort=0;
}
}
}
//Bar更新事件函数,参数indexs表示变化的数据源图层ID数组
OnBar(ArrayRef<Integer> indexs)
{
Range[1:1]
{
minPoint=MinMove()*PriceScale();
Commentary("该品种1跳等于"+Text(minPoint)+"点");
//计算高低点
High1=High;
Low1=Low;
High2=High;
Low2=Low;
HH=Highest(High[1],N)+minPoint;
LL=Lowest(Low[1],N)-minPoint;
HH1=Highest(High1[1],L1)+minPoint;
LL1=Lowest(Low1[1],L1)-minPoint;
HH2=Highest(High2[1],L2)+minPoint;
LL2=Lowest(Low2[1],L2)-minPoint;
PlotNumeric("HH",HH);
PlotNumeric("LL2",LL);
//Return;
//计算ATR
ATR=AvgTrueRange(LengthAtr);
Commentary("ATR="+Text(ATR));
Commentary("ATR="+Text(ATR) + " 1倍ATR"+Text(Lots)+"手盈亏金额:"+ Text(ATR*1*Lots*ContractUnit()*BigPointValue()) +"元");
//计算仓位数
minPointPrice=ContractUnit()*BigPointValue();
Lots= IntPart(Amount/(LossAtr*ATR[1]*minPointPrice));
Commentary("计算手数:"+Text(Amount/(LossAtr*ATR[1]*minPointPrice)));
If (Lots<1) Lots=1;
Commentary("Lots="+Text(Lots));
Commentary("lossPrice="+Text(lossPrice));
}
Range[0:0]
{
HH=Data1.HH;
LL=Data1.LL;
ATR=Data1.ATR[1];
HH1=Data1.HH1;
LL1=Data1.LL1;
HH2=Data1.HH2;
LL2=Data1.LL2;
PlotNumeric("HH",HH);
PlotNumeric("LL2",LL);
Numeric lossPoint=LossAmount/(ContractUnit()*BigPointValue()*Lots);
Commentary("ATR="+Text(ATR));
Commentary("ATR="+Text(ATR) + " 1倍ATR"+Text(Lots)+"手盈亏金额:"+ Text(ATR*1*Lots*ContractUnit()*BigPointValue()) +"元");
//多头开仓:破前10日高点作多
If (MarketPosition==0 And Vol>0 And High>=HH And Lots>=1 And todayLong==0)
{
todayLong=1;
myPrice=Max(Open,HH);
Lots=Data1.Lots;
Buy(Lots,myPrice);
Commentary("多头开仓:破前10日高点作多");
//计算止损价
lossPrice=myPrice-Min(lossPoint,LossAtr*ATR);
//Commentary("lossPoint="+Text(lossPoint));
//Commentary("LossAtr*ATR[1]="+Text(LossAtr*ATR[1]));
//Commentary("lossPrice="+Text(lossPrice));
}
//空头开仓:破前10日低点作空
If (MarketPosition==0 And Vol>0 And Low<=LL And Lots>=1 And todayShort==0)
{
todayShort=1;
myPrice=Min(Open,LL);
Lots=Data1.Lots;
SellShort(Lots,myPrice);
Commentary("空头开仓:破前10日低点作空");
//计算止损价
lossPrice=myPrice+Min(lossPoint,LossAtr*ATR);
}
//多头止损
If (MarketPosition==1 And Vol>0 And BarsSinceEntry>0 And Low<=lossPrice And lossPrice>0 )
{
Commentary("多头固定止损");
Sell(0,Min(Open,lossPrice));
lossPrice=0;
//winPrice=0;
PlotBool("dd",True);
}
//空头止损
If (MarketPosition==-1 And Vol>0 And BarsSinceEntry>0 And High>=lossPrice And lossPrice>0 )
{
Commentary("空头固定止损");
BuyToCover(0,Max(Open,lossPrice));
lossPrice=0;
//winPrice=0;
PlotBool("dd",True);
}
//记录开仓后高低点
If(BarsSinceentry == 0)
{
HighAfterEntry = High;
LowAfterEntry = Low;
}else
{
HighAfterEntry = Max(HighAfterEntry,High); // 记录下当前Bar的最高点,用于下一个Bar的跟踪止损判断
LowAfterEntry = Min(LowAfterEntry,Low); // 记录下当前Bar的最低点,用于下一个Bar的跟踪止损判断
}
Bool corssup=CrossOver(HighAfterEntry[1]-EntryPrice,WinAtr*ATR) And MarketPosition==1 ;
Bool corssDn=CrossOver(EntryPrice-LowAfterEntry[1], WinAtr*ATR) And MarketPosition==-1;
//出场2:反向破前1日低点且利润回吐60%出
If (MarketPosition==1 And Vol>0 And BarsSinceEntry>0)
{
//当盈利1个ATR时,止损移动到入场点
If (High>=EntryPrice+WinAtr*ATR)
{
lossPrice=EntryPrice;
Commentary("当盈利"+Text(WinAtr)+"个ATR时,止损移动到入场点");
PlotBool("提高止损",True,EntryPrice);
}
Commentary("多头持仓"+Text( longCurrentContracts() )+"手");
takingRate=(HighAfterEntry[1]-Low)/(HighAfterEntry[1]-EntryPrice);
takingPrice1=HighAfterEntry[1]-R1*(HighAfterEntry[1]-EntryPrice);
Commentary("多头利润回吐:"+Text(takingRate*100)+"%");
Commentary("多头利润回吐止损价1:"+Text(takingPrice1));
takingPrice2=HighAfterEntry[1]-R2*(HighAfterEntry[1]-EntryPrice);
Commentary("多头利润回吐止损价2:"+Text(takingPrice2));
//亏损且破低
Numeric myLL1;
myLL1=Min(takingPrice1,LL1);
//回撤且破低
If (takingRate>=R1 And Low<=myLL1)
{
myPrice=Min(Open,myLL1);
Commentary("多头出场1(反向破前 5 日低点且利润回吐 25%出)");
//判断是否止盈
If (myPrice>EntryPrice)
{
//todayLong=0;
}
Sell(0,myPrice);
Return;
}
/*
=反向破前 5 日低点且利润回吐 25%出
=反向破前 1 日低点且利润回吐 50%出
*/
Numeric myLL2;
myLL2=Min(takingPrice2,LL2);
If (takingRate>=R2 And Low<=myLL2)
{
myPrice=Min(Open,myLL2);
Commentary("多头出场2(反向破前 1 日低点且利润回吐 50%出)");
//判断是否止盈
If (myPrice>EntryPrice)
{
//todayLong=0;
}
Sell(0,myPrice);
Return;
}
}
If (MarketPosition == -1 And Vol > 0 And BarsSinceEntry > 0)
{
//当盈利1个ATR时,止损移动到入场点
If (Low <= EntryPrice - WinAtr * ATR)
{
lossPrice = EntryPrice;
Commentary("当盈利" + Text(WinAtr) + "个ATR时,止损移动到入场点");
PlotBool("提高止损", True, EntryPrice);
}
Commentary("空头持仓" + Text(shortCurrentContracts()) + "手");
takingRate = (Low - LowAfterEntry[1]) / (EntryPrice - LowAfterEntry[1]);
takingPrice1 = LowAfterEntry[1] + R1 * (EntryPrice - LowAfterEntry[1]);
Commentary("空头利润回吐:" + Text(takingRate * 100) + "%");
Commentary("空头利润回吐止损价1:" + Text(takingPrice1));
takingPrice2 = LowAfterEntry[1] + R2 * (EntryPrice - LowAfterEntry[1]);
Commentary("空头利润回吐止损价2:" + Text(takingPrice2));
//亏损且破高
Numeric myHH1;
myHH1 = Max(takingPrice1, HH1);
//回撤且破高
If (takingRate >= R1 And High >= myHH1)
{
myPrice = Max(Open, myHH1);
Commentary("空头出场1(反向破前5日高点且利润回吐25%出)");
//判断是否止盈
If (myPrice<EntryPrice)
{
//todayShort=0;
}
BuyToCover(0, myPrice);
Return;
}
/*
=反向破前5日高点且利润回吐25%出
=反向破前1日高点且利润回吐50%出
*/
Numeric myHH2;
myHH2 = Max(takingPrice2, HH2);
If (takingRate >= R2 And High >= myHH2)
{
myPrice = Max(Open, myHH2);
Commentary("空头出场2(反向破前1日高点且利润回吐50%出)");
//判断是否止盈
If (myPrice<EntryPrice)
{
//todayShort=0;
}
BuyToCover(0, myPrice);
Return;
}
}
//空头平仓:破前10日高点作多
If (MarketPosition==-1 And Vol>0 And High>=HH And Lots>=1)
{
myPrice=Max(Open,HH);
//判断是否止盈
If (myPrice<EntryPrice)
{
//todayShort=0;
}
BuyToCover(0,myPrice);
Commentary("空头平仓:破前10日高点作多");
//计算止损价
//lossPrice=EntryPrice-LossAtr*ATR;
Return;
}
//多头平仓:破前10日低点作空
If (MarketPosition==1 And Vol>0 And Low<=LL And Lots>=1)
{
myPrice=Min(Open,LL);
//判断是否止盈
If (myPrice>EntryPrice)
{
//todayLong=0;
}
Sell(0,myPrice);
Commentary("多头平仓:破前10日低点作空");
//计算止损价
//lossPrice=EntryPrice+LossAtr*ATR;
Return;
}
}
}