单独写一个保护本金的策略附加到其他主策略上,或直接写入主策略,遇到一些问题,想咨询一下老师:
多图层跨周期,大周期2图层,中周期1图层,小周期0图层,图层代码顺序2-1-0,图表周期顺序0-1-2,1图层按固定手数开仓,2图层在1图层有持仓的情况下采用可用资金开仓,计算结果发现各个图层的动态权益是一样的,累计总利润、累计总亏损、累计净利润不同,不清楚在多图层跨周期里这些权益相关的数据是如何统计的。
相关问题:
1、动态权益是按最小周期的开盘价或收盘价计算还是分图层计算的,图表图层顺序是否必须与代码图层顺序一致?代码图层顺序是否会影响动态权益的计算?
2、累计总利润、累计总亏损、累计净利润是否是分图层统计的?
3、如果在累计净利润为亏损大于本金的30%时全平所有多单和空单,然后程序自动终止,是否需要把各个图层的净利润加起来比较,还是直接可以在对应图层上根据动态权益的比较后执行?
4、如果在任何一个图层上统计到动态权益或净利润为亏损大于本金的30%,价格突破前日收盘价或跌破前日收盘价时,全平自身仓位,同时平掉其他图层所有仓位,应该如何表达?
5、采用data[ 图层自定义编号]的索引方式是否会因为回溯的问题出现错误和降低程序计算速度?Range[0:DataCount-1]与Range[0:DataSourceSize-1]有什么区别?在多图层跨周期中,是否不能混用,使用时应该注意什么?
权益相关代码如下:
//------------------------------------------------------------------------
// 简称: S_BENJIN
// 名称: S_BENJIN
// 类别: 策略应用
// 类型: 用户应用
// 输出: VoID
//------------------------------------------------------------------------
Params
Numeric BenJIN(100); //初始资金,单位万元
Numeric BenJin_Risk(30);//初始本金风险度控制系数(%)
Numeric BeginBar_XH(10);//中周期信号起始Bar数
Bool IsRollover(True);//是否后复权
Bool IsRolloverRealPrice(True);//是否映射真实价格
Bool IsAutoSwapPosition(True);//是否自动换仓
Vars
Global Integer i;
Global Integer ID(0);
Events
OnInit()
{
//与数据源有关
Range[i=0:DataCount-1]
{
//=========数据源相关设置==============
If(IsRollover)
{
AddDataFlag(Enum_Data_RolloverBackWard());//设置后复权
}
If(IsRolloverRealPrice)
{
AddDataFlag(Enum_Data_RolloverRealPrice());//是否映射真实价格
}
If(IsAutoSwapPosition)
{
AddDataFlag(Enum_Data_AutoSwapPosition());//设置自动换仓
}
AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); //设置忽略换仓信号计算
SetSlippage(Enum_Rate_PointPerHand,2); //设置滑点为2跳/手
SetOrderPriceOffset(2); //设置委托价为叫买/卖价偏移2跳
SetOrderMap2MainSymbol(); //设置委托映射到主力
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//与数据源无关
SetBeginBarMaxCount(BeginBar_XH); //设置最大起始bar数为10
SetInitCapital(BenJIN*10000);
}
OnReady()
{
// Range[i=0:DataSourceSize-1]
{
// SetBackBarMaxCount(1+Max(Max(Max(Max(Length1,length2),Length3),Length4),Length5));
}
}
//Bar更新事件函数,参数indexs表示变化的数据源图层ID数组
OnBar(ArrayRef<Integer> indexs)
{
Range[i=0:DataSourceSize-1]
{
ID=i;
Commentary("ID="+text(ID));
If(Rollover<>InvalIDNumeric And IsRollover == True )
{
If (Frequency() == "1d" /*and BarStatus==2*/)
{
print("大周期-图层:" + text(i) + "//" + "时间:" + text(SystemTimestamp));
print("大周期-图层:" + text(i) + "//" + "Bar数:" + text(CurrentBar));
print("大周期-图层:" + text(i) + "//" + "复权系数:" + text(Rollover()));
print("大周期-图层:" + text(i) + "//" + "OPEN=" + text(open/Rollover));
print("大周期-图层:" + text(i) + "//" + "开盘动态权益=" + text(Portfolio_CurrentCapital() + Portfolio_UsedMargin()));
print("大周期-图层:" + text(i) + "//" + "Close=" + text(Close/Rollover));
print("大周期-图层:" + text(i) + "//" + "收盘动态权益=" + text(Portfolio_CurrentEquity));
print("大周期-图层:" + text(i) + "//" + "累计总利润=" + text(GrossProfit));
print("大周期-图层:" + text(i) + "//" + "累计总亏损=" + text(GrossLoss));
print("大周期-图层:" + text(i) + "//" + "累计净利润=" + text(NetProfit));
print("大周期-图层:" + text(i) + "//" + "分隔符" + "---------------------------------------------");
}
If (Frequency() == "1h" /*and BarStatus==2*/)
{
print("中周期-图层:" + text(i) + "//" + "时间:" + text(SystemTimestamp));
print("中周期-图层:" + text(i) + "//" + "Bar数:" + text(CurrentBar));
print("中周期-图层:" + text(i) + "//" + "复权系数:" + text(Rollover()));
print("中周期-图层:" + text(i) + "//" + "OPEN=" + text(open/Rollover));
print("中周期-图层:" + text(i) + "//" + "开盘动态权益=" + text(Portfolio_CurrentCapital() + Portfolio_UsedMargin()));
print("中周期-图层:" + text(i) + "//" + "Close=" + text(Close/Rollover));
print("中周期-图层:" + text(i) + "//" + "收盘动态权益=" + text(Portfolio_CurrentEquity));
print("中周期-图层:" + text(i) + "//" + "累计总利润=" + text(GrossProfit));
print("中周期-图层:" + text(i) + "//" + "累计总亏损=" + text(GrossLoss));
print("中周期-图层:" + text(i) + "//" + "累计净利润=" + text(NetProfit));
print("中周期-图层:" + text(i) + "//" + "分隔符" + "---------------------------------------------");
}
If (Frequency() == "5m" /* and BarStatus==2*/)
{
print("小周期-图层:" + text(i) + "//" + "时间:" + text(SystemTimestamp));
print("小周期-图层:" + text(i) + "//" + "Bar数:" + text(CurrentBar));
print("小周期-图层:" + text(i) + "//" + "复权系数:" + text(Rollover()));
print("小周期-图层:" + text(i) + "//" + "OPEN=" + text(open/Rollover));
print("小周期-图层:" + text(i) + "//" + "开盘动态权益=" + text(Portfolio_CurrentCapital() + Portfolio_UsedMargin()));
print("小周期-图层:" + text(i) + "//" + "Close=" + text(Close/Rollover));
print("小周期-图层:" + text(i) + "//" + "收盘动态权益=" + text(Portfolio_CurrentEquity));
print("小周期-图层:" + text(i) + "//" + "累计总利润=" + text(GrossProfit));
print("小周期-图层:" + text(i) + "//" + "累计总亏损=" + text(GrossLoss));
print("小周期-图层:" + text(i) + "//" + "累计净利润=" + text(NetProfit));
print("小周期-图层:" + text(i) + "//" + "分隔符" + "---------------------------------------------");
}
}
Else
{
If (Frequency() == "1d" /*and BarStatus==2*/)
{
print("大周期-图层:" + text(i) + "//" + "时间:" + text(SystemTimestamp));
print("大周期-图层:" + text(i) + "//" + "Bar数:" + text(CurrentBar));
print("大周期-图层:" + text(i) + "//" + "复权系数:" + text(Rollover()));
print("大周期-图层:" + text(i) + "//" + "OPEN=" + text(open));
print("大周期-图层:" + text(i) + "//" + "开盘动态权益=" + text(Portfolio_CurrentCapital() + Portfolio_UsedMargin()));
print("大周期-图层:" + text(i) + "//" + "Close=" + text(Close));
print("大周期-图层:" + text(i) + "//" + "收盘动态权益=" + text(Portfolio_CurrentEquity));
print("大周期-图层:" + text(i) + "//" + "累计总利润=" + text(GrossProfit));
print("大周期-图层:" + text(i) + "//" + "累计总亏损=" + text(GrossLoss));
print("大周期-图层:" + text(i) + "//" + "累计净利润=" + text(NetProfit));
print("大周期-图层:" + text(i) + "//" + "分隔符" + "---------------------------------------------");
}
If (Frequency() == "1h" /*and BarStatus==2*/)
{
print("中周期-图层:" + text(i) + "//" + "时间:" + text(SystemTimestamp));
print("中周期-图层:" + text(i) + "//" + "Bar数:" + text(CurrentBar));
print("中周期-图层:" + text(i) + "//" + "复权系数:" + text(Rollover()));
print("中周期-图层:" + text(i) + "//" + "OPEN=" + text(open));
print("中周期-图层:" + text(i) + "//" + "开盘动态权益=" + text(Portfolio_CurrentCapital() + Portfolio_UsedMargin()));
print("中周期-图层:" + text(i) + "//" + "Close=" + text(Close));
print("中周期-图层:" + text(i) + "//" + "收盘动态权益=" + text(Portfolio_CurrentEquity));
print("中周期-图层:" + text(i) + "//" + "累计总利润=" + text(GrossProfit));
print("中周期-图层:" + text(i) + "//" + "累计总亏损=" + text(GrossLoss));
print("中周期-图层:" + text(i) + "//" + "累计净利润=" + text(NetProfit));
print("中周期-图层:" + text(i) + "//" + "分隔符" + "---------------------------------------------");
}
If (Frequency() == "5m" /* and BarStatus==2*/)
{
print("小周期-图层:" + text(i) + "//" + "时间:" + text(SystemTimestamp));
print("小周期-图层:" + text(i) + "//" + "Bar数:" + text(CurrentBar));
print("小周期-图层:" + text(i) + "//" + "复权系数:" + text(Rollover()));
print("小周期-图层:" + text(i) + "//" + "OPEN=" + text(open));
print("小周期-图层:" + text(i) + "//" + "开盘动态权益=" + text(Portfolio_CurrentCapital() + Portfolio_UsedMargin()));
print("小周期-图层:" + text(i) + "//" + "Close=" + text(Close));
print("小周期-图层:" + text(i) + "//" + "收盘动态权益=" + text(Portfolio_CurrentEquity));
print("小周期-图层:" + text(i) + "//" + "累计总利润=" + text(GrossProfit));
print("小周期-图层:" + text(i) + "//" + "累计总亏损=" + text(GrossLoss));
print("小周期-图层:" + text(i) + "//" + "累计净利润=" + text(NetProfit));
print("小周期-图层:" + text(i) + "//" + "分隔符" + "---------------------------------------------");
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Range[1:1]
{
BOOL BenJin_Protect =(data[1].Portfolio_CurrentCapital() + data[1].Portfolio_UsedMargin())<= BenJIN*10000*(1-BenJin_Risk/100);
If (BenJin_Protect )
{
if(data[1].MarketPosition==1 && L<=Close[1])
{
data[1].Sell(0,Min(Open,Close[1]));
if(data[0].MarketPosition==1 && data[0].L<=data[0].Close[1])
{
data[0].Sell(0,Min(Min(data[0].Open,data[1].Open),Min(data[0].Close[0],data[1].Close[1])));
}
}
if(data[1].MarketPosition==-1 && H>=Close[1])
{
data[1].BuyToCover(0, Max(Open, Close[1]));
if(data[0].MarketPosition == -1 && data[0].H >= data[0].Close[1])
{
data[0].BuyToCover(0, Max(Max(data[0].Open, data[1].Open), Max(data[0].Close[0], data[1].Close[1])));
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Range[0:0]
{
BOOL BenJin_Protect =(data[0].Portfolio_CurrentCapital() + data[0].Portfolio_UsedMargin())<= BenJIN*10000*(1-BenJin_Risk/100);
If (BenJin_Protect )
{
if(data[0].MarketPosition==1 && L<=Close[1])
{
data[0].Sell(0,Min(Open,Close[1]));
if(data[1].MarketPosition==1 && data[1].L<=data[1].Close[1])
{
data[1].Sell(0,Min(Min(data[1].Open,data[0].Open),Min(data[1].Close[0],data[0].Close[1])));
}
}
if(data[1].MarketPosition==-1 && H>=Close[1])
{
data[1].BuyToCover(0, Max(Open, Close[1]));
if(data[0].MarketPosition == -1 && data[0].H >= data[0].Close[1])
{
data[0].BuyToCover(0, Max(Max(data[0].Open, data[1].Open), Max(data[0].Close[0], data[1].Close[1])));
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
//------------------------------------------------------------------------
// 编译版本 2024/12/18 85451
// 版权所有 Shanhai888
// 更改声明 TradeBlazer Software保留对TradeBlazer平台
// 每一版本的TradeBlazer策略修改和重写的权利
//------------------------------------------------------------------------
麻烦老师帮解答一下并顺便看一下代码是否存在问题,如有问题麻烦帮指导修正。谢谢!
1.Portfolio打头的函数,是资金函数,一个策略单元资金是共享,不分图层
2.datacount,DataSourceSize二者是一样的
上面是在TB3的运行结果。另外麻烦老师帮看一下上面的图层对齐问题在标准版里如何处理。谢谢!
上面大周期图层没表达出来,主策略代码顺序是大周期图层Range[DZQTC:DZQTC] ,Params Numeric DZQTC(2); //大周期图层编号 大周期图层是放在1图层的前面的
在图层语句最后应该加上Return 麻烦老师抽空帮看一下 谢谢
测试环境,能否简化下? 我复制了代码,也按照三个周期叠加创建了策略单元,但还没能复现问题。估计你是加了其它策略
代码本身是没有问题的,主要是想搞清楚下面的几个疑问,麻烦再看看帮解答一下。1、动态权益是按最小周期的开盘价或收盘价计算还是分图层计算的,图表图层顺序是否必须与代码图层顺序一致?代码图层顺序是否会影响动态权益的计算? 2、累计总利润、累计总亏损、累计净利润是否是分图层统计的? 3、采用data[ 图层自定义编号]的索引方式是否会因为回溯的问题出现错误和降低程序计算速度?Range[0:DataCount-1]与Range[0:DataSourceSize-1]有什么区别?在多图层跨周期中,是否不能混用,使用时应该注意什么?谢谢!