金字塔教程之阿火秘笈——汇集各种模型编写方法(适用于所有模型的组合)
本帖最后由 火焰之神 于 2015-4-8 16:54 编辑 <br /><br />一,如何把“K线走完模式”的模型转换成“固定轮询模式”的模型以便把各个模型放在同一个框架内进行图表程序化交易
举例:
均线交叉模型(K线走完模型):
runmode:0;
ma5:=ma(c,5);
ma20:=ma(c,20);
entertime:=time>100000 and time<144500;
if holding>0 and ma5<ma20 then sell(1,1,market);
if holding<0 and ma5>ma20 then sellshort(1,1,market);
if holding=0 and ma5>ma20 and entertime then buy(1,1,market);
if holding=0 and ma5<ma20 and entertime then buyshort(1,1,market);
if time>=150000 then begin
sell(1,1,market);
sellshort(1,1,market);
end
简单的改法,自然是把各个条件“过去化”,如:ma5 改为 ref(ma(c,5),1);但这种方法碰到大型的、复杂的模型时,容易出错
可采用这种方法,把holding用全局变量cc替换,然后加入红色部分代码,红色部分代码要放在信号语句的前面:
runmode:0;
variable:cc=0;
ma5:=ma(c,5);
ma20:=ma(c,20);
entertime:=time>100000 and time<144500;
if holding>0 and cc<=0 then sell(1,1,limitr,o);
if holding<0 and cc>=0 then sellshort(1,1,limitr,o);
if holding=0 and cc>0 then buy(1,1,limitr,o);
if holding=0 and cc<0 then buyshort(1,1,limitr,o);
if cc>0 and ma5<ma20 then cc:=0;
if cc<0 and ma5>ma20 then cc:=0;
if cc=0 and ma5>ma20 and entertime then cc:=1;
if cc=0 and ma5<ma20 and entertime then cc:=-1;
if time>=150000 then begin
cc:=0;
end
那么,如果是 K线走完模式和盘中模式并存,怎么做呢?也简单,就是在“开盘价下单语句”后面加入蓝色部分的“盘中下单语句”就行了
如下:
runmode:0;
variable:zs=0,cc=0;
ma5:=ma(c,5);
ma20:=ma(c,20);
entertime:=time>100000 and time<144500;
if holding>0 and cc<=0 then sell(1,1,limitr,o);
if holding<0 and cc>=0 then sellshort(1,1,limitr,o);
if holding=0 and cc>0 then buy(1,1,limitr,o);
if holding=0 and cc<0 then buyshort(1,1,limitr,o);
if cc>0 and l<zs then begin
sell(1,1,limitr,min(o,zs-0.6));
cc:=0;
end
if cc<0 and h>zs then begin
sellshort(1,1,limitr,max(o,zs+0.6));
cc:=0;
end
if cc>0 and ma5<ma20 then cc:=0;
if cc<0 and ma5>ma20 then cc:=0;
if cc=0 and ma5>ma20 and entertime then begin
cc:=1;
zs:=c-10;
end
if cc=0 and ma5<ma20 and entertime then begin
cc:=-1;
zs:=c+10;
end
if time>=150000 then begin
cc:=0;
end
本帖最后由 火焰之神 于 2015-4-8 16:54 编辑 <br /><br />二、移动止损的编写方法:
还是以之前的模型为例,希望加入移动止损,即:开仓后的最高点回落10个点要盘中止损离场
加入一个全局变量 hl,记录开多后的最高点,开空后的最低点:
runmode:0;
variable:zs=0,cc=0,hl=0;
ma5:=ma(c,5);
ma20:=ma(c,20);
entertime:=time>100000 and time<144500;
if holding>0 and cc<=0 then sell(1,1,limitr,o);
if holding<0 and cc>=0 then sellshort(1,1,limitr,o);
if holding=0 and cc>0 then buy(1,1,limitr,o);
if holding=0 and cc<0 then buyshort(1,1,limitr,o);
if cc>0 and l<zs then begin
sell(1,1,limitr,min(o,zs-0.6));
cc:=0;
end
if cc<0 and h>zs then begin
sellshort(1,1,limitr,max(o,zs+0.6));
cc:=0;
end
if cc>0 and ma5<ma20 then cc:=0;
if cc<0 and ma5>ma20 then cc:=0;
if cc=0 and ma5>ma20 and entertime then begin
cc:=1;
zs:=c-10;
hl:=h;
end
if cc=0 and ma5<ma20 and entertime then begin
cc:=-1;
zs:=c+10;
hl:=l;
end
if cc>0 and h>hl then begin//创新高后,上移hl
hl:=h;
zs:=hl-10;
end
if cc<0 and l<hl then begin//创新低后,下移hl
hl:=l;
zs:=hl+10;
end
if time>=150000 then begin
cc:=0;
end
本帖最后由 火焰之神 于 2015-4-8 16:54 编辑 <br /><br />三、逐K线模式的模型,用免费版下单交易的方法
runmode:0;
variable:cc=0;
ma5:=ma(c,5);
ma20:=ma(c,20);
entertime:=time>100000 and time<144500;
exitlong:cc<>1,tfilter;
exitshort:cc<>-1,tfilter;
enterlong:ref(cc,1)<>1 and cc=1,tfilter;
entershort:ref(cc,1)<>-1 and cc=-1,tfilter;
if cc>0 and ma5<ma20 then cc:=0;
if cc<0 and ma5>ma20 then cc:=0;
if cc=0 and ma5>ma20 and entertime then cc:=1;
if cc=0 and ma5<ma20 and entertime then cc:=-1;
if time>=150000 then cc:=0;
原理是,用全局变量cc记录仓位,然后根据仓位的变化情况来确定下单信号
本帖最后由 火焰之神 于 2015-4-8 16:55 编辑 <br /><br />四、日内满仓反手的写法
因为满仓的情况下,要等平仓单成交、保证金释放后,开仓下单才能成功。
用系统自带的orderqueue在平仓单没有第一时间成交的情况下有一定的局限性,可用如下的方法:
runmode:0;
input:cw(3,1,10,1);
variable:cc=0;
ma5:=ma(c,5);
ma20:=ma(c,20);
entertime:=time>100000 and time<144500;
if holding>0 and cc<=0 then sell(1,cw,limitr,o);
if holding<0 and cc>=0 then sellshort(1,cw,limitr,o);
//此方法撤单和追单时间要控制在出信号的K线时间以内
if holding=0 and cc>0 and cw+tholding2>=cw then buy(1,cw,limitr,o);//平空成交后,"cw+tholding2>=cw "才会成立并开多
if holding=0 and cc<0 and cw-tholding2>=cw then buyshort(1,cw,limitr,o);//平多成交后,"cw-tholding2>=cw "才会成立并开空
if cc>0 and ma5<ma20 then cc:=0;
if cc<0 and ma5>ma20 then cc:=0;
if cc=0 and ma5>ma20 and entertime then cc:=1;
if cc=0 and ma5<ma20 and entertime then cc:=-1;
if time>=150000 then begin
cc:=0;
end
本帖最后由 火焰之神 于 2015-4-8 16:55 编辑 <br /><br />五、自行计算最大回撤的方法,放到逐K线模式的模型最后面即可:
zichan:asset,noaxis;
if barpos=1 then begin
MaxAsset:=zichan;
Maxhc:=0; end
if zichan>MaxAsset then MaxAsset:=zichan;
if MaxAsset-zichan>Maxhc then Maxhc:=MaxAsset-zichan;
最大回撤:Maxhc,linethick0;
交易次数:totaltrade,linethick0;
正确率:percentwin,linethick0;
//这里的变量"MaxAsset”、"Maxhc" 其实是全局变量,可不必声明。有重新赋值变量值才会改变
本帖最后由 火焰之神 于 2015-4-8 16:55 编辑 <br /><br />六、“后台下单模板”,可用于各种模型。不会写后台模型的塔友,以后不用写了,复制此模板即OK。
只要把此模板放在 模型的最后面,就可以后台全自动化交易了。此方法还有一个好处,即使用固定轮询模式,也不会漏单
有个性化需求的,也可在此模板上的基础上定制。不会的可以找我。
runmode:0;
Globalvariable:hold=drawnull;
……//这里添加上你自己的模型
……//这里添加上你自己的模型
cc800988:=holding;//这句放在信号稳定的地方,即时下单的,就放下单语句的后面,K线走完下单的就放下单语句的前面
drawtextex(1,1,800,0,'虚拟持仓为:'+numtostr(cc800988,0));//在图表上输出虚拟持仓以便监控
if not(islastbar) or workmode<>1 then exit;
xiadan800988:=cc800988-hold;
if xiadan800988>0.5 then begin
cang:=min(xiadan800988,abs(hold));
if hold<0 then begin
tsellshort(1,cang,mkt,0,0,'800988'),allowrepeat;
debugfile('D:\800988.txt',numtostr(hold,0)+' '+numtostr(cc800988,0)+' 平空 %.0f',cang);//监控语句
end
cang:=xiadan800988+min(hold,0);
if cang>0 then begin
tbuy(1,cang,mkt,0,0,'800988'),allowrepeat;
debugfile('D:\800988.txt',numtostr(hold,0)+' '+numtostr(cc800988,0)+' 开多 %.0f',cang);//监控语句
end
end
if xiadan800988<-0.5 then begin
cang:=min(abs(xiadan800988),abs(hold));
if hold>0 then begin
tsell(1,cang,mkt,0,0,'800988'),allowrepeat;
debugfile('D:\800988.txt',numtostr(hold,0)+' '+numtostr(cc800988,0)+' 平多 %.0f',cang);//监控语句
end
cang:=abs(xiadan800988)-max(hold,0);
if cang>0 then begin
tbuyshort(1,cang,mkt,0,0,'800988'),allowrepeat;
debugfile('D:\800988.txt',numtostr(hold,0)+' '+numtostr(cc800988,0)+' 开空 %.0f',cang);//监控语句
end
end
hold:=cc800988;
本帖最后由 火焰之神 于 2015-4-8 16:55 编辑 <br /><br />七、把各种模型组合成一个模型的方法,适用于所有模型,即便是“即时下单模型”
说明:因为图表交易同一根K线出现2个开多信号的话,只会开一次,另外一个无法执行,但是可以做历时回测
组合起来的模型,加入后台下单语句,就可以用于后台下单,当然,后台下单用“后台下单模板”会更好用。
方法原理:计算每个时点要下单的手数和方向,再根据holding判断出要平仓和开仓的数量,然后再下单。
看起来很多,其实很简单,最基本得模块就是蓝色部分
input:cang1(1,0,10,1),cang2(1,0,10,1);
variable:cc1=0,cc2=0;
/////////////////////////////////模型1——10周期反手
hi:=ref(hhv(h,10),1);
lo:=ref(llv(l,10),1);
if cc1>0 and l<lo then begin
pc:=min(max(holding,0),cang1);
kc:=cang1-pc;
if pc>0 then sell(1,cang1,limitr,min(o,lo-0.2)-0.6);
if kc>0 then buyshort(1,cang1,limitr,min(o,lo-0.2)-0.6);
cc1:=0;
end
if cc1<0 and h>hi then begin
pc:=min(abs(min(holding,0)),cang1);
kc:=cang1-pc;
if pc>0 then sellshort(1,cang1,limitr,max(o,hi+0.2)+0.6);
if kc>0 then buy(1,cang1,limitr,max(o,hi+0.2)+0.6);
cc1:=0;
end
if cc1=0 and h>hi then begin
pc:=min(abs(min(holding,0)),cang1);
kc:=cang1-pc;
if pc>0 then sellshort(1,cang1,limitr,max(o,hi+0.2)+0.6);
if kc>0 then buy(1,cang1,limitr,max(o,hi+0.2)+0.6);
cc1:=1;
end
if cc1=0 and l<lo then begin
pc:=min(max(holding,0),cang1);
kc:=cang1-pc;
if pc>0 then sell(1,cang1,limitr,min(o,lo-0.2)-0.6);
if kc>0 then buyshort(1,cang1,limitr,min(o,lo-0.2)-0.6);
cc1:=-1;
end
/////////////////////////////////以上是模型1
/////////////////////////////////模型2——20周期反手
hi:=ref(hhv(h,20),1);
lo:=ref(llv(l,20),1);
if cc2>0 and l<lo then begin
pc:=min(max(holding,0),cang2);
kc:=cang2-pc;
if pc>0 then sell(1,cang2,limitr,min(o,lo-0.2)-0.6);
if kc>0 then buyshort(1,cang2,limitr,min(o,lo-0.2)-0.6);
cc2:=0;
end
if cc2<0 and h>hi then begin
pc:=min(abs(min(holding,0)),cang2);
kc:=cang2-pc;
if pc>0 then sellshort(1,cang2,limitr,max(o,hi+0.2)+0.6);
if kc>0 then buy(1,cang2,limitr,max(o,hi+0.2)+0.6);
cc2:=0;
end
if cc2=0 and h>hi then begin
pc:=min(abs(min(holding,0)),cang2);
kc:=cang2-pc;
if pc>0 then sellshort(1,cang2,limitr,max(o,hi+0.2)+0.6);
if kc>0 then buy(1,cang2,limitr,max(o,hi+0.2)+0.6);
cc2:=1;
end
if cc2=0 and l<lo then begin
pc:=min(max(holding,0),cang2);
kc:=cang2-pc;
if pc>0 then sell(1,cang2,limitr,min(o,lo-0.2)-0.6);
if kc>0 then buyshort(1,cang2,limitr,min(o,lo-0.2)-0.6);
cc2:=-1;
end
/////////////////////////////////以上是模型2
//有更多的模型,往后面添加即可
本帖最后由 火焰之神 于 2015-4-8 16:55 编辑 <br /><br />八、提前N秒下单的方法,适用于各个周期 。
//这里以股指期货为例,商品原理类似:关键是找出K线结束的时间规律。
//以下红色部分是K线结束时间的规律
ma5:=ma(c,5);
ma10:=ma(c,10);
zq:=2;//N分钟周期,3分钟就填3 ,5分钟就填5
tq:=5;//提前的秒数,最多提前60秒
opentm:=openminutes(dynainfo(207));
lastopentm:=if(date<>ref(date,1),0,ref(openminutes(time),1));
abb:=(mod(dynainfo(207),100)>=60-tq and islastbar and (opentm-lastopentm=zq-1 or time=113000 or time=151500)) or not(islastbar);
if holding>0 and ma5<ma10 and abb then sell(1,1,thisclose);
if holding<0 and ma5>ma10 and abb then sellshort(1,1,thisclose);
if holding=0 and ma5>ma10 and abb then buy(1,1,thisclose);
if holding=0 and ma5<ma10 and abb then buyshort(1,1,thisclose);
{
如果所交易的品种不够活跃,动态行情dynainfo(207)不是每一秒钟都有的
那么,abb这个变量可以这样写,要注意保证本机时间准确:
abb:=(mod(currenttime,100)>=60-tq and islastbar and (opentm-lastopentm=zq-1 or time=113000 or time=151500)) or not(islastbar);
本帖最后由 火焰之神 于 2015-4-8 16:55 编辑 <br /><br />阿火很强!
金字塔很好!
{:37:}
本帖最后由 火焰之神 于 2015-4-8 16:55 编辑 <br /><br />{:05:}
本帖最后由 火焰之神 于 2015-4-8 16:55 编辑 <br /><br />九、 通过飞信给自己发短信的VBA代码
以下红色部分要变动,千万不要跟我说复制黏贴后就想发短信
Set fs=CreateObject("Microsoft.XMLHTTP")
num="13900***688" '这里输入开通飞信的手机号
pwd="iloveweistock" '这里请输入飞信密码
dat="&pass="&pwd&"&m="&num
fs.Send dat
sub fsfx()
msg="股指开多"
fs.Open "POST",dm&"user/sendMsgToMyselfs.action",False
fs.Send "msg="&msg
End Sub
把以上部分复制到Macro地下,输入开通飞信的手机号码和飞信密码输入,后按alt+F8,输入宏名 fsfx 即可收到“股指开多”的短信
把Sub过程换成Function函数,就可以通过自定义函数,根据条件实时地给自己发送短信
比如:
runmode:0;
Globalvariable: tvo=0;
If buycond and Tvo<>barpos and islastbar Then Begin
fs(1);//1是参数
tvo:=barpos;
End
自定义函数可以这样写:
Function fs(Formula,trend)
'系统会在逐K线模式解释公式时的每个周期都会调用此函数一遍,因此设计时应该注重程序的执行效率,不要重复的执行一些没必要的代码
if trend=1 then
msg="股指开多"
end if
if trend=2 then
msg="股指平多"
end if
if trend=3 then
msg="股指开空"
end if
if trend=4 then
msg="股指平空"
end if
if trend=5 then
msg="股指平空开多"
end if
if trend=6 then
msg="股指平多开空"
end if
fs.Open "POST",dm&"user/sendMsgToMyselfs.action",False
fs.Send "msg="&msg
fs=1
End Function
{:05:}{:05:}{:05:}{:05:}{:05:}{:05:}{:28:}{:28:}{:28:} 祝所有金字塔用户 爱好者 新春大吉 龙年大发! {:05:}{:05:}{:05:}{:05:}{:05:}{:05:} {:05:}{:05:} {:01:}{:02:}{:03:}{:13:} 闪电交易要收费 文华不收{:03:}{:03:} 各版本收费情况,见官网。
十、在小周期级别上记录大周期指标的实际走势的方法
这里以1分钟引用3分钟的macd为例,常规方法只能在1分钟K线上显示3分钟K线的macd走势,至于3分钟内部每根1分钟K线的macd走势不知道
方法原理:获取上一根3分钟的diff、dea、macd,然后配合1分钟的CLOSE计算出实际的diff、dea、macd
第一步、首先在macd指标里加入以下2句:
ema12: ema(c,12),linethick0;
ema26: ema(c,26),linethick0;
第二步、复制以下代码即可
runmode:1;
em1:=stkindi(stklabel,'macd.ema12',0,17,-1);
em2:=stkindi(stklabel,'macd.ema26',0,17,-1);
ema12:=em1*11/13+c*2/13;
ema26:=25/27* em2 +c*2/27;
diff:ema12-ema26;
dea1:=stkindi(stklabel,'macd.dea',0,17,-1);
dea:dea1*4/5+diff/5;
十一、日内重新计算指标(macd)的方法,以避免跳空对指标造成的影响。
这里顺带介绍一下日内重新计算指标的方法,这样可以避免跳空对指标造成的影响。
比较难的是macd,kdj之类的,均线之类的简单
这里依然以macd为例
runmode:0;
variable:ema12=c,ema26=c,dea=0;
if day<>ref(day,1) then begin
ema12:=c;
ema26:=c;
dea:=0;
end
ema12:=ema12*11/13+c*2/13;
ema26:=ema26*25/27+c*2/27;
diff:ema12-ema26;
dea:=dea*4/5+diff/5;
dea1:dea;
macd:2*(diff-dea),colorstick;
研究研究