Ein einfaches Zahlungsverfahren für digitale Währungskontrakte

Schriftsteller:Kleine Träume, Erstellt: 2021-04-07 21:30:05, Aktualisiert: 2023-09-24 19:35:33

img

Ein einfaches Zahlungsverfahren für digitale Währungskontrakte

In einem früheren Artikel haben wir einen einfachen Roboter für die Berechnung von Bestellungen realisiert, heute haben wir einen einfachen Roboter für die Berechnung von Verträgen realisiert.

Entwurfsideen

Die Kontrakte unterscheiden sich stark von der Handbuchversion. Die Handbuchversion kann hauptsächlich durch die Überwachung von Vermögensveränderungen im Konto realisiert werden. Die Futures-Version erfordert jedoch die Überwachung von Veränderungen in den Konten. Die Situation mit Futures ist also etwas komplizierter, da Futures mehrere Halden, leere Halten und verschiedene Verträge haben. Es wurde ursprünglich geplant, Multi-Head, Empty Heads zusammen zu behandeln, aber es stellte sich heraus, dass diese Behandlung sehr kompliziert wird. Nach der Analyse wurde entschieden, dass Multi-Head, Empty Heads getrennt behandelt werden sollten.

Strategie umgesetzt

Strategieparameter:

img

Sie unterstützen Retesting und können direkt mit dem Standard-Retest-Observer eingesetzt werden.

Die Strategie ist hier:

/*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
    }
}

Tests

Da die OKEX-Analogdisken nach dem Update V5 verfügbar sind, habe ich die zwei OKEX-Analogdisken API KEY sehr praktisch getestet.

Das erste hinzugefügte Austauschobjekt ist die Referenzbörse, und jede Austauschbörse wird mit diesem Austauschkonto verarbeitet. Auf der OKEX-Diskseite können Sie die Quartals-Ethinkontrakte für 3 ETH manuell mit dem Referenz-Börse-Konto aktivieren.

img

Sie können sehen, dass die reale Platte die Veränderungen in den Aktienbeständen der Referenzbörse erkennt und dann der Operation folgt.

img

Wenn wir die beiden gerade eröffneten Positionen wieder ausgleichen, dann sehen wir, wie die Positionen nach dem Ausgleich aussehen:

img

Die Spieler haben zwei Verträge ausgeglichen.

img

Diese Strategie ist einfach und verständlich konzipiert, ohne Optimierung, und der vollständige Teil muss auch Details wie die Asset-Prüfung bei der Abrechnung behandeln. Um es einfach zu gestalten, wurde die Abrechnung nur mit Marktpreisen durchgeführt.

Die Strategie ist unter:https://www.fmz.com/strategy/270012

Ich bin sehr froh, dass Sie sich bei uns melden können.


Verwandt

Mehr

pw1013Zwei verschiedene Börsen können nicht zusammenarbeiten.

Mingxi1005Wann werden die Erfinder die Münzen paaren und Futures-Kontrakte gewinnen?

AkklcIch wünschte, es gäbe eine kostenlose Version von Bitcoin.

Lau99Ich möchte eine dauerhaft vertraglich vertraglich vereinbarte Version von Binusdt, die API des Ausführers????

ZhousoneIch hoffe, dass es eine dauerhafte Vertragserfassung von USDT gibt.

- Ich weiß nicht.Danke fürs Teilen, es ist wert, gelernt zu haben.

Kleine TräumeDa sich die Vertragsspezifikationen von Börse zu Börse unterscheiden können, kann es notwendig sein, den Code der Aufforderung anhand der jeweiligen Situation anzupassen.

pw1013Ich benutze die Bibox-Börse mit 80 Prozent Kommissionsrückerstattung, die von FMZ voll unterstützt wird.

pw1013Wenn ich die Bibox-Futures benutze, die ich jetzt benutze, und wenn ich die OX-Börse von jemand anderem verknüpfen möchte, wo muss ich sie ändern?

Kleine TräumeDas ist möglich, wenn man den Code ändert.

Kleine TräumeWir haben noch keine Kontaktaufnahme von der Börse erhalten, um diese Börse zu bewerten.