En la carga de los recursos... Cargando...

Explicación detallada de la actualización de la API de FMZ Quant: Mejorar la experiencia de diseño de estrategias

El autor:FMZ~Lydia, Creado: 2024-07-05 09:44:08, Actualizado: 2024-07-25 15:15:03

[TOC] ¿Qué quieres decir?

img

Explicación detallada de la actualización de la API de FMZ Quant: Mejorar la experiencia de diseño de estrategias

Prefacio

Después de 9 años de iteración técnica, la Plataforma de Comercio Cuantitativo FMZ ha sido reconstruida muchas veces, aunque como usuarios tal vez no lo hayamos notado.

Con el fin de hacer que el diseño de estrategias sea más conveniente, la lógica de negociación más clara y más fácil para los principiantes, la plataforma ha actualizado la interfaz API utilizada por la estrategia. Los dockers que utilizan la última versión pueden habilitar estas nuevas características. La plataforma sigue siendo compatible con las viejas llamadas de interfaz en la mayor medida.

Guía de sintaxis:https://www.fmz.com/syntax-guideGuía del usuario:https://www.fmz.com/user-guide

Así que echemos un vistazo rápido a las interfaces que se han actualizado y qué cambios son necesarios para utilizar las viejas estrategias para hacerlos compatibles con la API actual.

1. nueva interfaz API

Añadido el intercambio.Función GetTickers

Para diseñar estrategias de múltiples productos y estrategias completas de monitoreo del mercado, la interfaz de mercado agregada es esencial.

Si el intercambio no dispone de esta interfaz (intercambios individuales), al llamarexchange.GetTickers(), se muestra un mensaje de error: No compatible.

Esta función no tiene parámetros y devolverá los datos de mercado en tiempo real de todas las variedades en la interfaz de mercado agregada de la bolsa.

exchange.GetTickers()Función es la versión de solicitud completa de laexchange.GetTicker()función (mirar cuidadosamente, la diferencia entre estos dos nombres de función es sólo el singular y plural).

Utilizamos el entorno de simulación de puntos OKX para las pruebas:

function main() {
    exchange.IO("simulate", true)

    var tickers = exchange.GetTickers()
    if (!tickers) {
        throw "tickers error"
    }

    var tbl = {type: "table", title: "test tickers", cols: ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], rows: []}
    for (var i in tickers) {
        var ticker = tickers[i]
        tbl.rows.push([ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume])
    }

    LogStatus("`" + JSON.stringify(tbl) +  "`")
    return tickers.length
}

img

Añadido el intercambio.CreateOrder función

El nuevoexchange.CreateOrder()la función es el foco de esta actualización.exchange.CreateOrder()El objetivo de la función es especificar el tipo y la dirección de la orden directamente en los parámetros de la función, de esta manera, ya no depende del par de operaciones actual, el código del contrato, la dirección de negociación y otros ajustes del sistema.

En los escenarios de colocación de órdenes de negociación de múltiples especies y en los escenarios concurrentes, la complejidad del diseño se reduce en gran medida.exchange.CreateOrder()La función essymbol, side, price, amount.

Prueba utilizando el entorno de simulación de futuros OKX:

function main() {
    exchange.IO("simulate", true)

    var id1 = exchange.CreateOrder("ETH_USDT.swap", "buy", 3300, 1)
    var id2 = exchange.CreateOrder("BTC_USDC.swap", "closebuy", 70000, 1)
    var id3 = exchange.CreateOrder("LTC_USDT.swap", "sell", 110, 1)

    Log("id1:", id1, ", id2:", id2, ", id3:", id3)
}

img

De esta manera, sólo tresexchange.CreateOrder()Las llamadas de función se utilizaron para colocar tres órdenes de futuros de diferentes variedades y direcciones.

Añadido el intercambio.GetHistoryOrders función

El nuevoexchange.GetHistoryOrders()La función también requiere el soporte de la interfaz de intercambio.

