O recurso está a ser carregado... Carregamento...

Estratégias ATR para futuros de moeda digital de várias variedades (instruções)

Autora:Inventor quantificado - sonho pequeno, Criado: 2022-01-07 11:11:54, Atualizado: 2023-09-15 20:54:33

img

Estratégias ATR para futuros de moeda digital de várias variedades (instruções)

Recentemente, os usuários de plataformas esperam muito que uma estratégia de Mac seja portada para uma estratégia de JavaScript, o que permite a flexibilidade de adicionar muitas ideias de otimização; até mesmo ampliar a estratégia para a maior variedade de versões; porque as estratégias de Mac geralmente são estratégias de tendência e muitas são executadas em modelos de preço de fechamento. As interfaces de API de solicitação de estratégias não são muito frequentes e são mais adequadas para a portação de várias versões de estratégia.

Estratégias para transplante

TR:=MAX(MAX((H-L),ABS(REF(C,1)-H)),ABS(REF(C,1)-L));
ATR:=EMA(TR,LENGTH2);

MIDLINE^^EMA((H + L + C)/3,LENGTH1);
UPBAND^^MIDLINE + N*ATR;
DOWNBAND^^MIDLINE - N*ATR;


BKVOL=0 AND C>=UPBAND AND REF(C,1)<REF(UPBAND,1),BPK;
SKVOL=0 AND C<=DOWNBAND AND REF(C,1)>REF(DOWNBAND,1),SPK;

BKVOL>0 AND C<=MIDLINE,SP(BKVOL);
SKVOL>0 AND C>=MIDLINE,BP(SKVOL);
// 止损
// stop loss
C>=SKPRICE*(1+SLOSS*0.01),BP;
C<=BKPRICE*(1-SLOSS*0.01),SP;
AUTOFILTER;

Esta estratégia de negociação é muito simples: primeiro, calcula-se o ATR com base nos parâmetros, e depois calcula-se o valor médio dos preços de fechamento mais altos, mais baixos e mais baixos de todos os BARs da linha K, e, com base nesses dados, obtém-se o indicador EMA. Finalmente, combina-se o coeficiente N no parâmetro ATR.

A abertura de posições, contra-mão é baseada no preço de fechamento quebrando a trajetória para baixo. A abertura de trajetória contra-mão (quando se tem uma posição de cabeça vazia) é mais frequente, a abertura da trajetória para baixo contra-mão. Quando o preço de fechamento atinge a linha média, o preço de fechamento até o preço de stop-loss também estabiliza (de acordo com o stop-loss SLOSS, o SLOSS é 1 ou 0.01, ou 1%). A estratégia é executada com o modelo de preço de fechamento.

OK, agora que entendemos as necessidades estratégicas e ideias da língua Ma, podemos começar a transplante-la.

Transplante, protótipo de estratégia de design

O código do protótipo de estratégia não tem mais de 1 a 200 linhas. Para facilitar o aprendizado das ideias de redação da estratégia, escreva as notas diretamente no código da estratégia.

// 解析params参数,从字符串解析为对象
var arrParam = JSON.parse(params)

// 该函数创建图表配置
function createChartConfig(symbol, atrPeriod, emaPeriod, index) {   // symbol : 交易对, atrPeriod : ATR参数周期 , emaPeriod : EMA参数周期 , index 对应的交易所对象索引
    var chart = {                                        
        __isStock: true,    
        extension: {
                layout: 'single', 
                height: 600, 
        },
        title : { text : symbol},                       
        xAxis: { type: 'datetime'},           
        series : [                                          
            {                                      
                type: 'candlestick',    // K线数据系列                         
                name: symbol,   
                id: symbol + "-" + index,
                data: []                                           
            }, {                                      
                type: 'line',           // EMA
                name: symbol + ',EMA:' + emaPeriod,          
                data: [],               
            }, {
                type: 'line',           // upBand
                name: symbol + ',upBand' + atrPeriod,
                data: []
            }, {
                type: 'line',           // downBand
                name: symbol + ',downBand' + atrPeriod,
                data: []
            }, {
                type: 'flags',
                onSeries: symbol + "-" + index,
                data: [],
            }
        ]
    }
    return chart
}

