avatar of 发明者量化-小小梦 发明者量化-小小梦
Seguir Mensajes Privados
4
Seguir
1271
Seguidores

Robot de copia de transacciones de contratos de moneda digital simple

Creado el: 2021-04-07 21:30:05, Actualizado el: 2024-12-05 21:59:36
comments   11
hits   4372

Robot de copia de transacciones de contratos de moneda digital simple

Robot de copia de transacciones de contratos de moneda digital simple

En artículos anteriores, implementamos un robot de operaciones de copia al contado simple. Hoy, implementaremos una versión de contrato de un robot de operaciones de copia simple.

Ideas de diseño

Existe una gran diferencia entre la versión de contrato del robot de copy trading y la versión spot. La versión spot de copy trading se puede lograr principalmente monitoreando los cambios en los activos de la cuenta. La versión de futuros requiere monitorear los cambios en las posiciones de la cuenta. Por lo tanto, la situación en la versión de futuros es más complicada, porque los futuros tienen posiciones largas, posiciones cortas y contratos diferentes. Esta serie de detalles necesita ser procesada. La idea central es monitorear los cambios en las posiciones. Activar la acción de copia en función del cambio de posición. Cuando se diseñó inicialmente, se planeó manejar posiciones largas y cortas juntas, pero se descubrió que esto se volvería muy complicado. Después de analizar el problema, se decidió manejar las posiciones largas y cortas por separado.

Implementación de la estrategia

Parámetros de la estrategia:

Robot de copia de transacciones de contratos de moneda digital simple

Se admite la realización de pruebas retrospectivas y puedes usar directamente la configuración predeterminada para realizar pruebas retrospectivas de las observaciones.

Código fuente de la estrategia:

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

prueba

Dado que OKEX puede usar el disco de simulación de OKEX después de actualizar la interfaz V5, utilicé dos CLAVES API de disco de simulación de OKEX para realizar pruebas convenientes.

El primer objeto de intercambio agregado es el intercambio de referencia, y el intercambio de copia seguirá esta cuenta de intercambio para operar. En la página de simulación de operaciones de OKEX, coloque manualmente 3 contratos trimestrales basados ​​en monedas ETH según la cuenta de intercambio.

Robot de copia de transacciones de contratos de moneda digital simple

Se puede observar que el mercado real detecta los cambios en las posiciones de las cuentas de cambio de referencia y luego sigue las operaciones.

Robot de copia de transacciones de contratos de moneda digital simple

Vamos a intentar cerrar las dos posiciones de contrato que acabamos de abrir. Las posiciones después del cierre son las que se muestran en la figura:

Robot de copia de transacciones de contratos de moneda digital simple

Siga la operación en tiempo real y cierre 2 contratos.

Robot de copia de transacciones de contratos de moneda digital simple

Esta estrategia está diseñada de una manera sencilla y fácil de entender, sin ninguna optimización. La mejora aún necesita abordar detalles como la detección de activos al seguir órdenes. En aras de la simplicidad en el diseño, se utilizan órdenes de mercado para seguir órdenes. . La estrategia solo proporciona ideas de aprendizaje y el trading real se optimizará según las necesidades.

Dirección de estrategia: https://www.fmz.com/strategy/270012

Bienvenido a dejar un mensaje.