[TOC] ¿Qué quieres decir?
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.
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
}
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)
}
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.
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:
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) + "`")
}
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:
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) + "`")
}
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
Cuando el parámetro pasó a laexchange.GetPositions()
La función es una cadena vacía
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ámetrosymbol
El 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
:
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.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 BTCvar 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
}
La solicitud de un lote de datos de mercado para un símbolo especificado se ha vuelto mucho más simple.
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"))
}
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) + "`")
}
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.
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:
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)
}
La función GetOrders también agregasymbol
Pará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:
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) + "`")
}
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.
Cuando elETH_USDT.swap
Si se especifica el parámetro, se solicitan todas las órdenes pendientes pendientes del contrato perpetuo del par de operaciones ETH_USDT.
Cuando una cadena vacía""
Se solicitan todas las órdenes no completadas de todos los contratos con margen USDT.
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()
.
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.com
Sin 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")
}
Esta actualización afecta principalmente el parámetroid
de 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:
123456
Antes de esta actualización, si usted quiere llamar a la función GetOrder, el orden Id pasado en es123456
.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.
El impacto de esta actualización en elexchange.CancelOrder()
la función es la misma que laexchange.GetOrder()
function.
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
.
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
.
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.
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.
Esta actualización agrega un campo de símbolo a la estructura de posición.exchange.GetTicker()
function.
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.
Los campos de laAccount
estructura devuelta por elGetAccount
La 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.
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)
}