En el artículo anterior, hablamos sobre los scripts de trading programático. De hecho, una estrategia comercial es un programa de script comercial. El artículo habla principalmente sobre la necesidad de un soporte de hardware para el programa de script comercial (donde se ejecuta el programa), qué lenguaje de programación de computadora se puede usar para escribir este programa de script comercial (lista El uso de la plataforma de negociación cuantitativa Inventor Existen tres lenguajes de programación. Por supuesto, puede utilizar cualquier lenguaje de programación para implementar estrategias de negociación programática. En este artículo, continuamos discutiendo el análisis cuantitativo del círculo de criptomonedas y comprendemos el conocimiento del análisis cuantitativo del círculo de criptomonedas.
Tipos de estrategias comerciales Los principiantes que se inician en el trading programático y el trading cuantitativo pueden confundirse con varios términos como estrategias de tendencia, estrategias de arbitraje, estrategias de alta frecuencia, estrategias de cuadrícula, etc. De hecho, los tipos de estrategias comunes del trading programático y el trading cuantitativo pueden ser simplemente Se describe de la siguiente manera: Varias direcciones.
Lo anterior se divide desde la perspectiva de las estrategias comerciales. Desde la perspectiva del diseño de estrategias en la plataforma de comercio cuantitativo Inventor, las estrategias también se pueden dividir en:
Estrategia de producto único Es decir, esta estrategia solo opera un producto, como el trading de BTC o el trading de ETH.
Estrategia multiproducto En pocas palabras, se trata de operar múltiples variedades según una lógica estratégica.
Estrategia multicuenta En pocas palabras, se trata de configurar múltiples objetos de intercambio en un disco real (el concepto de intercambio se introdujo en el artículo anterior y el objeto de intercambio con API KEY configurado representa una cuenta de intercambio). Por ejemplo, algunas estrategias de copy trading implican que varias cuentas sigan la operación (puede ser la misma bolsa o diferentes bolsas). En resumen, se gestionan varios objetos de bolsa (cuentas) en una cuenta real.
Estrategias lógicas múltiples Por ejemplo, en un mercado real, la estrategia MACD, la estrategia de promedio móvil, la estrategia de cuadrícula, etc. se diseñan al mismo tiempo (por supuesto, operan en diferentes objetos de cambio). Si opera el mismo objeto de cambio, debe ver si Las estrategias específicas tienen conflictos lógicos)
API de intercambio ¿Cómo funcionan los scripts comerciales programados en las cuentas de intercambio? La respuesta está a través de la interfaz API abierta por el exchange. Entonces, ¿qué tipos de interfaces están abiertas a los intercambios? En el artículo anterior, hablamos sobre la sección “Intercambio”, donde decíamos que los intercambios generalmente tienen interfaces REST y Websocket. Aquí agregamos algunos conceptos del nivel de programa estratégico. Las interfaces de intercambio se dividen en dos tipos: verificadas y no verificadas, dependiendo de si están verificadas o no (tanto REST como Websocket).
Interfaces que no requieren autenticación
Generalmente llamada “interfaz pública”, este tipo de interfaz no requiere verificación.API KEY
(Si olvidas qué es API KEY, puedes consultar el artículo anterior). Este tipo de interfaz es generalmente una interfaz de mercado, como consultar información profunda del mercado, consultar datos de la línea K, consultar tasas de financiación, consultar información relacionada con productos de transacción, consultar marcas de tiempo del servidor de intercambio, etc.
En pocas palabras, una interfaz que no tiene nada que ver con su cuenta puede determinarse aproximadamente como una interfaz pública (no se requiere verificación).
En la plataforma de comercio cuantitativo de Inventor, al llamar a una función API no verificada (que encapsula la interfaz no verificada del intercambio, la interfaz pública), incluso si la CLAVE API está configurada incorrectamente, los datos devueltos por la interfaz se pueden obtener normalmente. (Porque no está verificado)
Interfaces que necesitan ser verificadas En pocas palabras, es una interfaz que necesita ser verificada (verificada mediante una CLAVE API). Este tipo de interfaz se denomina interfaz privada. Este tipo de interfaz suele estar relacionada con algunas operaciones o información de su cuenta, como consultar activos de la cuenta, consultar posiciones de la cuenta, consultar órdenes pendientes, consultar transferencias, transferir monedas, ajustar apalancamiento, configurar modos de posición, etc. Estas operaciones deben ser verificadas. En la Plataforma de Comercio Cuantitativo de Inventor, al llamar a una función API que requiere verificación (la interfaz que el intercambio encapsulado necesita verificar, la interfaz privada), si la CLAVE API está configurada incorrectamente, se informará un error al llamar a la interfaz y un Se devolverá un valor nulo.
Entonces, ¿cómo se utilizan estas interfaces en la plataforma de comercio cuantitativo de Inventor?
La plataforma de negociación cuantitativa Inventor encapsula el comportamiento del intercambio y define interfaces consistentes (como la interfaz de línea K, la interfaz de mercado profundo, la interfaz de consulta de activos actuales, la interfaz de órdenes, la interfaz de retiro de órdenes, etc.). Estas interfaces se denominan Funciones API de la La plataforma de comercio cuantitativo de Inventor se puede ver consultando la documentación de la API (https://www.fmz.com/api).
Entonces, ¿cómo utilizar algunas interfaces de intercambio con comportamientos y definiciones inconsistentes en la plataforma de comercio cuantitativo de Inventor?
Estas interfaces de intercambio incluyen: transferencia de activos, confianza condicional, colocación de órdenes por lotes, cancelación de órdenes por lotes, modificación de órdenes, etc. Algunas bolsas tienen estas interfaces, mientras que otras no. Sus funciones y detalles de uso pueden variar considerablemente. Por lo tanto, estas interfaces están disponibles en la plataforma de negociación cuantitativa de Inventor.exchange.IO
Esta función se utiliza para acceder (para obtener más detalles, consulte el documento API de la plataforma de comercio cuantitativo de Inventor: https://www.fmz.com/api#exchange.io…). También hay algunos ejemplos prácticos de estrategias de IO en la plataforma de comercio cuantitativo Inventor Strategy Square.
¿Todas las funciones API en la documentación de la API de Inventor Quantitative Trading Platform generan solicitudes de red?
Digamos primero que la interfaz API de Exchange tiene un límite de frecuencia de acceso (por ejemplo, 5 veces por segundo). El acceso no puede ser demasiado frecuente, de lo contrario se informará un error http 429 y se denegará el acceso (la mayoría de los exchanges informan 429). . La misma limitación se aplica también a las llamadas a la interfaz de intercambio empaquetada en la Plataforma de negociación cuantitativa de Inventor. No existe tal limitación para las funciones API en la Plataforma de negociación cuantitativa de Inventor que no generan solicitudes de red. No todas las funciones API de la Plataforma de Comercio Cuantitativo de Inventor generarán solicitudes de red. Algunas de las funciones API de Inventor solo modifican algunas configuraciones locales, como la configuración del par de negociación actual, la configuración del código de contrato, la función de cálculo del indicador, la obtención del nombre del objeto de intercambio, etc. Básicamente, se puede juzgar si se produce una solicitud de red a partir del propósito de la función. Siempre que sea para obtener datos de intercambio, operar en cuentas de intercambio, etc., se generará una solicitud de red. Debe prestar atención a la llamada frecuencia de estas interfaces.
Hablemos de algunos problemas y experiencias comunes al utilizar funciones API en la plataforma de comercio cuantitativo de Inventor.
Al escribir estrategias, necesitamos juzgar y verificar los datos que devuelve la interfaz. Por ejemplo, esta línea de código se utiliza para obtener información del mercado en la plataforma de negociación cuantitativa Inventor (lo mismo ocurre cuando se escribe un programa para acceder directamente a la bolsa). interfaz):var ticker = exchange.GetTicker()
Si necesitamos usar estoticker
Variable (ver la estructura devuelta por la función GetTicker)Last
(precio más reciente) datos que necesitamos utilizarvar newPrice = ticker.Last
Obtenga los datos de esta manera (¿qué es newPrice? new: latest, Price: price, ¡sí! ¡Póngalos juntos!) En este momento, siGetTicker()
Está bien si la función devuelve datos normales, pero si la solicitud se agota, ocurren errores de red, el intercambio desconecta el cable de red, el cable se corta, un niño travieso tira del interruptor de encendido, etc., causaráGetTicker()
Función devuelvenull
. En este momentoticker
El valor de esnull
Lo visitaré nuevamente.Last
Se producirá una excepción de programa que provocará que el programa de políticas se detenga.
Parece que la falla de la llamada de interfaz (la llamada GetTicker falló y devolvió nulo) no es la causa directa de la detención del trading real de la estrategia (la causa directa es acceder a unanull
Las propiedades variables, las fallas en las llamadas de interfaz y los errores no provocarán que se detenga el comercio real (énfasis añadido).
¿Qué podemos hacer entonces para evitar una suspensión anormal del comercio real?
La respuesta es realizar un procesamiento de tolerancia a fallas en los datos devueltos por la interfaz. Es muy simple determinar si los datos devueltos sonnull
(Se utiliza JavaScript como ejemplo, otros lenguajes son básicamente iguales)
Escribe un pequeño fragmento de código para explicarlo (esto es solo una explicación, ¡no funcionará si lo ejecutas directamente!)
var ticker = exchange.GetTicker()
if (ticker) {
var newPrice = ticker.Last
Log("打印最新价格:", newPrice)
} else {
// 数据为null,不做操作就不会出问题
}
No sóloGetTicker
La interfaz debe ser tolerante a fallas. Todas las interfaces con solicitudes de red deben ser tolerantes a fallas para los valores de retorno (si se utiliza el valor de retorno de la función).
Hay muchas formas de tolerar los fallos, puedes utilizar_C()
Función (consulte la documentación de la API de FMZ), escriba su propia función tolerante a fallas y diseñe su propio mecanismo y lógica tolerantes a fallas.
acerca de_C()
Al utilizar funciones, es probable que muchos estudiantes nuevos las utilicen incorrectamente._C()
Los parámetros de función son referencias de función, no llamadas de función. En términos simples:
_C(funcName, param1, param2)
, la llamada es correcta, funcName no tiene paréntesis, param1 y param2 son los parámetros que se deben pasar a la función funcName.
_C(funcName(param1, param2))
, error de llamada, generalmente los novatos que no leen atentamente la documentación de la API de FMZ lo escribirán así.
LTC_USDT
function main() {
exchange.IO("simulate", true) // 切换为OKEX交易所的模拟盘
exchange.Buy(-1, 1) // 价格是-1,表示下的订单为市价单,数量为1表示下单量是1USDT
}
Dado que los exchanges generalmente tienen límites en el monto de los pedidos, no se enviarán pedidos inferiores al límite (por ejemplo, Binance spot requiere que cada pedido sea mayor a 5 USDT para enviarse con éxito). Entonces, realizar un pedido como éste dará como resultado un error:
错误 Buy(-1, 1): map[code:1 data:[map[clOrdId: ordId: sCode:51020 sMsg:Order amount should be greater than the min available amount. tag:]] msg:]
Dado que la función de orden solo tieneBuy
,Sell
. Sin embargo, los futuros (por supuesto, no hay problema con el spot, el spot solo tiene compra y venta) tienen direcciones como abrir largo, cerrar largo, abrir corto y cerrar corto. Obviamente, la compra/venta no puede representar operaciones en tantas direcciones. En este momento, es necesario introducir la configuración de la dirección de negociación de futuros. Esta funciónexchange.SetDirection()
。
En FMZ
exchange.SetDirection("buy")
(establezca la dirección primero) yexchange.Buy
Cuando se usan juntos, significa que la orden realizada es una orden para abrir una posición larga.
Etcétera:
exchange.SetDirection("sell")
yexchange.Sell
Cuando se usan juntos, significa que la orden realizada es una orden para abrir una posición corta.
exchange.SetDirection("closebuy")
yexchange.Sell
Cuando se usan juntos, significa que la orden realizada es una orden para cerrar una posición larga.
exchange.SetDirection("closesell")
yexchange.Buy
Cuando se usan juntos, significa que la orden realizada es una orden para cerrar una posición corta.
Por lo general, los novatos lo haránexchange.SetDirection("sell")
yexchange.Buy
Utilizado en conjunción con otros u otras combinaciones incorrectas. Luego informó un error (el backtesting puede no informar un error, pero obviamente es un error lógico y las personas con trastorno obsesivo compulsivo no pueden tolerarlo…).
Otro error común que cometen los novatos
function main() {
exchange.SetContractType("quarter") // 设置当前合约为季度合约
exchange.SetDirection("sell")
var id = exchange.Sell(-1, 1)
Log("看我市价单下单了,成交了,就有持仓了", exchange.GetPosition())
exchange.SetDirection("closebuy") // closebuy 和Sell 搭配使用,嗯没错~
exchange.Sell(-1, 1)
}
Al ver esto, usted puede preguntarse: “¿Por qué tengo una posición y uso closebuy y sell juntos, pero me da un error y no puedo cerrar la posición?” Yo respondería: “¡Cerré en la dirección equivocada! Cerré la posición larga”.
Otra posible situación para el error anterior es: la dirección de cierre está configurada correctamente, la función de orden se utiliza correctamente y la posición se mantiene en esta dirección, pero este error aún se informa.
El motivo es que su programa puede haber colocado varias órdenes, pero la orden inicial no se ejecutó y la orden de cierre quedó en el mercado esperando a ser ejecutada. En este momento, el programa continúa cerrando la posición y le indicará un error de sobrepasar la posición de cierre.
print
。
JavaScriptconsole.log
。
Golangfmt.Println()
。
C++cout
Hablemos de la información que se muestra en la plataforma FMZ. En la plataforma de negociación cuantitativa Inventor, hay dos ubicaciones principales donde se muestra la información.
- Barra de estado
Una vez que se ejecuta el disco real, la página del disco real se muestra en la figura

La parte de visualización es la información de la barra de estado. La barra de estado se utiliza principalmente para mostrar algunos datos que cambian en tiempo real (porque los cambios en tiempo real deben observarse en tiempo real y no se pueden imprimir como registros cada vez, por lo que este tipo Se pueden mostrar varios datos en la barra de estado. Si se imprimen todos, el registro contendrá muchos datos repetidos y sin sentido, lo que afectará la consulta).
Mostrar el uso de datos en la barra de estado`LogStatus`Función, consulte la documentación API de FMZ para obtener más detalles.
- Columna de registro
También en la página del mercado real, como se muestra en la figura:

La parte de visualización es la barra de registro, que se utiliza principalmente para registrar de forma permanente ciertos datos en un momento determinado, o para registrar una determinada operación de una estrategia en un momento determinado.
Existen varios tipos de registros:
1. Registro ordinario: la estrategia FMZ utiliza la función Registro para generar e imprimir en el registro de estrategia.

2. Registro de órdenes, utilizado en la estrategia FMZ`exchange.Sell`/`exchange.Buy`Se registrará automáticamente en la salida del registro.

3. Registro de cancelación de pedidos, utilizado en la estrategia FMZ`exchange.CancelOrder`, el registro de cancelación de pedidos se imprimirá automáticamente en el registro.

4. Registro de errores. Cuando se ejecuta la estrategia FMZ, si se produce un error de llamada en la interfaz de la solicitud de red o se genera una excepción (como una instrucción como throw), se generará automáticamente un registro de errores en el registro.

Las funciones de la API de FMZ que pueden generar una salida de registro, como Log(…), exchange.Buy(Price, Amount), exchange.CancelOrder(Id), etc., pueden ir seguidas de algunos parámetros de salida adicionales después de los parámetros requeridos. como por ejemplo: intercambio.CancelarOrden(pedidos[j].Id, orders[j]) Esto es cancelar pedidos[j] Al realizar este pedido, se mostrará la información del pedido.
function main() {
Log("数据1", "数据2", "数据3", "...")
var data2 = 200
var id = exchange.Sell(100000, 0.1, "附带数据1", data2, "...")
exchange.CancelOrder(id, "附带数据1", data2, "...")
LogProfit(100, "附带数据1", data2, "...")
}
JavaScript
La estrategia de idioma se mostrará al imprimir los datos del indicador calculadonull
。Hay un ejemplo de enseñanza en Strategy Square: https://www.fmz.com/strategy/125770 Al realizar una prueba retrospectiva de esta estrategia de ejemplo del tutorial, puede ver el gráfico generado por el sistema de prueba retrospectiva y el promedio móvil de 10 períodos:
Dibujo de estrategia personalizado, línea K dibujada y gráfico de media móvil:
P: ¿Qué pasa si quiero el promedio móvil de 10 horas? Respuesta: Los datos de la línea K pueden utilizar los datos de la línea K del período horario.
En términos sencillos, la línea K que vemos es una matriz después de digitalizarla (si no entiende el concepto de matriz, puede buscar en Baidu), en la que cada elemento es una columna de la línea K, que está organizada en orden. El primer elemento es el más alejado de la hora actual y el último elemento de la matriz es el más cercano a la hora actual. Generalmente, la última barra de datos de la línea K es la barra del período actual, que cambia en tiempo real y no está terminada (puede observar los cambios iniciando sesión en la página de un exchange y observando su línea K). Los indicadores calculados también corresponden uno a uno a las barras de la línea K. En el ejemplo anterior, puede ver que un valor de indicador corresponde a una barra de la línea K. Tenga en cuenta que la última columna de la línea K cambia en tiempo real y los indicadores calculados también cambiarán con los cambios en la columna de la línea K.
En la plataforma de negociación cuantitativa Inventor, puede utilizar la biblioteca TA (una biblioteca implementada por la plataforma FMZ, integrada en el custodio y que se puede utilizar directamente en varios idiomas) o la biblioteca talib (talib es una biblioteca de indicadores bien establecida, integrado con JS y C++, y Python debe ser escrito por usted mismo) Instalar). Por ejemplo, en el ejemplo anterior, el promedio móvil se calcula: Usando la biblioteca TA:
function main() {
var records = exchange.GetRecords()
var ma = TA.MA(records, 10)
Log(ma) // 打印均线
}
Usando la biblioteca talib:
function main() {
var records = exchange.GetRecords()
var ma = talib.MA(records, 10)
Log(ma) // 打印均线
}
Los datos del indicador calculado ma son una matriz, cada elemento del cual corresponde a la matriz de K líneas (registros), es decir,ma[ma.length -1]
corresponderrecords[records.length - 1]
, etcétera.
Lo mismo se aplica a otros indicadores complejos, y es necesario prestar atención a indicadores como el MACD.
var macd = TA.MACD(records) // 这样只传入K线数据,不传入指标参数,指标参数采用的就是默认值,其它指标函数也是同理
En este momento, la variable macd es una matriz bidimensional (si no comprende el concepto, puede buscar en Baidu). En pocas palabras, una matriz bidimensional es una matriz y cada elemento de la misma también es una matriz. . Pregunta: ¿Por qué los datos del indicador macd son una matriz bidimensional? Respuesta: Porque el indicador MACD está compuesto por dos líneas (línea DIF y línea DEA) y un conjunto de barras de volumen (barra de volumen MACD, de hecho, estos datos de la barra de volumen también pueden considerarse como una línea). Entonces la variable macd se puede dividir en:
var dif = macd[0]
var dea = macd[1]
var macdColumn = macd[2]
También hay un ejemplo de enseñanza listo para usar aquí, si estás interesado, estúdialo: https://www.fmz.com/strategy/151972