手把手教你移植一个麦语言策略(进阶)

2019-12-14  本文已影响0人  发明者量化

上一篇文章手把手教你写策略--移植一个my语言策略中,对于一个简单的麦语言策略做了移植测试,如果是一个稍微复杂一点的麦语言,如何移植成JavaScript语言的策略呢?这里面有哪些技巧呢?

我们首先看下这次要移植的策略:

(*backtest
start: 2019-05-01 00:00:00
end: 2019-11-12 00:00:00
period: 1d
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
args: [["SlideTick",10,126961],["ContractType","quarter",126961]]
*)

N1:=10;
N2:=21;
AP:=(HIGH+LOW+CLOSE)/3;
ESA:=EMA(AP,N1);
D:=EMA(ABS(AP-ESA),N1);
CI:=(AP-ESA)/(0.015*D);
TCI:=EMA(CI,N2);
WT1:TCI;
WT2:SMA(WT1,4,1);
AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;

这个麦语言策略开头的部分(*backtest...*)是回测设置的配置代码,为了方便对比,设定一个统一的回测配置。这个策略也是随机找的一个策略,也并不算太复杂(相对上次文章中的复杂一些),是比较有代表性的策略。移植一个麦语言策略,首先要通篇看下策略内容,麦语言策略代码比较简练,基本上看下来可以对策略全局有一定的认识,这个策略我们看到使用到了几种指标函数EMASMA

先造个轮子

编写填充部分

策略框架使用手把手教你写策略--移植一个my语言策略文章中相同的框架,主要填充两个部分:

image

首先,做行情数据处理、指标计算。


image

我们把麦语言这部分一句一句的功能逐个处理:

交易信号的移植就非常简单了。

AA:=CROSS(WT1,WT2);
BB:=CROSSDOWN(WT1,WT2);
REF(AA,1),BPK;
REF(BB,1),SPK;

阅读这几句麦语言代码,可知,就是对于WT1、WT2这两条指标线的金叉、死叉判断作为开仓条件,需要注意的是,使用的是前一个交叉信号。
直接用该麦语言策略回测,我们观察下:


image

通过麦语言策略实际运行观察可知,在开仓点检测到信号时,实际是检测开仓点这个BAR往前数2个BAR的位置是否是金叉。上图可以明显看出:


image image

信号检测部分的填充代码可以写为:

if ((_State == IDLE || _State == SHORT) && wt1[wt1.length - 4] < wt2[wt2.length - 4] && wt1[wt1.length - 3] > wt2[wt2.length - 3]) {
    if (_State == IDLE) {
        _State = OPENLONG
        Log("OPENLONG")    // 测试
    }
    if (_State == SHORT) {
        _State = COVERSHORT
        Log("COVERSHORT")  // 测试
    }
    isOK = false  
}

if ((_State == IDLE || _State == LONG) && wt1[wt1.length - 4] > wt2[wt2.length - 4] && wt1[wt1.length - 3] < wt2[wt2.length - 3]) {
    if (_State == IDLE) {
        _State = OPENSHORT
        Log("OPENSHORT")  // 测试
    }
    if (_State == LONG) {
        _State = COVERLONG
        Log("COVERLONG")  // 测试
    }
    isOK = false   
}

这里可以思考下,为什么麦语言的SPK、BPK指令可以用以上代码实现。

回测

回测配置:


image

麦语言版本回测:


image

JavaScript版本回测:


image image

OnTick函数开头部分的代码,用来让回测速度快一点,是让策略以收盘价模型来运行,有兴趣可以详细分析下。

function OnTick(){
    // 驱动策略的行情处理部分
    var records = _C(exchange.GetRecords)
    if (records[records.length - 1].Time == preTime) {
        if (isOK) {
            Sleep(500)
            return 
        }
    } else {
        preTime = records[records.length - 1].Time
    }
    ...
    ..
    .

完整的教学策略代码:
https://www.fmz.com/strategy/174457

感谢阅读

上一篇 下一篇

猜你喜欢

热点阅读