Les ressources ont été chargées... Je charge...

Les contrats de crypto-monnaie sont faciles à suivre pour les robots

Auteur:L'inventeur de la quantification - un petit rêve, Créé: 2021-04-07 21:30:05, Mis à jour: 2023-09-24 19:35:33

img

Les contrats de crypto-monnaie sont faciles à suivre pour les robots

Dans un précédent article, nous avons réalisé un simple robot de facturation instantanée, aujourd'hui nous avons réalisé un robot de facturation simple en version contractuelle.

Des idées de conception

Les contrats sont très différents de la version en temps réel. La version en temps réel est principalement réalisée en surveillant les changements d'actifs sur les comptes. La version à terme nécessite de surveiller les changements de positions sur les comptes. La version des futures est donc un peu plus compliquée, car les futures ont plusieurs titres, des titres vides et des contrats différents. Le système de traitement de l'échantillon est basé sur les variations de l'échantillon. Il a été conçu à l'origine pour traiter les échantillons à plusieurs têtes et à des têtes vides.

Mise en œuvre de la stratégie

Paramètres de stratégie:

img

La prise en charge de l'observation de retouche peut être utilisée directement avec l'observation de retouche par défaut.

Le code source de la stratégie:

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

Le test

Étant donné que l'interface V5 d'OKEX a été mise à jour et que l'on peut utiliser l'analogue OKEX, j'ai testé très facilement avec les deux API KEY d'OKEX.

Le premier objet d'échange ajouté est un objet de référence, et chaque échange suit son compte. Sur la page de l'analogique d'OKEX, le compte de référence de l'échange peut être activé manuellement avec 3 contrats d'ETH sur une base trimestrielle.

img

Vous pouvez voir que le disque réel détecte les changements dans la détention des comptes de l'échange de référence, puis il suit l'opération.

img

Nous allons essayer d'aplanir les deux positions que nous venons d'ouvrir, et les positions après l'aplanissement sont les suivantes:

img

Le disque réel suit l'opération et équivaut à deux contrats.

img

Cette stratégie est conçue de manière simple et facile à comprendre, sans optimisation, la partie perfectionnée nécessite également de traiter les détails tels que la détection des actifs lors de la facturation.

L'adresse de la stratégie:https://www.fmz.com/strategy/270012

Bienvenue dans les commentaires.


Relationnée

Plus de

Pw1013Deux bourses différentes ne peuvent pas se connecter.

le groupe Mingxi1005Quand l'inventeur pourra-t-il gagner des contrats à terme sur des paires de pièces?

- Je ne sais pas.J'espère qu'il y aura une version payante de Bitcoin.

au99Vous souhaitez une version de Bitcoin sous contrat permanent, l'API de l'exécuteur?????

ZhousoneNous espérons avoir une version du token usdt sous contrat permanent

Je ne sais pas.Merci pour votre partage, ça vaut le coup d'apprendre.

L'inventeur de la quantification - un petit rêveComme les spécifications des contrats peuvent varier d'une bourse à l'autre, le code de l'ordre peut être modifié en fonction des circonstances.

Pw1013L'échange bibox que j'utilise, avec 80% de commissions, est parfaitement soutenu par FMZ.

Pw1013Si vous souhaitez modifier le bibox futures que j'utilise actuellement, et que vous souhaitez connecter à l'échange okx de quelqu'un d'autre, où est-ce que vous pouvez le modifier?

L'inventeur de la quantification - un petit rêveIl est possible de changer le code.

L'inventeur de la quantification - un petit rêvePour évaluer cette bourse, personne ne nous a contacté.