Para consultar pedidos históricos, las interfaces implementadas por varios intercambios varían mucho:

  • Algunos soportan consultas paginadas, mientras que otros no;
  • Algunos intercambios tienen un período de ventana de consulta, es decir, no se pueden consultar órdenes de más de N días;
  • La mayoría de los intercambios admiten consultas en un momento especificado, pero algunos no lo hacen; Dichas interfaces están encapsuladas con el mayor grado de compatibilidad y, en el uso real, debe prestarse atención a si cumplen los requisitos y las expectativas de la estrategia.

La descripción detallada de la función no se repite aquí, puede consultar el manual de sintaxis en la documentación de la API:

https://www.fmz.com/syntax-guide#fun_exchange.gethistoryorders

Probado usando el entorno de negociación al contado de Binance:

function main() {
    var orders = exchange.GetHistoryOrders("ETH_USDT")

    // Write to chart
    var tbl = {type: "table", title: "test GetHistoryOrders", cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}
    for (var order of orders) {
        tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
    }
    
    LogStatus("orders.length:", orders.length, "\n", "`" + JSON.stringify(tbl) +  "`")
}

img

Añadido el intercambio.GetPositions función

La versión anterior de la función de adquisición de datos de posición esexchange.GetPosition()Esta actualización añade una nueva función de adquisición de posición para que coincida mejor con la semántica de nombres de funciones:exchange.GetPositions(). Al mismo tiempo, sigue siendo compatible/actualizado con la función GetPosition.