// 主要逻辑
function process(e, kIndex, c) {    // e 即交易所对象,exchanges[0] ... , kIndex K线数据在图表中的数据系列, c 为图表对象
    // 获取K线数据
    var r = e.GetRecords(e.param.period)
    if (!r || r.length < e.param.atrPeriod + 2 || r.length < e.param.emaPeriod + 2) {
        // K线数据长度不足则返回
        return 
    }

    // 计算ATR指标
    var atr = TA.ATR(r, e.param.atrPeriod)
    var arrAvgPrice = []
    _.each(r, function(bar) {
        arrAvgPrice.push((bar.High + bar.Low + bar.Close) / 3)
    })
    // 计算EMA指标
    var midLine = TA.EMA(arrAvgPrice, e.param.emaPeriod)
    // 计算上下轨
    var upBand = []
    var downBand = [] 
    _.each(midLine, function(mid, index) {
        if (index < e.param.emaPeriod - 1 || index < e.param.atrPeriod - 1) {
            upBand.push(NaN)
            downBand.push(NaN)
            return 
        }
        upBand.push(mid + e.param.trackRatio * atr[index])
        downBand.push(mid - e.param.trackRatio * atr[index])
    })

    // 画图
    for (var i = 0 ; i < r.length ; i++) {
        if (r[i].Time == e.state.lastBarTime) {
            // 更新
            c.add(kIndex, [r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close], -1)
            c.add(kIndex + 1, [r[i].Time, midLine[i]], -1)
            c.add(kIndex + 2, [r[i].Time, upBand[i]], -1)
            c.add(kIndex + 3, [r[i].Time, downBand[i]], -1)
        } else if (r[i].Time > e.state.lastBarTime) {
            // 添加
            e.state.lastBarTime = r[i].Time
            c.add(kIndex, [r[i].Time, r[i].Open, r[i].High, r[i].Low, r[i].Close])  
            c.add(kIndex + 1, [r[i].Time, midLine[i]])
            c.add(kIndex + 2, [r[i].Time, upBand[i]])
            c.add(kIndex + 3, [r[i].Time, downBand[i]])
        }
    }

    // 检测持仓
    var pos = e.GetPosition()
    if (!pos) {
        return 
    }
    var holdAmount = 0
    var holdPrice = 0
    if (pos.length > 1) {
        throw "同时检测到多空持仓!"
    } else if (pos.length != 0) {
        holdAmount = pos[0].Type == PD_LONG ? pos[0].Amount : -pos[0].Amount
        holdPrice = pos[0].Price
    }

    if (e.state.preBar == -1) {
        e.state.preBar = r[r.length - 1].Time
    }
    // 检测信号
    if (e.state.preBar != r[r.length - 1].Time) {   // 收盘价模型
        if (holdAmount <= 0 && r[r.length - 3].Close < upBand[upBand.length - 3] && r[r.length - 2].Close > upBand[upBand.length - 2]) {   // 收盘价上穿上轨
            if (holdAmount < 0) {   // 持有空仓,平仓
                Log(e.GetCurrency(), "平空仓", "#FF0000")
                $.CoverShort(e, e.param.symbol, Math.abs(holdAmount))
                c.add(kIndex + 4, {x: r[r.length - 2].Time, color: 'red', shape: 'flag', title: '平', text: "平空仓"})
            }
            // 开多
            Log(e.GetCurrency(), "开多仓", "#FF0000")
            $.OpenLong(e, e.param.symbol, 10)
            c.add(kIndex + 4, {x: r[r.length - 2].Time, color: 'red', shape: 'flag', title: '多', text: "开多仓"})
        } else if (holdAmount >= 0 && r[r.length - 3].Close > downBand[downBand.length - 3] && r[r.length - 2].Close < downBand[downBand.length - 2]) {  // 收盘价下穿下轨
            if (holdAmount > 0) {   // 持有多仓,平仓
                Log(e.GetCurrency(), "平多仓", "#FF0000")
                $.CoverLong(e, e.param.symbol, Math.abs(holdAmount))
                c.add(kIndex + 4, {x: r[r.length - 2].Time, color: 'green', shape: 'flag', title: '平', text: "平多仓"})
            }
            // 开空
            Log(e.GetCurrency(), "开空仓", "#FF0000")
            $.OpenShort(e, e.param.symbol, 10)
            c.add(kIndex + 4, {x: r[r.length - 2].Time, color: 'green', shape: 'flag', title: '空', text: "开空仓"})
        } else {
            // 平仓
            if (holdAmount > 0 && (r[r.length - 2].Close <= holdPrice * (1 - e.param.stopLoss) || r[r.length - 2].Close <= midLine[midLine.length - 2])) {   // 持多仓,收盘价小于等于中线,按开仓价格止损
                Log(e.GetCurrency(), "触发中线或止损,平多仓", "#FF0000")
                $.CoverLong(e, e.param.symbol, Math.abs(holdAmount))
                c.add(kIndex + 4, {x: r[r.length - 2].Time, color: 'green', shape: 'flag', title: '平', text: "平多仓"})
            } else if (holdAmount < 0 && (r[r.length - 2].Close >= holdPrice * (1 + e.param.stopLoss) || r[r.length - 2].Close >= midLine[midLine.length - 2])) {  // 持空仓,收盘价大于等于中线,按开仓价格止损
                Log(e.GetCurrency(), "触发中线或止损,平空仓", "#FF0000")
                $.CoverShort(e, e.param.symbol, Math.abs(holdAmount))
                c.add(kIndex + 4, {x: r[r.length - 2].Time, color: 'red', shape: 'flag', title: '平', text: "平空仓"})
            }
        }
        e.state.preBar = r[r.length - 1].Time
    }
}

