举个例子,我用半小时周期:
if(marketposition <> 1 && high >= upline)
{ buy(0, q_bidprice/ rollover());}
if(marketposition <> -1 && low <= downline)
{ sellshort(0, q_askprice/ rollover());}
实盘中随着时间推移,high >= upline及low <= downline这个状态会成为一直满足的情形,产生反复开仓的现象,是否建议将high、low价格改为q_bidprice和 q_askprice这两个盘口价格?老师们对这个问题有啥别的更好的处理办法?
建议你先看看零基础教程,把onbar驱动的运行机制,a函数案例先领会一下
为什么会反复开仓?
因为半小时周期较长,high、low记录了当前bar下的最高、最低价,两个价格假如在bar运行到10分钟时就完成了对up和down的突破的话,后20分钟的状态都是满足了突破条件的
老师,这不是回测哈,是实盘模拟中遇到的现实情境
你的意思是,你用了buy 和sellshort来开仓,然后实盘模拟的时候触发信号就报一次单,一根bar上报了很多回?
是您说的意思,一根bar上一直在报单,因为条件都满足。所以我想要不要把high和low改成q_price这种实际盘口价格来规避这个情况
你说的这个不太可能。
同一根bar上的一个信号是不会重复发单的
这个是违背基本机制的
建议你把具体的代码,环境,委托记录发出来分析一下
Params
Numeric Length(2); //周期
Numeric SlowLength(26);
Numeric Offset(0.7); //标准差倍数
Numeric comno(1);//打算投资的品种个数
Vars
Series<Numeric> UpLine; //上轨
Series<Numeric> DownLine; //下轨
Series<Numeric> MidLine; //中间线
Series<Numeric> Band;//样本方差
Numeric money;//开仓资金
Numeric myprice;//委托价格
Numeric mrate;//委托价格
global Numeric lmrate;//委托价格
global Numeric smrate;//委托价格
Numeric lotsl;//委托数量
Numeric lotss;//委托数量
global Numeric mylentry;//委托数量
global Numeric mysentry;//委托数量
global Numeric lposition;//多头持仓量
global Numeric sposition;//空头持仓量
Series<Numeric> kcprice;//开仓价格
Events
OnInit()
{
AddDataFlag(Enum_Data_RolloverBackWard());
AddDataFlag(Enum_Data_RolloverRealPrice());
AddDataFlag(Enum_Data_AutoSwapPosition());
AddDataFlag(Enum_Data_IgnoreSwapSignalCalc());
SetBeginBarMaxCount(10); //设置最大起始bar数为10
SetOrderMap2MainSymbol();//映射主力合约
}
OnReady()
{
SetBackBarMaxCount(1+Max(SlowLength,Length));
}
OnBar(ArrayRef<Integer> indexs)
{
Numeric a;
Numeric result = 1;
for a = 0 to DataSourceSize-1
{
result = result*data[a].BarExistStatus;
}
If (result <> 1) Return;//检查跨周期数据源是否闪烁
If(BarStatus == 2 && CurrentTime < 0.09 ) Return;
If(BarStatus == 2 && CurrentTime < 0.1330 && CurrentTime > 0.1130) Return;
If(BarStatus == 2 && CurrentTime < 0.21 && CurrentTime > 0.15) Return;
MarginRate mRate;//获取账户对应合约的保证金率
A_GetMarginRate(relativeSymbol, mRate);
lmrate = mRate.longMarginRatio;
smrate = mRate.shortMarginRatio;
Position pos;//获取指定合约当前仓位
A_GetPosition(relativeSymbol, pos, \"\");
lposition = pos.longCurrentVolume;
sposition = pos.shortCurrentVolume;
Range[0:DataSourceSize() - 1]
{
MidLine = AverageFC(Close[1],Length);
Band = StandardDev(Close[1],Length,2);
UpLine = MidLine + Offset * Band;
DownLine = MidLine - Offset * Band;
PlotNumeric(\"UpLine\",UpLine);
PlotNumeric(\"DownLine\",DownLine);
PlotNumeric(\"MidLine\",MidLine);
}
Numeric risk;//账户当前风险程度
risk = A_totalMargin(0) / A_CurrentEquity(0);//定义risk为保证金占动态权益比例
money = A_CurrentEquity * 0.1 / comno;//按总风险度的20%
myprice = q_Open/rollover(); //这里使用open,更为精确的是使用委托价格
if(lposition == 0)
{
lotsl = IntPart(money/(myprice*contractunit*BigPointValue* lmrate)); //计算开仓手数
mylentry = Max(1,lotsl);
}
if(sposition == 0)
{
lotss = IntPart(money/(myprice*contractunit*BigPointValue* smRate)); //计算开仓手数
mysentry = Max(1,lotss);
}
Commentary(\"MarketPosition:\" + Text(lposition));
Commentary(\"MarketPosition:\" + Text(sposition));
Commentary(\"动态权益:\" + Text(a_CurrentEquity));
Commentary(\"保证金占用:\" + Text(A_totalMargin));
If (CurrentBar >= Max(SlowLength,Length))
{
Range[0:0]
{
Commentary(\"风险度:\"+Text(risk));
If(risk <= 0.4 && lposition == 0 && Low <= DownLine)//在震荡市,限制开仓规模
{
Array<Integer> orderids;
A_SendOrderEx(RelativeSymbol, enum_Buy, Enum_Entry, mylentry,Q_AskPrice/rollover(), orderids,\"\",\"\");//低线做多
Commentary(\"低位做多价:\"+Text(EntryPrice));
kcprice = EntryPrice;
}
If(lposition > 0 && High >= UpLine )//多头止赢
{
Array<Integer> orderids;
A_SendOrderEx(RelativeSymbol, Enum_Sell,Enum_Exit, lposition, Q_BidPrice/rollover(), orderids,\"\",\"\");
Commentary(\"多头止盈退出价:\"+Text(ExitPrice));
Commentary(\"多头止盈\");
Commentary(\"多头止赢点数:\"+Text(ExitPrice - kcprice));
}
If(risk <= 0.4 && sposition == 0 && High >= UpLine) //在震荡市,限制开仓规模
{
Array<Integer> orderids;
A_SendOrderEx(RelativeSymbol, Enum_Sell,Enum_Entry, mysentry, Q_BidPrice/rollover(), orderids,\"\",\"\");//高线做空
Commentary(\"高位做空价:\"+Text(EntryPrice));
kcprice = EntryPrice;
}
If(sposition > 0 && Low <= downLine)//空头止赢
{
Array<Integer> orderids;
A_SendOrderEx(RelativeSymbol, Enum_buy, Enum_Exit, sposition, Q_AskPrice/rollover(), orderids,\"\",\"\");
Commentary(\"空头止盈退出价:\"+Text(ExitPrice));
Commentary(\"空头止赢\");
Commentary(\"空头盈利点数:\"+Text(kcprice - ExitPrice));
}
}
}
}
//------------------------------------------------------------------------
// 编译版本 2024/06/20 220532
// 版权所有 xingn1991
// 更改声明 TradeBlazer Software保留对TradeBlazer平台
// 每一版本的TradeBlazer公式修改和重写的权利
//------------------------------------------------------------------------
这是上午的成交记录,同一时间产生了买、卖开仓的操作
你这用的不是buy 和sellshort图表命令啊 你这个帖子里内容完全不一样
图表命令是不会重复发单的,但是a函数是会的
这种情况一般是需要用一个状态变量来控制的
一般用global类型 发单以后就关掉,直到下次允许开仓的时候再打开
好的老师。那么在实盘中使用A函数,当价格触碰到高低轨才发单的话,用q_price作为条件判断语句中的变量,合适不?比如:if(marketposition <>1 && q_askprice >= upline)满足了就发单
跟askprice没关系,上面说了,你需要一个状态变量来控制不要反复发单,不是askprice的事情