老师您好,策略思路是每天对60个商品按照收盘距离100日高点和低点的百分比幅度进行排序,分别取离高点距离幅度最小的前5名商品开多,离低点距离最小的前5名开空。如果有个品种既在做多的排名中又在做空的品种中,则这个品种需要排除不开多也不开空,有仓位也需要平掉。以上根据每天的排名进行调仓。以下是我写的代码,有些问题,一是仓位对不上,理论上两个排名没有重复品种的情况每天的持仓应该是多5个空5个品种。但我不知道哪里写错出了问题。持仓对不上。升值第一次开仓的持仓都对不上。麻烦老师帮看一下谢谢。
Params
//此处添加参数
Vars
series<Numeric> hh;
series<Numeric> ll;
series<Numeric> hhfar;
series<Numeric> llfar;
global array<Numeric> array_hhfar;
global array<Numeric> array_llfar;
array<integer> id1;
Series<Numeric> numkai;//开仓手数计算
Series<Numeric> money1;
Series<Numeric> MarginR;
Series<Numeric> ConUnit;
Events
OnInit()
{
PrintClear;
}
OnBarOpen(ArrayRef<Integer> indexs)
{
Numeric i;
//range的作用对所有品种计算相关指标
Range[i=0:datacount-1]
{
if(TrueDate(0)<>truedate(1))
{
MarginR = MarginRatio();
ConUnit = ContractUnit();
money1 = close[1] * ConUnit*MarginR;
numkai = round(max (1,20000/ money1 ),0);
}
hh = Highest(h,100);
ll = lowest(l,100);
hhfar = (hh[2]-c[1])/c[1]*100;
llfar = (c[1]-ll[2])/c[1]*100;
Commentary("data["+text(i)+"].hhfar="+text(hhfar));
Commentary("data["+text(i)+"].llfar="+text(llfar));
array_hhfar[i] = hhfar;//形成所有品种离高点距离的列表
array_llfar[i] = llfar;//形成所有品种离低点距离的列表
}
Commentary("高点距离:"+TextArray(array_hhfar));//默认在第一个品种图标上显示列表
Array<Integer> idh; //设置一个整数空列表
Array<Integer> idl;
for i = 0 to GetArraySize(array_hhfar)-1
{
idh[i] = i;//形成一个和所有品种数一样多的整数列表,作为各品种的标签
idl[i] = i;
}
Na1Sort2(array_hhfar,idh,0,GetArraySize(array_hhfar)-1,True);//对距离高点的幅度排序,返回排序好后品种对应的(标签)图层号
Commentary("高点距离排序"+TextArray(idh));//第一个品种图上显示排序好的品种(标签)顺序
Na1Sort2(array_llfar,idl,0,GetArraySize(array_llfar)-1,True);
Commentary("低点距离排序"+TextArray(idl));
//处理现有持仓
//平多排名靠后的多持仓
for i = 5 to GetArraySize(idh)-1
{
if( data[idh[i]].MarketPosition <> 0)
{
data[idh[i]].sell(numkai,Open);
Commentary("平多"+text(idh[i]));//显示交易品种
}
}
//持有空单排名靠后,平空单
for i = 5 to GetArraySize(idl)-1
{
if( data[idl[i]].MarketPosition <> 0)
{
data[idl[i]].BuyToCover(numkai,Open);
Commentary("空头平仓"+text(idl[i]));//显示交易品种
}
}
//分别确定开多品种和开空品种
Array<Integer> idh0; //设置一个整数空列表(排名前5列表)
Array<Integer> idl0; //设置一个整数空列表(排名前5列表)
Array<Integer> idhh; //设置一个整数空列表(删除重复后的交易列表)
Array<Integer> idll; //设置一个整数空列表(删除重复后的交易列表)
for i = 0 to 4
{
idh0[i] = idh[i];
idl0[i] = idl[i];
idhh[i] = idh[i];
idll[i] = idl[i];
}
//最后清理确定开多和开空的品种
for i = 0 to GetArraySize(idh0)-1
{
Bool iscontain = ArrayFind(idl0,idh0[i]); //逐一比较开多列表中品种是否有重叠
if (iscontain and data[idh0[i]].MarketPosition <> 0)
{
data[idh0[i]].sell(numkai,Open);//如果有持仓的话,平掉重复品种多仓
//去掉重复品种确定最后开多的品种列表
ArrayErase(idhh,idhh[i],1);
}
}
For i = 0 to GetArraySize(idl0)
{
Bool iscontainl = ArrayFind(idh0,idl0[i]);
if (iscontainl and data[idl0[i]].MarketPosition <> 0)
{
data[idl0[i]].BuyToCover(numkai,Open);//如果有持仓的话,平掉重复品种空仓
//去掉重复品种确定最后开空的品种列表
ArrayErase(idll,idll[i],1);
}
}
//多头开仓
for i = 0 to GetArraySize(idhh)-1
{
Commentary("开多品种:"+text(idhh[i]));
if( data[idhh[i]].MarketPosition<>1 )
{
data[idhh[i]].buy(numkai,open);
}
}
//空头开仓
for i = 0 to GetArraySize(idll)-1
{
Commentary("开空品种:"+text(idll[i]));
if(data[idll[i]].MarketPosition<>-1)
{
data[idll[i]].SellShort(numkai,open);
}
}
}
代码模式发了一次,谢谢
Params
//此处添加参数
Vars
series<Numeric> hh;
series<Numeric> ll;
series<Numeric> hhfar;
series<Numeric> llfar;
global array<Numeric> array_hhfar;
global array<Numeric> array_llfar;
array<integer> id1;
Series<Numeric> numkai;//开仓手数计算
Series<Numeric> money1;
Series<Numeric> MarginR;
Series<Numeric> ConUnit;
Events
OnInit()
{
PrintClear;
}
OnBarOpen(ArrayRef<Integer> indexs)
{
Numeric i;
//range的作用对所有品种计算相关指标
Range[i=0:datacount-1]
{
if(TrueDate(0)<>truedate(1))
{
MarginR = MarginRatio();
ConUnit = ContractUnit();
money1 = close[1] * ConUnit*MarginR;
numkai = round(max (1,20000/ money1 ),0);
}
hh = Highest(h,100);
ll = lowest(l,100);
hhfar = (hh[2]-c[1])/c[1]*100;
llfar = (c[1]-ll[2])/c[1]*100;
Commentary("data["+text(i)+"].hhfar="+text(hhfar));
Commentary("data["+text(i)+"].llfar="+text(llfar));
array_hhfar[i] = hhfar;//形成所有品种离高点距离的列表
array_llfar[i] = llfar;//形成所有品种离低点距离的列表
}
Commentary("高点距离:"+TextArray(array_hhfar));//默认在第一个品种图标上显示列表
Array<Integer> idh; //设置一个整数空列表
Array<Integer> idl;
for i = 0 to GetArraySize(array_hhfar)-1
{
idh[i] = i;//形成一个和所有品种数一样多的整数列表,作为各品种的标签
idl[i] = i;
}
Na1Sort2(array_hhfar,idh,0,GetArraySize(array_hhfar)-1,True);//对距离高点的幅度排序,返回排序好后品种对应的(标签)图层号
Commentary("高点距离排序"+TextArray(idh));//第一个品种图上显示排序好的品种(标签)顺序
Na1Sort2(array_llfar,idl,0,GetArraySize(array_llfar)-1,True);
Commentary("低点距离排序"+TextArray(idl));
//处理现有持仓
//平多排名靠后的多持仓
for i = 5 to GetArraySize(idh)-1
{
if( data[idh[i]].MarketPosition <> 0)
{
data[idh[i]].sell(numkai,Open);
Commentary("平多"+text(idh[i]));//显示交易品种
}
}
//持有空单排名靠后,平空单
for i = 5 to GetArraySize(idl)-1
{
if( data[idl[i]].MarketPosition <> 0)
{
data[idl[i]].BuyToCover(numkai,Open);
Commentary("空头平仓"+text(idl[i]));//显示交易品种
}
}
//分别确定开多品种和开空品种
Array<Integer> idh0; //设置一个整数空列表(排名前5列表)
Array<Integer> idl0; //设置一个整数空列表(排名前5列表)
Array<Integer> idhh; //设置一个整数空列表(删除重复后的交易列表)
Array<Integer> idll; //设置一个整数空列表(删除重复后的交易列表)
for i = 0 to 4
{
idh0[i] = idh[i];
idl0[i] = idl[i];
idhh[i] = idh[i];
idll[i] = idl[i];
}
//最后清理确定开多和开空的品种
for i = 0 to GetArraySize(idh0)-1
{
Bool iscontain = ArrayFind(idl0,idh0[i]); //逐一比较开多列表中品种是否有重叠
if (iscontain and data[idh0[i]].MarketPosition <> 0)
{
data[idh0[i]].sell(numkai,Open);//如果有持仓的话,平掉重复品种多仓
//去掉重复品种确定最后开多的品种列表
ArrayErase(idhh,idhh[i],1);
}
}
For i = 0 to GetArraySize(idl0)
{
Bool iscontainl = ArrayFind(idh0,idl0[i]);
if (iscontainl and data[idl0[i]].MarketPosition <> 0)
{
data[idl0[i]].BuyToCover(numkai,Open);//如果有持仓的话,平掉重复品种空仓
//去掉重复品种确定最后开空的品种列表
ArrayErase(idll,idll[i],1);
}
}
//多头开仓
for i = 0 to GetArraySize(idhh)-1
{
Commentary("开多品种:"+text(idhh[i]));
if( data[idhh[i]].MarketPosition<>1 )
{
data[idhh[i]].buy(numkai,open);
}
}
//空头开仓
for i = 0 to GetArraySize(idll)-1
{
Commentary("开空品种:"+text(idll[i]));
if(data[idll[i]].MarketPosition<>-1)
{
data[idll[i]].SellShort(numkai,open);
}
}
}
调试的方法就是先简化,确定出问题的点
比如排序有问题 还是开仓有问题,还是赋值不对等等
像你这种案例,肯定先检查排序值
老师,上周18号周四的直播课关于换月问题的还想再看下,线上答疑录播课里面没找到呢?请再上传下当期课程
排序我检查过没有问题,排出来的,我感觉是开仓逻辑有问题,你能帮看看吗
先学会控制变量,开仓上先调到1个多 1个空
简化
好的,谢谢