求助!关于用到会员持仓数据的策略。

各位老师们好~我遇到了调用会员持仓数据时,策略报告中的头寸与打开K线图表后显示的头寸不符的情况。例如TA上的,4月25号空开的信号,K线图表中的显示31手时正确的,但打开策略报告中是15手(缩小的一半),发现很多错误的都是不需要缩小一半头寸的,结果在策略报告中是缩小一半的,但打开K线图是显示是正常的。麻烦帮我看一下,谢谢了。策略是简单的突破策略data0:5分钟K线data1:日线入场:盘中价格突破较长周期最高或最低价时入场.出场:盘中价格突破较短周期最高或最低价时离场。无止损头寸:单笔最大亏损2W,2倍ATR倒推计算得出。头寸调节:调用会员持仓数据,例如多单,合计<=0时缩小一半// 简称: temp20240528 // 名称: temp20240528 // 类别: 公式应用 // 类型: 用户应用 // 输出: Void // // 会员持仓调整头寸,图表上显示的信号仓位正确,打开参数报告里的交易记录仓位错误 // //------------------------------------------------------------------------ Params Numeric one_loss(20000); Vars //【data1_日线】 Series<Numeric> LongD_H; Series<Numeric> ShortD_H; Series<Numeric> LongD_L; Series<Numeric> ShortD_L; Series<Numeric> myatr; Numeric i; Series<Numeric> lots; //会员持仓部分 String T_Object; //主力合约 Dic<Array<String>>R_Data_ROLLOVER(\"TB_ROLLOVER_v2\"); Array<Array<String>> rvalue_B; Array<Array<String>> rvalue_S; Series<Numeric> HYB20; //会员持仓_多头持仓合计 Series<Numeric> HYS20; //会员持仓_空头持仓合计 Series<Numeric> MyTop20; //会员持仓合计后的多空差 Events //Bar更新事件函数,每根BAR都需要运行 onBar(ArrayRef<Integer> indexs) { Range[1:1] { T_Object=R_Data_ROLLOVER[0][0]; Commentary(\"合约:\"+T_Object); GetDicValue(\"TB_MEMBER_positions_long\",T_Object,date,rvalue_B); GetDicValue(\"TB_MEMBER_positions_short\",T_Object,date,rvalue_S); HYB20 = 0; HYS20 = 0; for i = 0 to 19 { HYB20 = HYB20 + Value(rvalue_B[i][1]); HYS20 = HYS20 + Value(rvalue_S[i][1]); } MyTop20 = HYB20 - HYS20; MyTop20 = MyTop20[1]; Commentary(\"TOP20: \"+text(MyTop20)); myatr = 0; ShortD_H = 0; ShortD_L = 999999999; LongD_H = 0; LongD_L = 999999999; for i = 1 to 19 { myatr = myatr + (Max(close[i+1],high[i]) - Min(close[i+1],low[i])); LongD_H = Max(LongD_H,High[i]); LongD_L = Min(LongD_L,Low[i]); if(i <= 9) { ShortD_H = Max(ShortD_H,High[i]); ShortD_L = Min(ShortD_L,Low[i]); } } myatr = myatr / 9; } Commentary(\"HYB20:\"+text(data1.HYB20)); Commentary(\"HYS20:\"+text(data1.HYS20)); Commentary(\"TOP20: \"+text(data1.MyTop20)); //建仓 If(MarketPosition != 1 and high > data1.LongD_H) { lots = Max(1,IntPart(one_loss/(data1.myatr*2*ContractUnit))); if(data1.MyTop20 <= 0) lots = lots*0.5; Commentary(\"lots:\"+text(lots)); Buy(lots,max(Open,data1.LongD_H)); } If(MarketPosition != -1 and low < data1.LongD_L) { lots = Max(1,IntPart(one_loss/(data1.myatr*2*ContractUnit))); if(data1.MyTop20 >= 0) lots = lots*0.5; Commentary(\"lots:\"+text(lots)); SellShort(lots,min(Open,data1.LongD_L)); } //平仓 If(MarketPosition == 1) { If(low <= data1.ShortD_L) Sell(Abs(CurrentContracts),Min(data1.ShortD_L,Open)); } If(MarketPosition == -1) { If(High >= data1.ShortD_H) BuyToCover(Abs(CurrentContracts),Max(data1.ShortD_H,Open)); } } //------------------------------------------------------------------------