Elexchange.GetPositions()La función tiene tres formas de llamada:

  • El cambio.GetPositions ((() Cuando no se transmitan parámetros, se solicitan datos de posición basados en la configuración actual del par de negociación/código del contrato.
  • En el caso de las operaciones de intercambio, las posiciones de intercambio deben ser las siguientes: Cuando se especifique información específica sobre el producto (el formato de ETH_USDT.swap está definido por la plataforma FMZ), se solicitarán los datos de posición del producto específico.
  • En cambio.GetPositions ((("") Solicitar a la interfaz de posición de intercambio para obtener toda la dimensión actual de los datos de posición (dividida según la dimensión del producto de la interfaz de intercambio) Prueba utilizando el entorno de simulación de futuros OKX:
function main() {
    exchange.IO("simulate", true)

    exchange.SetCurrency("BTC_USDT")
    exchange.SetContractType("swap")

    var p1 = exchange.GetPositions()
    var p2 = exchange.GetPositions("")

    var tbls = []
    for (var positions of [p1, p2]) {
        var tbl = {type: "table", title: "test GetPosition/GetPositions", cols: ["Symbol", "Amount", "Price", "FrozenAmount", "Type", "Profit", "Margin", "ContractType", "MarginLevel"], rows: []}
        for (var p of positions) {
            tbl.rows.push([p.Symbol, p.Amount, p.Price, p.FrozenAmount, p.Type, p.Profit, p.Margin, p.ContractType, p.MarginLevel])
        } 
        tbls.push(tbl)
    }

    LogStatus("`" + JSON.stringify(tbls) +  "`")
}

img

Cuando el parámetro pasó a laexchange.GetPositions()la función esETH_USDT.swap, se pueden obtener los datos de posición de los contratos perpetuos basados en U de ETH.

img

Cuando el parámetro pasó a laexchange.GetPositions()La función es una cadena vacía , los datos de posición de todos los contratos basados en U. ¿No es conveniente?

2. Actualización de la interfaz de API

Actualizar el intercambio.Función GetTicker

La actualización principal de la función de mercadoexchange.GetTicker()El objetivo de esta función es agregar el parámetro de símbolo. Esto permite a la función solicitar datos de mercado directamente de acuerdo con la información del producto especificada por el parámetro sin el par de negociación actual y el código del contrato. Simplifica el proceso de escritura de código. Al mismo tiempo, sigue siendo compatible con el método de llamada sin pasar parámetros, y es compatible con la antigua estrategia de plataforma en la mayor medida.

El parámetrosymbolEl importe de las pérdidas de valor de las pérdidas de valor derivadas de las pérdidas de valor de las pérdidas de valor derivadas de las pérdidas de valor de las pérdidas de valor derivadas de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valor de las pérdidas de valorexchange:

  • Objeto de intercambio al contado El formato es el siguiente:AAA_BBB, AAA representa baseCurrency, es decir, moneda de negociación, y BBB representa quoteCurrency, es decir, moneda de fijación de precios. Por ejemplo: el par de operaciones al contado BTC_USDT.
  • Objeto del intercambio de futuros El formato es el siguiente:AAA_BBB.XXX, AAA representa baseCurrency, es decir, moneda de negociación, BBB representa quoteCurrency, es decir, moneda de fijación de precios, y XXX representa el código del contrato, como el cambio de contrato perpetuo. Por ejemplo: BTC_USDT.swap, contrato perpetuo basado en U de BTC. Probado usando el entorno en vivo de Binance Futures:
var symbols = ["BTC_USDT.swap", "BTC_USDT.quarter", "BTC_USD.swap", "BTC_USD.next_quarter", "ETH_USDT.swap"]

function main() {
    exchange.SetCurrency("ETH_USD")
    exchange.SetContractType("swap")

    var arr = []
    var t = exchange.GetTicker()
    arr.push(t)

    for (var symbol of symbols) {
        var ticker = exchange.GetTicker(symbol)
        arr.push(ticker)
    }

    var tbl = {type: "table", title: "test GetTicker", cols: ["Symbol", "High", "Open", "Low", "Last", "Buy", "Sell", "Time", "Volume"], rows: []}
    for (var ticker of arr) {
        tbl.rows.push([ticker.Symbol, ticker.High, ticker.Open, ticker.Low, ticker.Last, ticker.Buy, ticker.Sell, ticker.Time, ticker.Volume])
    }

    LogStatus("`" + JSON.stringify(tbl) +  "`")
    return arr
}

img

La solicitud de un lote de datos de mercado para un símbolo especificado se ha vuelto mucho más simple.

Actualizar la función de intercambio.GetDepth

Similar a la función GetTicker, elexchange.GetDepth()Esto nos permite especificar directamente el símbolo al solicitar datos de profundidad.

Probado usando el entorno en vivo de Binance Futures:

function main() {
    exchange.SetCurrency("LTC_USD")
    exchange.SetContractType("swap")

    Log(exchange.GetDepth())
    Log(exchange.GetDepth("ETH_USDT.quarter"))
    Log(exchange.GetDepth("BTC_USD.swap"))
}

img

Actualizar la función Exchange.GetTrades

Similar a la función GetTicker, elexchange.GetTrades()Esto nos permite especificar el símbolo directamente al solicitar datos de transacciones de mercado.

Probado usando el entorno en vivo de Binance Futures:

function main() {
    var arr = []
    var arrR = []
    var symbols = ["LTC_USDT.swap", "ETH_USDT.quarter", "BTC_USD.swap"]    

    for (var symbol of symbols) {
        var r = exchange.Go("GetTrades", symbol)
        arrR.push(r)
    }

    for (var r of arrR) {
        arr.push(r.wait())
    }
    
    var tbls = []
    for (var i = 0; i < arr.length; i++) {
        var trades = arr[i]
        var symbol = symbols[i]

        var tbl = {type: "table", title: symbol, cols: ["Time", "Amount", "Price", "Type", "Id"], rows: []}
        for (var trade of trades) {
            tbl.rows.push([trade.Time, trade.Amount, trade.Price, trade.Type, trade.Id])
        }

        tbls.push(tbl)
    }

    LogStatus("`" + JSON.stringify(tbls) +  "`")
}

img

Esta actualización también es compatible con el parámetro de símbolo especificado por elexchange.Go()Función cuando se llama simultáneamente a la interfaz API de la plataforma.

Actualizar la función de intercambio.GetRecords

La función GetRecords se ha ajustado en gran medida esta vez. Además de soportar el parámetro símbolo para especificar directamente la información de tipo de los datos de línea K solicitados, se conserva el parámetro de período original para especificar el período de línea K, y se agrega un parámetro límite para especificar la longitud de línea K esperada al solicitar. Al mismo tiempo, también es compatible con la versión anterior de la función GetRecords que solo pasa en el parámetro de período.

El método de llamada deexchange.GetRecords()su función es:

  • ¿ Qué pasa con los registros? Si no se especifican parámetros, se solicitan los datos de línea K del producto correspondientes al par de operaciones/código del contrato actual.
  • En cambio.GetRecords ((60 * 15) Cuando solo se especifique el parámetro de período de línea K, se solicitarán los datos de línea K del producto correspondientes al par de negociación/código de contrato actual.
  • En el momento en que el cambio.GetRecords ((BTC_USDT.swap) Cuando solo se especifica la información del producto, se solicitan los datos de la línea K del producto especificado.
  • En el caso de las transacciones de intercambio.GetRecords ((BTC_USDT.swap, 60 * 60) Especificar la información sobre el producto y el período específico de línea K para solicitar datos de línea K.
  • exchange.GetRecords ((BTC_USDT.swap, 60, 1000) Especificar la información sobre el producto, especificar el período específico de línea K y especificar la longitud de línea K esperada para solicitar datos de línea K. Tenga en cuenta que cuando el parámetro límite excede la longitud máxima de una sola solicitud del intercambio, se generará una solicitud de búsqueda (es decir, múltiples llamadas a la interfaz de línea K del intercambio).

Probado usando el entorno en vivo de Binance Futures:

function main() {
    exchange.SetCurrency("ETH_USDT")
    exchange.SetContractType("swap")
    
    var r1 = exchange.GetRecords()
    var r2 = exchange.GetRecords(60 * 60)
    var r3 = exchange.GetRecords("BTC_USDT.swap")
    var r4 = exchange.GetRecords("BTC_USDT.swap", 60)
    var r5 = exchange.GetRecords("LTC_USDT.swap", 60, 3000)

    Log("r1 time difference between adjacent bars:", r1[1].Time - r1[0].Time, "Milliseconds, Bar length:", r1.length)
    Log("r2 time difference between adjacent bars:", r2[1].Time - r2[0].Time, "Milliseconds, Bar length:", r2.length)
    Log("r3 time difference between adjacent bars:", r3[1].Time - r3[0].Time, "Milliseconds, Bar length:", r3.length)
    Log("r4 time difference between adjacent bars:", r4[1].Time - r4[0].Time, "Milliseconds, Bar length:", r4.length)
    Log("r5 time difference between adjacent bars:", r5[1].Time - r5[0].Time, "Milliseconds, Bar length:", r5.length)
}

img

Actualizar la función de intercambio.GetOrders

La función GetOrders también agregasymbolParámetros, que pueden especificar el tipo de órdenes pendientes actuales (ordenes pendientes) directamente a consultar; también admite la consulta de todas las órdenes pendientes (independientemente del tipo); y es compatible con el método de llamada original.

Elexchange.GetOrders()La función puede ser llamada de las siguientes maneras:

  • El cambio.GetOrders() Encuesta de todas las órdenes no completadas para el par de operaciones/código del contrato actual.
  • En el caso de las operaciones de intercambio.GetOrders ((BTC_USDT.swap) Consultar todas las órdenes pendientes de contratos perpetuos con margen USDT en BTC.
  • En cambio.GetOrders (("") Consulta todas las órdenes pendientes en la dimensión actual del intercambio (dividido según la dimensión de la interfaz API del intercambio).

Prueba utilizando el entorno de simulación de futuros OKX:

function main() {
    exchange.IO("simulate", true)

    exchange.SetCurrency("BTC_USDT")
    exchange.SetContractType("swap")

    // Write to chart
    var tbls = []
    for (var symbol of ["null", "ETH_USDT.swap", ""]) {
        var tbl = {type: "table", title: symbol, cols: ["Symbol", "Id", "Price", "Amount", "DealAmount", "AvgPrice", "Status", "Type", "Offset", "ContractType"], rows: []}

        var orders = null
        if (symbol == "null") {
            orders = exchange.GetOrders()
        } else {
            orders = exchange.GetOrders(symbol)
        }

        for (var order of orders) {
            tbl.rows.push([order.Symbol, order.Id, order.Price, order.Amount, order.DealAmount, order.AvgPrice, order.Status, order.Type, order.Offset, order.ContractType])
        }

        tbls.push(tbl)
    }
    
    LogStatus("`" + JSON.stringify(tbls) +  "`")
}

img

Cuando no se pasan parámetros, la solicitud predeterminada es para todas las órdenes pendientes no completadas del par de operaciones BTC_USDT actual y el contrato perpetuo de swap.

img

Cuando elETH_USDT.swapSi se especifica el parámetro, se solicitan todas las órdenes pendientes pendientes del contrato perpetuo del par de operaciones ETH_USDT.

img

Cuando una cadena vacía""Se solicitan todas las órdenes no completadas de todos los contratos con margen USDT.

Actualizar la función exchange.GetPosition

Todavía es compatible con la antigua función de adquisición de posición de nombre, y también agrega el parámetro de símbolo, que puede especificar el tipo de información de los datos de posición específicos solicitados. El uso de esta función es exactamente el mismo queexchange.GetPositions().

Actualizaciónexchange.IOFunción

Paraexchange.IO("api", ...)llamadas de funciones, todos los objetos de intercambio han sido actualizados para soportar el paso directo de direcciones de solicitud completas. Por ejemplo, si quieres llamar a la interfaz OKX:

// GEThttps://www.okx.com/api/v5/cuenta/máximo ccy de retiro: BTC

Apoya la escritura directa a la dirección basehttps://www.okx.comSin tener que cambiar la dirección de base primero y luego llamar a la función IO.

Prueba utilizando el entorno de simulación de futuros OKX:

function main() {
    exchange.IO("simulate", true)

    return exchange.IO("api", "GET", "https://www.okx.com/api/v5/account/max-withdrawal", "ccy=BTC")
}

img

3. Impacto de la interfaz de API

Afecta la función de intercambio.GetOrder

Esta actualización afecta principalmente el parámetroidde lasexchange.GetOrder(id)El parámetro id se cambia del id original de la orden de intercambio a un formato de cadena que contiene el producto de negociación. Todos los ID de pedido encapsulados en la plataforma FMZ están en este formato.

Por ejemplo:

  • El ID de orden original del intercambio definido en la orden de intercambio es:123456Antes de esta actualización, si usted quiere llamar a la función GetOrder, el orden Id pasado en es123456.
  • El código del producto nombrado por la bolsa definida en la orden de cambio:BTC-USDT¿ Qué pasa? Tenga en cuenta que esto se refiere al código de producto de negociación nombrado por la bolsa, no al par de negociación definido por la plataforma FMZ.

Después de esta actualización, el formato del parámetro id que se debe pasar en elexchange.GetOrder(id)la función se ajusta a:BTC-USDT,123456.

Primero, permítanme explicar por qué se hace este diseño: Debido a que la función CreateOrder se ha actualizado para especificar el tipo de orden directamente (el tipo de orden puesta puede ser diferente del par de operaciones y el código de contrato actualmente establecido). Si el ID de orden devuelto no contiene la información de tipo, entonces este ID de orden será inutilizable. Debido a que al verificar la orden, no sabemos para qué tipo (contrato) es la orden. La mayoría de los intercambios requieren la especificación de parámetros que describen el código de tipo al verificar y cancelar órdenes.

Cómo ser compatible con este impacto: Si utiliza elexchange.IOLa función para llamar a la interfaz de orden de intercambio directamente para realizar un pedido, el valor devuelto generalmente contiene el símbolo original del intercambio (código de producto) y el ID de pedido original. Luego, concatenando los dos con comas en inglés será el ID de pedido que cumple con la definición de la plataforma FMZ. Del mismo modo, si utiliza la interfaz de pedido encapsulada de la plataforma FMZ para realizar un pedido, ya que el comienzo del ID de pedido es el código del producto comercial, si necesita usar el ID de pedido original, simplemente elimine el código del producto y la coma.

Afecta la función de intercambio.

El impacto de esta actualización en elexchange.CancelOrder()la función es la misma que laexchange.GetOrder() function.

Afecta la función de intercambio.compra

El impacto de esta actualización en elexchange.Buy()la función es la misma que laexchange.GetOrder()la función. El ID de pedido devuelto por elexchange.Buy()la función es una nueva estructura, por ejemplo, el ID devuelto al colocar una orden de futuros en la bolsa OKX es:LTC-USDT-SWAP,1578360858053058560.

Afecta el intercambio. Función de venta

El impacto de esta actualización en elexchange.Sell()la función es la misma que laexchange.GetOrder()la función. El ID de pedido devuelto por elexchange.Sell()la función es una nueva estructura, por ejemplo, el ID devuelto al colocar una orden de futuros en la bolsa OKX es:ETH-USDT-SWAP,1578360832820125696.

4. Adaptación estructural

Estructura de los tickers

Esta actualización agrega un campo de símbolo a la estructura de ticker, que registra la información de mercado de la estructura de ticker actual. El formato de este campo es exactamente el mismo que el formato del parámetro de símbolo delexchange.GetTicker() function.

Estructura del orden

Esta actualización agrega un campo de símbolo a la estructura de orden, y el formato de este campo es exactamente el mismo que el formato de parámetro de símbolo delexchange.GetTicker()la función. Esta actualización también modifica el campo ID de la estructura del pedido, registrando la información del producto y la información del pedido original en el nuevo formato de ID del pedido.exchange.GetOrder()La Comisión no ha podido dar una respuesta clara a esta pregunta.

Estructura de la posición

Esta actualización agrega un campo de símbolo a la estructura de posición.exchange.GetTicker() function.

5. Sistema de pruebas de retroceso

Para satisfacer las necesidades de los usuarios, esta actualización primero será compatible con el comercio en vivo, y el sistema de backtesting se adaptará dentro de una semana.

Actualizaciones adicionales

1. Nuevos campos en la estructura de las cuentas

Los campos de laAccountestructura devuelta por elGetAccountLa función de los miembros del objeto de intercambio de futuros se han ampliado.

  • Capital propio El valor de la moneda de los activos de margen actual es el valor total de la moneda de los activos de margen.

  • La UPnL La mayoría de las bolsas de futuros apoyan este campo, excepto algunas que no lo hacen.

La función SetMarginLevel se ha actualizado para soportar el parámetro de símbolo

Se ha actualizado la función miembro SetMarginLevel del objeto de intercambio de futuros y se ha añadido el símbolo de parámetro.

Ejemplo de ensayo:

function main() {
    exchange.SetCurrency("ETH_USDT")
    exchange.SetContractType("swap")
    
    // The current trading pair is ETH_USDT, the contract code is swap, and the leverage value is set to 10
    exchange.SetMarginLevel(10)
    
    // Directly specify the trading pair BTC_USDT, contract code swap, and set the leverage value to 20
    exchange.SetMarginLevel("BTC_USDT.swap", 20)
}

Más.