记次主力合约的对数价格 ln F 主力合约的价格 lnF2
lnF=A+BlnF1+resid
resid为残差.
R = resid_now/std(resid)
在满足协整的关系时,
当 R 的绝对值超过 .8 且小于 2.5 时开仓;
开仓后当 R 回落到 0.8 值时平仓;
开仓后当 R 的绝对值超过 2.5 时认亏平仓。
在数据对比上,这里仅取了两种合约共有的时间段。每个月的第三周五全部平仓
回测曲线(由Auto-trader提供回测报告)
策略源码:
function CSArb(bInit,bDayBegin,cellPar)%%% 函数说明% 上面的三个参数是一种固定结构。% 当在调用该函数如 StrategyName(a1,a2,a3,a4,a5,...).所有的参数都会被赋值给cellPar,即cellPar={a1,a2,a3,a4,a5,...}% bInit,在策略逻辑运行前为1,类似优矿等平台的initialize函数。当开始判断是否下单后,该变量为0.% bDayBegin 在一天的第一根Bar为1,其他时刻为0%% 外部和全局参数声明,这是一个固定结构.global g_idxKMin; % 注册日数据的index.日数据是分钟数据的合成.如在日中获取,当日的数据仅是当日已出现数据的合成,不包含之后的数据。global g_idxSignal;Freq=cellPar{1};%% 初始化回测帐户if bInit % traderSetParalMode(false);%默认是true,因子计算函数并行执行,速度快,不能调试,false串行执行可以设断点调试 g_idxKMin = traderRegKData('min',Freq);% 只有注册之后才能获取数据。分钟数据的获取方法为 traderRegKData('min',1)。后面的数字是刷新频率。 g_idxSignal = traderRegUserIndi(@getSignal,{g_idxKMin}); %计算因子。调用需要函数如getRange,大括号内是输入参数 %% 交易逻辑else dataDay = traderGetRegKData(g_idxKMin,1,false); if isnan(dataDay(5,end))|| isnan(dataDay(13,end)) || dataDay(1,end) ~= dataDay(9,end) return end signal = traderGetRegUserIndi(g_idxSignal,1); targetList = traderGetTargetList(); % 获取标的信息。 TLen = length(targetList); [mp,~,~]=traderGetAccountPositionV2(1,1:TLen); %% Third Friday Close All Order if signal(2,end)==1 if mp(1)~=0 traderPositionToV2(1,1,0,0,'market','close'); end if mp(2)~=0 traderPositionToV2(1,2,0,0,'market','close'); end return; end %% 14:50后 不交易 [~,BarTime] = traderGetCurrentBarV2(); % 获取当下时间 dateVec = datevec(BarTime); % datevec将时间转化为序列。对应[年,月,日,时,分,...] nowTime = dateVec(4)*100 + dateVec(5); if nowTime>1450 return; end if signal(1,end)>.8 && signal(1,end)<2.5 && mp(2)>=0 && mp(1)<=0 traderSellShortV2(1,2,1,0,'market','buy1');%开多单 traderBuyV2(1,1,1,0,'market','buy1');%开多单 elseif signal(1,end)<-.8 && signal(1,end)>-2.5 && mp(2)<=0 && mp(1)>=0 traderSellShortV2(1,1,1,0,'market','buy1');%开多单 traderBuyV2(1,2,1,0,'market','buy1');%开多单 elseif abs(signal(1,end))<=.8 || abs(signal(1,end))>=2.5 if mp(1)~=0 traderPositionToV2(1,1,0,0,'market','close'); end if mp(2)~=0 traderPositionToV2(1,2,0,0,'market','close'); end end endend%% 计算因子的自定义函数function value=getSignal(cellPar,bpPFCell)%调用该函数的参数将会全部被赋给cellPar%bpPFCell为一个时间序列,标记特定的刷新时刻%%%参数声明idxK =cellPar{1};%%%函数计算value=[100,0];regKMatrix = traderGetRegKData(idxK,240,false,bpPFCell);regKMatrix(:,any(isnan(regKMatrix),1))=[];if isempty(regKMatrix) returnendTime = intersect(regKMatrix(1,:),regKMatrix(9,:));[~,loc1] = ismember(Time,regKMatrix(1,:));[~,loc2] = ismember(Time,regKMatrix(9,:));current_data = regKMatrix(1:8,loc1);next_data = regKMatrix(9:end,loc2);[~,KLen]=size(current_data);if KLen < 200 returnendFit = polyfit(log(current_data(5,:)),log(next_data(5,:)),1);rsd1 = log(next_data(5,:))-log(current_data(5,:))*Fit(1)-Fit(2);[~,p_value] = adftest(rsd1);if p_value>0.01 returnendvalue(1) = rsd1(end)/std(rsd1,1);dates = floor(current_data(1,end));if sum((dates-[0,1,2,3]) == thirdFriday(dates))>0 value(2) = 1;endendfunction [ res ] = thirdFriday(dates )mt = month(dates);yr = year(dates);count = 0;for t = 1:eomday(yr,mt) res = datenum(yr,mt,t); if weekday(res,'long')==6 count = count + 1; end if count==3 break; endendend
更多免费策略源码下载请登录DigQuant社区-策略资源下载~


雷达卡


京公网安备 11010802022788号







