海龟交易法则与matlab程序代码.docx
《海龟交易法则与matlab程序代码.docx》由会员分享,可在线阅读,更多相关《海龟交易法则与matlab程序代码.docx(47页珍藏版)》请在冰点文库上搜索。
海龟交易法则与matlab程序代码
海龟交易法则与matlab程序代码
字号:
大中小%%%5
%%Turtle.M
%海龟交易法则(多品种、多市场)
%主要包括:
%?
市场----买卖什么,根据SVR强弱觉得买卖优先顺序
% ?
头寸规模----买卖多少,根据ATR以及不对称相关性风险矩阵进行寸风险管理
% ?
入市----何时买卖,根据突破信号辨别方法,辨别真假信号,并受账户资金水平限制其头寸,这里没有考虑到快速变化行情的滑点。
% ?
止损----何时退出亏损的头寸,根据ATR和固定损失水平设定。
这里没有考虑到快速变化行情的滑点。
% ?
离市----何时退出赢利的头寸,根据特定参数回归。
% ?
策略----如何买卖,此处只考虑了4种策略,但如何更细致的执行改策略我们没有考虑到。
如:
如何利用其他指标辅助,如何优化组合资产配置等。
%说明:
%为了明晰化思路,一些循环被拆成若干个子循环,影响了速度,但不妨碍我们学习和分析。
%为了更为精确的服务高频数据,这里设定所得数据为1分钟数据。
所以,这里特别要注意的是,程序目前只能处理同样交易时间的市场品种。
%那么,郑州和大连(9:
00-10:
1510:
30-11:
301:
30-3:
00),上海(9:
00-10:
1510:
30-11:
301:
30-2:
102:
20-3:
00),证券市场(9:
30-11:
301:
00-3:
00)就被割裂开来了。
%因为无法控制非对称时间窗口内的风险,策略和程序暂时不向此扩展和修改。
不过,如果用天数据,则不存在任何问题了。
%讨论:
%这里我没有写出强弱讨论程序,因为我觉得我的思路还不完全清晰。
我的初步想法是,根据相关性水平,如果上涨相关性水平高情形下,
%如果上涨击穿压力线,则买入最强的SVR,卖出最弱的;理论根据是journalofFinance2002,Andrew,and
%JournalofFinance2005,Patton
%writtenby:
%JemnboCai
%jemnbo@
%Thecopyrightbelongstome.Thecodesexchangedonlyforstudy.
%Foryourownapplication,loadyourdataintothematrix"data",andchangethe
%"controls"listedbelow
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%Controls%
functionturtle()
clearall;
closeall;
clc;
globalEMA;
globalRepeat
globalMargin;
globalSize;
globalAccount;
globalStr1
globalStr2
globalCorrLev
globalPosLim
globalFreq
Freq=240;%市场交易长度(分钟):
大连、郑州=225,上海=215,证券=240
STRATEGY=2;%选择的交易策略,1策略1;2策略2;3强弱套利;d
EMA=20;%计算指数平均的周期数d
Repeat=1;%多久时间重新算一次ATRD
Margin=[0.050.050.071];%所交易品种的保证金率1×i,i资产数量,股票为1
Size=[5581];%所交易品种的合约规模1×i,股票为1
Account=[100000000];%初始账户资金D
Str1_in=20;%策略一进场周期参数d
Str2_in=55;%策略二进场周期参数d
Str1_out=10;%策略一出场周期参数d
Str2_out=20;%策略二出场周期参数d
P_RSV=30*Freq;%相对强弱指标
CorrAdj=30*Freq;%市场相关性调查时间窗口长度,考虑到市场相关性的不对称性,买入考察下跌相关性,卖出考虑上涨相关性
CorrLev=[0.30.7];%相关性水平识别,高于它为高度相关性市场,低于它为低度相关市场。
1×2
PosLim=[4681012];%分别为单市场、高度相关、一般相关、低度相关、单向交易持仓限制1×5
HoldingPosition=[];%持仓,针对每一个品种,描述出其(开仓价格,持仓量,开仓方向,预设止损值,,开仓时间)4×(5×i)
LastPL=[];%平仓记录,【盈利状况多头水平空头水平开仓时间平仓时间】K*(5×i),k交易次数
Balance=[];%账户可用资金账户交易资产现值m*(2*i),m时间长度
%Loadyourowndataintomatrix"dat"@
%%数据初始化及参数设计
loaddata;
%{
海龟们用于确定能够参与交易的期货品种的主要标准就是构成市场基础的流动性。
每一个品种,我们要求具有以下几个指标:
开、高、低、收、量
%}
[mn]=size(data);
ifround(n/5)~=n/5||(m/Freq)<=max([Str1Str220])||length(Margin)~=length(Size)||length(Margin)~=n/5
error('你输入的数据格式不满足我们的要求,请重新核对数据质量')
end
Q=n/5;
Days=fix(m/Freq);
out=fopen('turtle','at');
fprintf(out,'**************************************************\n');
fprintf(out,'数据观察量:
%u\n',m);
fprintf(out,'一天观察次数:
%u\n',Freq);
fprintf(out,'研究的品种数量:
%u\n',Q);
fprintf(out,'所交易品种的保证金率:
所交易品种的合约规模:
\n');
fori=1:
Q
fprintf(out,'%u%u\n',Margin(i),Size(i));
end
fprintf(out,'选择的交易策略(1短线;2长线;3强弱套利):
%u\n',STRATEGY);
fprintf(out,'计算指数平均的周期数%u\n',EMA);
fprintf(out,'多久时间重新算一次:
%u\n',Repeat);
fprintf(out,'初始账户资金:
%u\n',Account);
fprintf(out,'策略一进场周期参数:
策略一出场周期参数:
\n');
fprintf(out,'%u%u\n',Str1_in,Str1_out);
fprintf(out,'策略二进场周期参数:
策略二出场周期参数:
\n');
fprintf(out,'%u%u\n',Str2_in,Str2_out);
fprintf(out,'相关性周期参数:
%u\n',CorrAdj);
fprintf(out,'相对强弱周期参数:
%u\n',P_RSV);
fprintf(out,'\n');
fclose(out);
%{
N就是TR(TrueRange,实际范围)的20日指数移动平均,现在更普遍地称之为ATR。
N表示单个交易日某个特定市场所造成的价格波动的平均范围。
N同样用构成合约基础的点(points)进行度量。
每日实际范围的计算:
TR(实际范围)=max(H-L,H-PDC,PDC-L)
式中:
H-当日最高价
L-当日最低价
PDC-前个交易日的收盘价
用下面的公式计算N:
N=(19×PDN+TR)/20
式中:
PDN-前个交易日的N值
TR-当日的实际范围
因为这个公式要用到前个交易日的N值,所以,你必须从实际范围的20日简单平均开始计算初始值。
%}
%需要多久计算一次N值和单位大小?
一般为一个星期一次,我这里用每天。
NMatrix=zeros(Days,Q);
fori=1:
Q
O=data(1:
Freq:
Days*Freq,i*5-4);H=data(1:
Freq:
Days*Freq,i*5-3);L=data(1:
Freq:
Days*Freq,i*5-2);C=data(1:
Freq:
Days*Freq,i*5-1);
V=data(1:
Freq:
Days*Freq,i*5);PDC=[0;C(1:
end-1,:
)];
%画出蜡烛图走势
cndl(O,H,L,C);
title('Figure蜡烛图');
ylabel('价格水平');
xlabel('观察样本');
gridon;
saveas(gcf,strcat('Candle_',num2str(i),'.eps'),'psc2');
forj=1:
Repeat:
Days
ifj==1
TR=max([H(j)-L(j)]);
NMatrix(i,j)=TR;
elseifj1
TR=max([H(j)-L(j),H(j)-PDC(j),PDC(j)-L(j)]);
NMatrix(i,j)=((j-1)*NMatrix(i,j-1)+TR)/j;
else
TR=max([H(j)-L(j),H(j)-PDC(j),PDC(j)-L(j)]);
NMatrix(i,j)=((EMA-1)*NMatrix(i,j-1)+TR)/EMA;
end
end
end
DailyData=data(1:
Freq:
Days*Freq,:
);
%{
价值量波动性=N×每点价值量
按照我们所称的单位(Units)建立头寸。
单位重新计算,使1N代表帐户净值的1%。
因为海龟把单位用作头寸规模的量度基础,还因为那些单位已经过波动性风险调整,所以,单位既是头寸风险的量度标准,又是头寸整个投资组合的量度标准。
单位=帐户的1%/(N×每点价值量)
%}
VN=zeros(Days,Q);%波动单位价值量,及其单位
%说明,此段被省略是因为在后面给出了更为精确的风险资金算法
%fori=1:
Q
%forj=1:
Days
%%调整交易规模,海龟不使用以起始净值为基础的、连续结算的标准帐户进行交易。
我们假设账户每季度调整一次。
盈利入金,亏损出金。
注意,此处
%%不精确,没有考虑P&L对资金的影响。
%ValuePerPoint=N(i,j)*Size(i)/Margin(i);%一手波动全部损失所值价值
%VN(i,j)=fix((0.01*Account)/ValuePerPoint);%用账户的1%来覆盖风险波动值,交易手数向下取整
%end
%end
HoldingPosition=zeros(4,5*Q);%持仓,针对每一个品种,描述出其(开仓价格,持仓量,开仓方向,预设止损值,开仓时间)4×(5×i)
LastPL=[0,0,0,0,1];%平仓记录,【盈利状况多头水平空头水平开仓时间平仓时间】K*(5×i),k交易次数
Balance=repmat([Account,0],m,1);%账户可用资金账户交易资产现值m*(2*i),m时间长度
%%交易策略正式开始测试:
%首先运算出辅助指标——RSV
RSV=50*ones(m,Q);
fori=1:
Q
O=data(:
i*5-4);H=data(:
i*5-3);L=data(:
i*5-2);C=data(:
i*5-1);
RSV(:
i)=rsv(H,L,C,P_RSV);
end
PLI=[DailyData(1,1:
5:
end);zeros(2,Q)];%上一次开仓价位、方向、以及盈利与否示性指标,确认短期开仓信号要用到。
ifSTRATEGY==1
forj=max([Str1_in,Str2_in,P_RSV/Freq])*Freq+1:
Days*Freq
Today=fix(j/Freq)+1;%现在所处的交易日
%系统一----以20日突破为基础的偏短线系统
%{
1,海龟的止损
有了止损并不意味着海龟总是让经纪人设置实际的止损指令。
因为海龟持有如此大量的头寸,所以,我们不想因为让经纪人设置止损指令而泄露我们的头寸或我们的交易策略。
相反,我们被鼓励设定某个价位,一旦达到该价位,我们就会使用限价指令或市价指令退出头寸。
2,离开市场
系统一离市对于多头头寸为10日最低价,对于空头头寸为10日最高价。
如果价格波动与头寸背离至10日突破,头寸中的所有单位都会退出。
%}
newlip=[0,0,0,inf,0];%平仓记录,【盈利状况多头水平空头水平开仓时间平仓时间】
MarketValue=0;%市值水平。
fori=1:
Q
O=data(j,i*5-4);H=data(j,i*5-3);L=data(j,i*5-2);C=data(j,i*5-1);
QuitL=min(DailyData(Today-Str1_out:
Today-1,i*5-2));
QuitH=max(DailyData(Today-Str1_out:
Today-1,i*5-3));
%HoldingPosition=zeros(4,5*Q);%持仓,针对每一个品种,描述出其(开仓价格,持仓量,开仓方向,预设止损值,开仓时间)4×(5×i)
ifany(HoldingPosition(:
i*5-4))%表示有档位的持仓非空
ii=find(HoldingPosition(:
i*5-3)~=0);
fork=1:
ii
ifHoldingPosition(k,i*5-2)==1%多头
ifL<=HoldingPosition(k,i*5-1)%止损触发
%LastPL=[0,0,0,0,1];%平仓记录,【盈利状况多头水平空头水平开仓时间平仓时间】K*(5×i),k交易次数
%Balance=[Account,0];%账户可用资金账户交易资产现值m*(2*i),m时间长度
newlip(1,1)=newlip(1,1)+(HoldingPosition(k,i*5-1)-HoldingPosition(k,i*5-4))*HoldingPosition(k,i*5-3);%盈亏
newlip(1,2)=newlip(1,2)-HoldingPosition(k,i*5-3);%多头减少量
newlip(1,3)=newlip(1,3)+0;
newlip(1,4)=min([newlip(1,4),HoldingPosition(k,i*5)]);
newlip(1,5)=max([newlip(1,5),j]);
HoldingPosition(k,:
)=zeros(1,5);%还原仓位
PLI(1,i)=HoldingPosition(k,i*5-4);%开仓价位
PLI(2,i)=1;%方向
PLI(3,i)=-1;%亏损与否
elseifL<=QuitL%退出触发
newlip(1,1)=newlip(1,1)+(HoldingPosition(k,i*5-1)-QuitL)*HoldingPosition(k,i*5-3);%盈亏
newlip(1,2)=newlip(1,2)-HoldingPosition(k,i*5-3);%多头减少量
newlip(1,3)=newlip(1,3)+0;
newlip(1,4)=min([newlip(1,4),HoldingPosition(k,i*5)]);
newlip(1,5)=max([newlip(1,5),j]);
HoldingPosition(k,:
)=zeros(1,5);%还原仓位
PLI(1,i)=HoldingPosition(k,i*5-4);%开仓价位
PLI(2,i)=1;%方向
if(HoldingPosition(k,i*5-1)-QuitL)*HoldingPosition(k,i*5-3)<0
PLI(3,i)=-1;%亏损
else
PLI(3,i)=1;%盈利
end
else
end
elseifHoldingPosition(k,i*5-2)==-1%空头
ifH>=HoldingPosition(k,i*5-1)%止损触发
%LastPL=[0,0,0,0,1];%平仓记录,【盈利状况多头水平空头水平开仓时间平仓时间】K*(5×i),k交易次数
%Balance=[Account,0];%账户可用资金账户交易资产现值m*(2*i),m时间长度
newlip(1,1)=newlip(1,1)-(HoldingPosition(k,i*5-1)-HoldingPosition(k,i*5-4))*HoldingPosition(k,i*5-3);%盈亏
newlip(1,2)=newlip(1,2)+0;
newlip(1,3)=newlip(1,3)-HoldingPosition(k,i*5-3);%空头减少量
newlip(1,4)=min([newlip(1,4),HoldingPosition(k,i*5)]);
newlip(1,5)=max([newlip(1,5),j]);
HoldingPosition(k,:
)=zeros(1,5);%还原仓位
PLI(1,i)=HoldingPosition(k,i*5-4);%开仓价位
PLI(2,i)=-1;%方向
PLI(3,i)=-1;%亏损与否
elseifH>=QuitH%退出触发
newlip(1,1)=newlip(1,1)-(HoldingPosition(k,i*5-1)-QuitH)*HoldingPosition(k,i*5-3);%盈亏
newlip(1,2)=newlip(1,2)+0;
newlip(1,3)=newlip(1,3)-HoldingPosition(k,i*5-3);%空头减少量
newlip(1,4)=min([newlip(1,4),HoldingPosition(k,i*5)]);
newlip(1,5)=max([newlip(1,5),j]);
HoldingPosition(k,:
)=zeros(1,5);%还原仓位
PLI(1,i)=HoldingPosition(k,i*5-4);%开仓价位
PLI(2,i)=-1;%方向
if-(HoldingPosition(k,i*5-1)-QuitH)*HoldingPosition(k,i*5-3)<0
PLI(3,i)=-1;%亏损
else
PLI(3,i)=1;%盈利
end
else
end
else
end
end
end
end
%更新平仓历史记录
ifnewlip(1,1)~=0
LastPL=[LastPL;newlip];
end
fori=1:
Q
O=data(j,i*5-4);H=data(j,i*5-3);L=data(j,i*5-2);C=data(j,i*5-1);
MarketValue=MarketValue+sum(HoldingPosition(:
i*5-3)*C);
end
%更新账户损益信息
Balance(j,:
)=[Balance(j-1,1)+newlip(1,1),MarketValue];
%%
%开仓信号产生和确认以及加仓信号的确认
%{
如果上次突破已导致赢利的交易,系统一的突破入市信号就会被忽视。
注意:
为了检验这个问题,上次突破被视为某种商品上最近一次的突破,
而不管对那次突破是否实际被接受,或者因这项法则而被忽略。
如果有赢利的10日离市之前,突破日之后的价格与头寸方向相反波动了2N,
那么,这一突破就会被视为失败的突破。
上次突破的方向与这项法则无关。
因此,亏损的多头突破或亏损的空头突破将使随后新的突破被视为有效的突破,而不管它的方向如何(即多头或空头)。
然而,如果系统一的入市突破由于以前的交易已经取得赢利而被忽略,还可以在55日突破时入市,以避免错过主要的波动。
这种55日突破被视为自动保险突破点(FailsafeBreakoutpoint)。
多品种组合时,开仓顺序按照相对强弱指标排序进行对比。
做多时,买强;做空时,卖弱。
%}
RSV_j=RSV(j,:
);
[ssr]=sort(RSV_j,'descend');%获得从大到小排序。
[s2sr2]=sort(RSV_j);%获得从小到大排序。
%率先对仓位和风险水平做一个核算。
%风险水平,根据相关性水平进行那个核算。
%首先要把价格序列转换成收益率。
MCorr=[0;0];%下相关和上相关
fori=1:
Q
fork=i+1
Ci=data(j-CorrAdj:
j,i*5-1);Ck=data(j-CorrAdj:
j,k*5-1);
ri=price2ret(Ci);rk=price2ret(Ck);
[corrxy]=exceedence_corr(ri,rk,0,0);%均值左右的相关性<0;>0
MCorr=MCorr+corrxy;
end
end
MCorr=MCorr/(i*(i-1)/2);
%做多风险控制,观察下跌相关性风险
ifMCorr(1,1)<=CorrLev(1,1)
CB=PosLim(1,4);
elseifMCorr(1,1)>=CorrLev(1,2)
CB=PosLim(1,2);
else
CB=PosLim(1,3);
end
%做空风险控制,观察上涨相关性风险
ifMCorr(2,1)<=CorrLev(1,1)
CS=PosLim(1,4);
elseifMCorr(2,1)>=CorrLev(1,2)
CS=PosLim(1,2);
else
CS=PosLim(1,3);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%再统计现在剩余的盘口数
%{
最大头寸限制为:
级别类型最大单位
1单一市场4个单位
2高度相关市场6个单位
3一般相关度市场8个单位
4低度相关市场10个单位
5单向交易—多头或空头12个单位
如果止损风险容度为2N,对单向交易而言,一次性系统承担的最大风险为-24%
%}
BQ=0;%买单位数buyquantity
SQ