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



各位老师们好~


我遇到了调用会员持仓数据时,策略报告中的头寸与打开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));   
		}
		
	}
	
//------------------------------------------------------------------------


会员持仓的数据获取
求助:获取会员持仓数据出问题
会员持仓系统里的会员成本价
TB如何获取期货会员券商持仓?
智大今天咋收不到11月3号的会员持仓啊
关于策略回测去除无效数据的问题
交易所会员分析技巧一:交易所基础数据
策略持仓时间统计数据
会员持仓数据 TB_MEMBER_positions_long 使用时, 需要下载吗 ?
求助帖!!如何取当日最高点时的持仓量
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]);
}

谢谢老师~~~

data-href=

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

果然解决了,谢谢老师!

研发人员反馈了一下

你如果是策略研究组件,基础数据必须在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如何联系研发人员呢