Los contratos de monedas digitales son fáciles de seguir por los robots

El autor:Un sueño pequeño., Creado: 2021-04-07 21:30:05, Actualizado: 2023-09-24 19:35:33

img

Los contratos de monedas digitales son fáciles de seguir por los robots

En el artículo anterior, implementamos un simple robot de facturación de contado, y hoy implementamos un robot de facturación sencillo en versión de contrato.

La idea del diseño

Las versiones de contratación son muy diferentes de las versiones de compra y venta. Las versiones de compra y venta se realizan principalmente mediante el monitoreo de los cambios en los activos de las cuentas. Las versiones de futuros requieren monitorear los cambios en las posiciones de las cuentas. Por lo tanto, la versión de futuros es un poco más complicada, ya que los futuros tienen múltiples tenencias, tenencias en blanco y diferentes contratos. El movimiento de la tenencia para activar la acción de seguimiento individual. Cuando se diseñó inicialmente para tratar múltiples cabezas, cabezas vacías juntas, se descubrió que este tratamiento se volvería complicado. Después de analizar el problema, se decidió para tratar múltiples cabezas, cabezas vacías separadas.

Implementación de la estrategia

Los parámetros de la estrategia:

img

Apoyo para retrospección, se puede usar directamente la configuración predeterminada para retrospección de observación.

El 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
    }
}

Las pruebas

Dado que OKEX actualizó la interfaz V5 para permitir el uso de discos de simulación OKEX, me fue muy fácil realizar pruebas con dos discos de simulación OKEX API KEY.

El primer objeto de intercambio que se agrega es el intercambio de referencia, y todos los intercambios siguen esta cuenta de intercambio. En la página de OKEX Analogue, se puede mover manualmente 3 contratos de localización de moneda trimestral de ETH en la cuenta de referencia de la bolsa.

img

Como se puede ver, el disco real detecta los cambios en la tenencia de la cuenta de la bolsa de referencia y luego sigue la operación.

img

En el caso de las posiciones que se han abierto recientemente, las posiciones que se mantienen después de la liquidación son las siguientes:

img

El disco real sigue la operación y elimina dos contratos.

img

Esta estrategia está diseñada de una manera simple y fácil de entender, sin hacer optimización, la parte perfeccionada también requiere tratar detalles como la detección de activos en el momento de la facturación. Para simplificar el diseño, la facturación se utiliza la lista de precios del mercado.

La dirección de la estrategia:https://www.fmz.com/strategy/270012

Bienvenido a sus comentarios.


Relacionados

Más.

Pw1013¿Qué pueden hacer dos bolsas diferentes?

el mismo número de unidades.¿Cuándo los inventores podrán ganar contratos de futuros con monedas en pareja?

- ¿ Qué?Espero que haya una versión de Bitcoin usdt.

el 99¿Quiere una versión de contrato permanente de Bitcoin usdt, API del ejecutor?????

Zhousone y otrosEn la actualidad, la mayoría de los usuarios de Bitcoin están interesados en el uso de los tokens de USDT.

¿Qué quieres?Muchas gracias por compartir, vale la pena aprender.

Un sueño pequeño.Como las especificaciones de los contratos pueden ser diferentes en los intercambios, es posible que el código de la orden sea adaptado en función de las circunstancias.

Pw1013El intercambio que uso es bibox, con un 80% de retorno de comisiones, y FMZ está perfectamente respaldado.

Pw1013¿Puedes decirme cuál es el cambio más específico que necesito hacer en mi bibox de futuros que uso ahora, si quiero conectar con otra persona en la bolsa de valores okx?

Un sueño pequeño.Si es posible, sólo hay que cambiar el código.

Un sueño pequeño.Para evaluar este intercambio, no se ha comunicado con nosotros.