for i = 1 to 19{ myatr = myatr + (Max(close[i+1],high[i]) - Min(close[i+1],low[i])); LongD_H = Max(LongD_H,High[i]); LongD_L = Min(LongD_L,Low[i]); if(i <= 9){ ShortD_H = Max(ShortD_H,High[i]); ShortD_L = Min(ShortD_L,Low[i]); } } myatr = myatr / 9; //9不正确?我觉得你的策略里面,自定义的计算以下数据的周期是不是也有问题:(1)ATR值(myatr):周期是不是想算20日的ATR,实际累加了前19日的TR然后分母的除数却写成了9(2)短期最高价(ShortD_H)、最低价(ShortD_L):周期是不是想算10日,实际算了前9日(3)长期最高价(LongD_H)、最低价(LongD_L):周期是不是想算20日,实际算了前19日所以是不是代码直接简化一下:myatr = AvgTrueRange(20); LongD_H = Highest(High, 20); LongD_L = Lowest(Low, 20); ShortD_H = Highest(High, 10); ShortD_L = Lowest(Low, 10);如果我猜测的计算周期范围是正确的,然后我看你代码中有意避开,当前Bar算出来的上述值,所以后面代码引用的时候,利用序列变量的回溯机制,回溯1根引用,替换以下写法就可以了:data1.myatr → data1.myatr[1] data1.LongD_H → data1.LongD_H[1] data1.LongD_L → data1.LongD_L[1] data1.ShortD_H → data1.ShortD_H[1] data1.ShortD_L → data1.ShortD_L[1]在计算前TOP20名会员的持仓量的时候,因为基础数据可能会发生变化,不一定有20个会员数据,所以要么用GetArraySize(rvalue_B)或GetArraySize(rvalue_S)控制一下循环次数for i = 0 to 19{ HYB20 = HYB20 + Value(rvalue_B[i][1]); HYS20 = HYS20 + Value(rvalue_S[i][1]); }要么判断是否有无效数据、异常数据进行控制会比较保险:for i = 0 to 19{ If(Value(rvalue_B[i][1]) != InvalidNumeric) HYB20 = HYB20 + Value(rvalue_B[i][1]); If(Value(rvalue_S[i][1]) != InvalidNumeric) HYS20 = HYS20 + Value(rvalue_S[i][1]); }

回复:谢谢老师~~~

另外你这里的赋值是有些问题的

回复:果然解决了,谢谢老师!

研发人员反馈了一下你如果是策略研究组件,基础数据必须在oninit里先订阅,才能正确获取如果是策略交易或者k线组件,可以不用订阅。 OnInit() { array<TimeStamp> tss; GetDicTimeRange(\"TB_ROLLOVER_v2\",Symbol,tss,BeginDateTime,EndDateTime); map<String,Integer> codeMap; Integer i = 0; for i = 0 to GetArraySize(tss)-1 { Array<String> ro; GetDicValue(\"TB_ROLLOVER_v2\",Symbol,tss[i],ro); codeMap[ro[0]] = 1; } Array<String> codes; GetMapKeys(codeMap,codes); for i = 0 to GetArraySize(codes)-1 { SubscribeDic(\"TB_MEMBER_positions_long\",codes[i],BeginDateTime,EndDateTime); SubscribeDic(\"TB_MEMBER_positions_short\",codes[i],BeginDateTime,EndDateTime); } }

回复:收到,谢谢~

回复:老师,再帮我看一下,我在策略研究组件里这么写的,然后打开K线 TCommentary(\"TOP20: \"+text(MyTop20))取不到值. //初始化事件函数,策略运行期间,首先运行且只有一次 OnInit() { GetDicValue(\"TB_MEMBER_positions_long\",R_Data_ROLLOVER[0][0],date,rvalue_B); GetDicValue(\"TB_MEMBER_positions_short\",R_Data_ROLLOVER[0][0],date,rvalue_S); HYB20 = 0; HYS20 = 0; for i = 0 to 19 { HYB20 = HYB20 + Value(rvalue_B[i][1]); HYS20 = HYS20 + Value(rvalue_S[i][1]); } MyTop20 = HYB20 - HYS20; } //Bar更新事件函数,每根BAR都需要运行 onBar(ArrayRef<Integer> indexs) { Commentary(\"TOP20: \"+text(MyTop20)); }

回复:重要的是先subscribe基础数据

复现问题,已转发给研发人员

回复:11如何联系研发人员呢

回复: