avatar of 发明者量化-小小梦 发明者量化-小小梦
konzentrieren Sie sich auf Private Nachricht
4
konzentrieren Sie sich auf
1271
Anhänger

Digitaler Währungsvertrag – Einfacher Kopierhandelsroboter

Erstellt in: 2021-04-07 21:30:05, aktualisiert am: 2024-12-05 21:59:36
comments   11
hits   4372

Digitaler Währungsvertrag – Einfacher Kopierhandelsroboter

Digitaler Währungsvertrag – Einfacher Kopierhandelsroboter

In früheren Artikeln haben wir einen einfachen Spot-Copy-Trading-Roboter implementiert. Heute werden wir eine Vertragsversion eines einfachen Copy-Trading-Roboters implementieren.

Gestaltungsideen

Es gibt einen großen Unterschied zwischen der Vertragsversion des Copy-Trading-Roboters und der Spot-Version. Spot-Copy-Trading kann hauptsächlich durch die Überwachung von Änderungen des Kontovermögens erreicht werden. Die Futures-Version erfordert die Überwachung von Änderungen der Kontopositionen. Daher ist die Situation in der Futures-Version komplizierter, da Futures Long-Positionen, Short-Positionen und unterschiedliche Kontrakte haben. Diese Reihe an Angaben gilt es zu verarbeiten. Die Kernidee besteht darin, Positionsänderungen zu überwachen. Lösen Sie anhand der Positionsänderung den Kopiervorgang aus. Bei der ersten Konzeption war geplant, sowohl Long- als auch Short-Positionen gleichzeitig abzuwickeln. Man stellte jedoch fest, dass dies sehr kompliziert werden würde. Nach der Analyse des Problems wurde entschieden, die Long- und Short-Positionen getrennt zu behandeln.

Strategieumsetzung

Strategieparameter:

Digitaler Währungsvertrag – Einfacher Kopierhandelsroboter

Backtesting wird unterstützt und Sie können die Standardeinstellungen für Backtesting-Beobachtungen direkt verwenden.

Quellcode der Strategie:

/*backtest
start: 2021-03-18 00:00:00
end: 2021-04-07 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"},{"eid":"Futures_OKCoin","currency":"BTC_USD"}]
*/

function test() {
    // 测试函数
    var ts = new Date().getTime()    
    if (ts % (1000 * 60 * 60 * 6) > 1000 * 60 * 60 * 5.5) {
        Sleep(1000 * 60 * 10)
        var nowPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
        var longPosAmount = nowPosAmount.long
        var shortPosAmount = nowPosAmount.short
        var x = Math.random()
        if (x > 0.7) {
            exchange.SetDirection("buy")
            exchange.Buy(-1, _N(Math.max(1, x * 10), 0), "参考账户测试开单#FF0000")
        } else if(x < 0.2) {
            exchange.SetDirection("sell")
            exchange.Sell(-1, _N(Math.max(1, x * 10), 0), "参考账户测试开单#FF0000")
        } else if(x >= 0.2 && x <= 0.5 && longPosAmount > 4) {
            exchange.SetDirection("closebuy")
            exchange.Sell(-1, longPosAmount, "参考账户测试平仓#FF0000")
        } else if(shortPosAmount > 4) {
            exchange.SetDirection("closesell")
            exchange.Buy(-1, _N(shortPosAmount / 2, 0), "参考账户测试平仓#FF0000")
        }
    }
}

function getPosAmount(pos, ct) {
    var longPosAmount = 0
    var shortPosAmount = 0
    _.each(pos, function(ele) {
        if (ele.ContractType == ct && ele.Type == PD_LONG) {
            longPosAmount = ele.Amount
        } else if (ele.ContractType == ct && ele.Type == PD_SHORT) {
            shortPosAmount = ele.Amount
        }
    })
    return {long: longPosAmount, short: shortPosAmount}
}

function trade(e, ct, type, delta) {
    var nowPosAmount = getPosAmount(_C(e.GetPosition), ct)
    var nowAmount = type == PD_LONG ? nowPosAmount.long : nowPosAmount.short
    if (delta > 0) {
        // 开仓
        var tradeFunc = type == PD_LONG ? e.Buy : e.Sell
        e.SetDirection(type == PD_LONG ? "buy" : "sell")
        tradeFunc(-1, delta)
    } else if (delta < 0) {
        // 平仓
        var tradeFunc = type == PD_LONG ? e.Sell : e.Buy
        e.SetDirection(type == PD_LONG ? "closebuy" : "closesell")
        if (nowAmount <= 0) {
            Log("未检测到持仓")
            return 
        }
        tradeFunc(-1, Math.min(nowAmount, Math.abs(delta)))
    } else {
        throw "错误"
    }
}

