做程序出身,见了公式难免想到优化问题。
网上有许多的公式号称多厉害,譬如五彩K线,到底哪个最好,好到什么程度,没有具体的数值,专门写了一个公式用来对五彩K线指标进行多重组合,选出最后组合,这才是最需要的。
相比炒股软件中自带的回测工具,这个无疑是最灵活的,可以实现你的大绝多说想法,并给出一个量化的验证结果。
要求也稍微高一些,能编写基本的公式代码,可以在我这个代码上自己任意修改,前后的框架不用动,只需要把中间的修改即可。
同时,如果针对一个指标优化参数,一样可以用这个进行改进,无非是多重for循环的问题,欢迎大家讨论。
另外一个,账户里面没金币,不能完全免费了,实在和我一样没金币的,发吧,有时间上来会回复的。
代码示例,详细说明见附件:
{
使用说明:
1.引入金魔方后,打开K线图,日线;kt交易师本质上也是支持的,只不过每次需要单独在另外一个公式中将全局变量 G_currentIndex 重置为0。金魔方也可以在软件菜单里面,程式交易->全局变量里面查看、修改和删除。
2.打开浦发银行600000K线图
3、将这个公式拖入附图指标中,等待附图窗口出现一条白线,表明已经计算完毕。如果你的机器慢的话,可能在主图窗口右上角有一个显示运行中的小黄圆圈,不断旋转。
4、由于软件的bug,有时候前面几个股票计算完毕后,并不会自动跳转到下一个股票,所以需要手动翻到下一个,我一般用键盘上的PgDn,也就是下一页完成,鼠标滚动有的是缩放功能,有的是太快,翻过很多个股票了。
5、等待,公式运行完毕混自动将附图指标设定为kdj指标,同时再次跳转到浦发银行那个K线图上。这表示完成了所有统计。
6、在excel里面查看csv文件,可以对不同的参数组合分别统计总数和成功次数,这里面经常用到excel的sumifs函数,可以了解一下,网上很多帮助。
7、很明显,公式的两头的是框架。这个框架的作用就是能够完全控制的实现自己的思路,并对所有的数据进行测试,得出自己思路的全部回测结果。
8、这个框架能干什么呢:
1)任意多个指标的组合,用多重循环可以搞定,不过这里面有个计算量的问题需要注意;毕竟3000多个A股,一个一秒,就需要1小时了,我曾经最长的用时24小时,不过对优化确实很有效,不是自己翻几个K线图看看能比的。
2单个指标的参数优化,比如都说macd金叉如何,那么12 26 9这个参数是最适合的吗?未必,可以按自己的优化目标进行参数优化,之后自己优化的才是自己的,才心理有谱,用起来也得心应手。
3 更复杂一点,多个指标的组合和参数一起优化,工作量肯定不小,可以通过多个机器分开跑,比如第一个机器只跑前面1000只股票,第二个接力,第三个再接力,结果是可以直接合并的。
9.结果中,需要按照股票代码和参数一起做一个唯一值,对结果进行去重,理论上不应该重复,或者只有一条重复,但软件有bug,这个去重还是需要做一下,有一半的机会是没有重复结果的。
}
stkblkName:='A股板块';
stkblkcount:=STKCOUNT(stkblkName);
currentIndex := GetGlobalVar('G_currentIndex');
if currentindex<1 then
currentindex:=1;
Else
currentindex+=1;
setGlobalVar('G_currentIndex',currentindex);
//下面加入需要统计的内容
Function getCondi
input:
CondiNumber(1,1,30000);
Begin
cond1:= REF(CLOSE,2)/REF(OPEN,2) < 0.95 AND
REF(OPEN,1) < REF(CLOSE,2) AND
ABS(REF(OPEN,1)-REF(CLOSE,1))/REF(CLOSE,1)<0.03 AND
CLOSE/OPEN>1.05 AND CLOSE>REF(CLOSE,2);//早晨之星
cond2:=REF(CLOSE,1)/REF(OPEN,1)<0.97 AND
CLOSE/OPEN>1.03 AND
OPEN
CLOSE>REF(CLOSE,1);//曙光初现
cond3:=REF(CLOSE,2)>REF(OPEN,2) AND
REF(CLOSE,1)>REF(OPEN,1) AND
CLOSE>OPEN AND
REF(CLOSE,1)>REF(CLOSE,2) AND
CLOSE>REF(CLOSE,1); //三个白武士
cond4:=HIGH=CLOSE AND HIGH<>LOW; //光头阳线
cond5:=CLOSE/OPEN>1.05 AND HIGH/LOW < CLOSE/OPEN+0.018; //大阳烛 继续看涨或者见底
cond6:=LOW>REF(HIGH,1); //向上突破缺口
cond7:=(HIGH-MAX(CLOSE,OPEN))/(HIGH-LOW)>0.667 and Range(abs(close/ref(close,1)-1),0.009,0.031); //仙人指路
cond8:=1;//"000diFenXing.ot"(0) ;,原本为缠论中底分型条件,这里暂时取消,不影响测试,可以换成自己的任何其他指标
cond9:=cross("dmi-ql.pdi","dmi-ql.mdi" );//
if(CondiNumber>0) then Begin
i:=INTPART((CondiNumber-1)/2)+1;//七个指标中的哪一个
j:=CondiNumber-(i-1)*2;//1 2 3表示一个指标的ref(,1),exist(,1)状态,
cond:=false;
Switch (i) Begin
case 1: Begin
cond:=cond1;
end
case 2: Begin
cond:=cond2;
end
case 3: Begin
cond:=cond3;
end
case 4: Begin
cond:=cond4;
end
case 5: Begin
cond:=cond5;
end
case 6: Begin
cond:=cond6;
end
case 7: Begin
cond:=cond7;
end
case 8: Begin
cond:=cond8;
end
case 9: Begin
cond:=cond9;
end
end;
Switch (j) Begin
case 1: Begin
cond:=ref(cond,1);
end
case 2: Begin
//cond:=cond;
end
end;
end;
Else//其它因子默认为true
cond:=true;
Return cond;
end;
close_zhangTing:=round(ref(close,1),3)+round(round(ref(close,1),3)*0.1,3);
close_new:=round(close,3);
FeiZhangTingcond01:=iif(close_new>=close_zhangTing,0, close_zhangTing-close_new>=0.010) ;//非涨停严格条件
TotalNums:=18;
GroupNums:=2;
Cond005:=close*1.005<=max(refx(high,1),refx(high,2));//成功条件,对公式优化很关键,可以改成自己的任意条件,比如两日内收盘价创新高
Cond010:=close*1.01<=max(refx(high,1),refx(high,2));//
outStr = '';
filename:='d:/paras/'+FormulaName(0)+ '_'+NumToStr(DataType,0)+'.csv';
for i=1 to TotalNums do Begin //两个一组,可以设置三个或者四个一组,这里是表示一个指标的ref(,1),exist(,1)状态,
for j=(INTPART((i-1)/GroupNums)+1)*GroupNums+1 to TotalNums do Begin
allcond:=getCondi(i) and getCondi(j) and FeiZhangTingcond01;//
if count(allcond>0,0)>0 then Begin
for k=0 to TotalNums do Begin
if k=0 or k>= (INTPART((j-1)/GroupNums)+1)*GroupNums+1 then Begin
allcond:=getCondi(i) and getCondi(j) and getCondi(k) and FeiZhangTingcond01;//
allcount:=count(allcond>0,0);
if allcount>0 then Begin
outStr := NumToStr(i,0) + ',' + NumToStr(j,0) + ',' + NumToStr(k,0) + ',' + //
NumToStr( allcount,0) + ',' +
NumToStr( count( allcond and Cond005,0),0) + ',' +
NumToStr( count( allcond and Cond010,0),0) ;
FileAppend(filename,STKLABEL,',',outStr);
end;
end;
end;
end;
end;
end;
//切换股票
if currentindex<=stkblkcount then
OpenChartView(STKFROMBLK(stkblkName,currentindex),'',P_Day);
Else
Begin
OpenChartView(STKFROMBLK(stkblkName,1),'kdj',P_Day);
PLAYSOUND(1,0,'D:/KT/Sound/ALERT7.WAV');
end;