function main() {
    var arrChartConfig = []
    if (arrParam.length != exchanges.length) {
        throw "参数和交易所对象不匹配!"
    }
    var arrState = _G("arrState")
    _.each(exchanges, function(e, index) {
        if (e.GetName() != "Futures_Binance") {
            throw "不支持该交易所!"
        }
        e.param = arrParam[index]
        e.state = {lastBarTime: 0, symbol: e.param.symbol, currency: e.GetCurrency()}
        if (arrState) {
            if (arrState[index].symbol == e.param.symbol && arrState[index].currency == e.GetCurrency()) {
                Log("恢复:", e.state)
                e.state = arrState[index]
            } else {
                throw "恢复的数据和当前设置不匹配!"
            }
        }
        e.state.preBar = -1   // 初始设置-1
        e.SetContractType(e.param.symbol)
        Log(e.GetName(), e.GetLabel(), "设置合约:", e.param.symbol)
        arrChartConfig.push(createChartConfig(e.GetCurrency(), e.param.atrPeriod, e.param.emaPeriod, index))
    })
    var chart = Chart(arrChartConfig)
    chart.reset()

    while (true) {
        _.each(exchanges, function(e, index) {
            process(e, index + index * 4, chart)
            Sleep(500)
        })      
    }
}

function onexit() {
    // 记录 e.state
    var arrState = []
    _.each(exchanges, function(e) {
        arrState.push(e.state)
    })
    Log("记录:", arrState)
    _G("arrState", arrState)
}

Parâmetros da estratégia:

var params = '[{
        "symbol" : "swap",    // 合约代码
        "period" : 86400,     // K线周期,86400秒即为一天
        "stopLoss" : 0.07,    // 止损系数,0.07即7%
        "atrPeriod" : 10,     // ATR指标参数
        "emaPeriod" : 10,     // EMA指标参数
        "trackRatio" : 1,     // 上下轨系数
        "openRatio" : 0.1     // 预留的开仓百分比,暂时没支持
    }, {
        "symbol" : "swap",
        "period" : 86400,
        "stopLoss" : 0.07,
        "atrPeriod" : 10,
        "emaPeriod" : 10,
        "trackRatio" : 1,
        "openRatio" : 0.1
    }]'

Testes de repetição

img

img

O código da estratégia:https://www.fmz.com/strategy/339344

A estratégia é apenas para testes, estudos e estudos.


Relacionados

Mais.