function main() {
    LogReset(1)
    if (exchanges.length < 2) {
        throw "没有跟单的交易所"
    }
    var exName = exchange.GetName()
    // 检测参考交易所
    if (!exName.includes("Futures_")) {
        throw "仅支持期货跟单"
    }
    Log("开始监控", exName, "交易所", "#FF0000")
    
    // 检测跟单交易所
    for (var i = 1 ; i < exchanges.length ; i++) {
        if (exchanges[i].GetName() != exName) {
            throw "跟单的期货交易所和参考交易所不同!"
        }
    }
    
    // 设置交易对、合约
    _.each(exchanges, function(e) {
        if (!IsVirtual()) {
            e.SetCurrency(refCurrency)
            if (isSimulate) {
                if (e.GetName() == "Futures_OKCoin") {
                    e.IO("simulate", true)
                }
            }
        }
        e.SetContractType(refCt)
    })

    var initRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
    while(true) {
        if (IsVirtual()) {    // 回测时才模拟
            test()            // 测试函数,模拟参考账户主动交易,触发跟单账户跟单        
        }
        Sleep(5000)
        var nowRefPosAmount = getPosAmount(_C(exchange.GetPosition), refCt)
        var tbl = {
            type : "table", 
            title : "持仓",
            cols : ["名称", "标签", "多仓", "空仓", "账户资产(Stocks)", "账户资产(Balance)"],
            rows : []
        }
        _.each(exchanges, function(e) {
            var pos = getPosAmount(_C(e.GetPosition), refCt)
            var acc = _C(e.GetAccount)
            tbl.rows.push([e.GetName(), e.GetLabel(), pos.long, pos.short, acc.Stocks, acc.Balance])
        })
        LogStatus(_D(), "\n`" + JSON.stringify(tbl) + "`")
        
        // 计算仓位变动量
        var longPosDelta = nowRefPosAmount.long - initRefPosAmount.long
        var shortPosDelta = nowRefPosAmount.short - initRefPosAmount.short

        // 检测变动
        if (longPosDelta == 0 && shortPosDelta == 0) {
            continue
        } else {
            // 检测到仓位变动
            for (var i = 1 ; i < exchanges.length ; i++) {
                // 执行多头动作
                if (longPosDelta != 0) {
                    Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "执行多头跟单,变动量:", longPosDelta)
                    trade(exchanges[i], refCt, PD_LONG, longPosDelta)
                }
                // 执行空头动作
                if (shortPosDelta != 0) {
                    Log(exchanges[i].GetName(), exchanges[i].GetLabel(), "执行空头跟单,变动量:", shortPosDelta)
                    trade(exchanges[i], refCt, PD_SHORT, shortPosDelta)
                }
            }
        }

        // 执行跟单操作后,更新
        initRefPosAmount = nowRefPosAmount
    }
}

prüfen

Da OKEX nach der Aktualisierung der V5-Schnittstelle die OKEX-Simulationsdiskette verwenden kann, habe ich zum bequemen Testen zwei API-Schlüssel für die OKEX-Simulationsdiskette verwendet.

Das erste hinzugefügte Austauschobjekt ist der Referenzaustausch, und der Kopieraustausch folgt bei der Ausführung diesem Austauschkonto. Platzieren Sie auf der OKEX-Simulationshandelsseite manuell 3 vierteljährliche münzbasierte ETH-Verträge basierend auf dem Börsenkonto.

Digitaler Währungsvertrag – Einfacher Kopierhandelsroboter

Es ist ersichtlich, dass der reale Markt die Änderungen in den Positionen der Referenzbörsenkonten erkennt und dann den Vorgängen folgt.

Digitaler Währungsvertrag – Einfacher Kopierhandelsroboter

Versuchen wir, die beiden soeben eröffneten Vertragspositionen zu schließen. Die Positionen nach dem Schließen sind wie in der Abbildung dargestellt:

Digitaler Währungsvertrag – Einfacher Kopierhandelsroboter

Verfolgen Sie den Echtzeitvorgang und schließen Sie 2 Verträge ab.

Digitaler Währungsvertrag – Einfacher Kopierhandelsroboter

Diese Strategie ist einfach und leicht verständlich gestaltet, ohne jegliche Optimierung. Die Verbesserung muss sich noch mit Details wie der Asset-Erkennung beim Befolgen von Aufträgen befassen. Der Einfachheit halber werden Marktaufträge zum Befolgen von Aufträgen verwendet. . Die Strategie dient lediglich der Vermittlung von Lerninhalten und der eigentliche Handel wird bedarfsgerecht optimiert.

Strategieadresse: https://www.fmz.com/strategy/270012

Hinterlassen Sie gern eine Nachricht.