En el último artículo, hablamos de scripts de trading programados. De hecho, la estrategia de trading es un programa de script de trading. El artículo habla principalmente de la necesidad de un portador de hardware para el programa de script de trading (donde se ejecuta el programa), y el programa de script de trading puede escribirse en ese lenguaje de programación de computadora (enumerando los tres lenguajes de programación utilizados en FMZ Quant Trading Platform; por supuesto, puedes usar cualquier lenguaje de programación para implementar estrategias en el trading programado).
Tipo de estrategia de negociación Los principiantes que son nuevos en el comercio programado y el comercio cuantitativo pueden confundirse con varios términos como estrategia de tendencia, estrategia de arbitraje, estrategia de alta frecuencia, estrategia de red, etc. De hecho, los tipos comunes de estrategias en el comercio programado y el comercio cuantitativo son simplemente en varias direcciones.
Estrategia de arbitraje En pocas palabras, una estrategia que básicamente mantiene posiciones largas mientras mantiene posiciones cortas puede clasificarse como una estrategia de arbitraje.
Estrategia de tendencia En pocas palabras, es la estrategia de seguir la tendencia y colocar una sola posición, como la media móvil doble, el MACD y otras estrategias.
Estrategia de retorno Por ejemplo, la estrategia de red, ganando el rendimiento de las fluctuaciones de precios en mercados volátiles.
Estrategia de alta frecuencia En pocas palabras, es una estrategia para realizar operaciones de alta frecuencia a través de algunos algoritmos para descubrir la microestructura del mercado, reglas, oportunidades, etc.
Los tipos anteriores se clasifican desde el punto de vista de la estrategia comercial; desde el punto de vista del diseño de estrategias en FMZ Quant, las estrategias también se pueden dividir en:
Estrategia de un solo símbolo Es decir, la estrategia solo puede operar un símbolo, como hacer un comercio de BTC o ETH.
estrategia de varios símbolos En pocas palabras, es operar múltiples símbolos por una lógica de estrategia.
estrategia de cuentas múltiples En pocas palabras, se trata de configurar múltiples objetos de intercambio en un bot (el concepto de plataforma se ha introducido en el artículo anterior, y un objeto de intercambio configurado con una clave API representa una cuenta de plataforma). Por ejemplo, en algunas estrategias de supervisión de pedidos, varias cuentas seguirán una operación juntas (que pueden ser las cuentas de la misma plataforma o plataformas diferentes).
Estrategia multi-lógica Por ejemplo, la estrategia MACD, la estrategia de media móvil, la estrategia de cuadrícula, etc. se diseñan al mismo tiempo en un bot (por supuesto, es para operar diferentes objetos de intercambio, y los objetos de intercambio con la misma operación dependen de si la estrategia específica es lógicamente conflictiva)
Interfaz API de la plataforma
La respuesta es a través de la interfaz API abierta por la plataforma.
Entonces, ¿qué tipos de interfaces están abiertas a las plataformas? En el artículo anterior, hablamos de que las plataformas generalmente tienen interfaces REST y Websocket en la sección
Interfaces que no requieren verificación
Por lo general, se denominan API KEY
Este tipo de interfaz es generalmente una interfaz de mercado, como consultar cotizaciones de mercado profundas, datos de la línea K, tasas de financiación, la información sobre símbolos de negociación, sellos de tiempo del servidor de la plataforma, etc.
En pocas palabras, la interfaz que básicamente no está relacionada con su cuenta puede determinarse aproximadamente como una interfaz pública (no se requiere verificación).
En FMZ Quant Trading Platform, cuando se llama a una función API no verificada (encapsula la interfaz no verificada de la plataforma; interfaz pública), incluso si la configuración de la clave API es incorrecta, los datos devueltos por la interfaz se pueden obtener normalmente. (no se requiere verificación)
Interfaces que requieren verificación En pocas palabras, son las interfaces que deben ser verificadas (por API KEY). Este tipo de interfaz se llama interfaz privada. Este tipo de interfaz generalmente está relacionado con algunas operaciones o información de su cuenta, como consultar activos de la cuenta, posiciones de la cuenta, órdenes pendientes, transferencias, conversión de moneda, ajuste de apalancamiento y configuración del modo de posición, etc. Estas operaciones deben ser verificadas.
En FMZ Quant, al llamar a las funciones API que necesitan verificación (las interfaces privadas, que están encapsuladas y necesitan la verificación de la plataforma). Si la configuración de API KEY es incorrecta, llamar a este tipo de función reportará un error y devolverá null.
Entonces, ¿cómo usar estas interfaces en FMZ Quant Trading Platform?
FMZ Quant Trading Platform encapsula las interfaces de la plataforma con acciones y definiciones unificadas (como interfaces de línea K, interfaces de mercado profundo, interfaces de consulta de activos actuales, interfaces de órdenes, interfaces de cancelación de órdenes, etc.). Estas interfaces se llaman en FMZ Quant Trading Platform. Las funciones de la API de FMZ se pueden ver consultando la documentación de la API: (https://www.fmz.com/api).
Entonces, ¿cómo usar algunas interfaces de plataforma sin acciones y definiciones unificadas en FMZ Quant?
Estas interfaces de la plataforma incluyen: transferencia de activos, orden condicional, orden por lotes, cancelación de orden por lotes, modificación de orden, etc. Algunas plataformas tienen estas interfaces, otras no, y las funciones y detalles de uso pueden ser bastante diferentes, por lo que estas interfaces se pueden acceder a través delexchange.IO
Función en la plataforma de negociación FMZ Quant (para más detalles, véase la documentación de la API de la plataforma de negociación FMZ Quant:https://www.fmz.com/api#exchange.io..También hay algunas estrategias prácticas de ejemplo de IO en el
¿Pueden todas las funciones de API en la documentación de FMZ API hacer una solicitud de red?
Debemos decir que las API de la plataforma tienen un límite para la frecuencia de acceso (por ejemplo, 5 veces en 1 segundo). El acceso no puede ser demasiado frecuente, o se reportará el error de http 429, y el acceso será rechazado (la mayoría de las plataformas reportan 429). Por lo tanto, llamar a las interfaces de la plataforma encapsuladas en FMZ Quant también tiene el límite, pero llamar a las funciones de API que no hacen solicitudes de red no tiene tal límite.
No todas las funciones de API en FMZ Quant pueden realizar solicitudes de red; algunas funciones de API en FMZ solo modifican algunas configuraciones locales, como establecer el par de operaciones actual, el código de contrato y la función de cálculo de indicadores, así como adquirir el nombre del objeto de intercambio, etc.
Básicamente, desde el uso de la función a, se puede determinar si se hará una solicitud de red; siempre que se trate de adquirir los datos de la plataforma, o operar una cuenta de plataforma, se hará una solicitud de red; estas interfaces necesitan prestar atención a la frecuencia de invocación.
Hablemos de varios problemas comunes y experiencia de uso de funciones API en FMZ Quant.
Tolerancia de fallas Este es el error más común, que ha preocupado a innumerables principiantes. A menudo, la estrategia backtest es buena y todo es normal. ¿Por qué el bot funciona anormalmente después de que el bot se ejecuta durante un tiempo (que puede desencadenarse en cualquier momento)?
Al escribir una estrategia, para los datos devueltos por la interfaz debe verificarse. Por ejemplo, el código de obtener ticker en FMZ Quant (que es lo mismo que escribir su propio programa para acceder directamente a la interfaz de la plataforma):var ticker = exchange.GetTicker()
• si es necesario utilizar los datos deLast
(el último precio) en la variableticker
(se puede referir a la estructura de retorno de la función GetTicker), necesitamos obtener los datos (¿qué es newPrice? new: el último; Price: price; that
Ahora, está bien si la funciónGetTicker()
devuelve los datos normales; si hay una solicitud de tiempo de espera, error de red, plataforma de tirar del cable, cables rotos por la excavación, o los niños apagar el interruptor de electricidad, la funciónGetTicker()
Volverá.null
En este momento, el valor deticker
esnull
; cuando accedo a laLast
de la misma, el programa estratégico se detendrá por excepción de programa.
A partir de eso, parece que el fracaso de la llamada de interfaz (la invocación de GetTicker falla y devuelve null) no es la causa directa de la parada del bot de estrategia (la causa directa es que un atributo de unnull
La situación de que el fallo de la llamada de interfaz reporta un error no hará que el bot se detenga (énfasis añadido aquí).
Entonces, ¿qué debemos hacer para evitar la parada anormal de bot?
La respuesta es hacer el proceso de tolerancia a fallas a los datos devueltos por interfaces; es muy simple, y sólo necesita para juzgar si los datos devueltos esnull
(aquí tomar JavaScript como ejemplo, para los otros idiomas son similares).
Escribir un pequeño segmento de código (que es sólo para instrucción, y no se puede ejecutar directamente!)
var ticker = exchange.GetTicker()
if (ticker) {
var newPrice = ticker.Last
Log("Print the latest price:", newPrice)
} else {
// data is null, so no operation will make no problem
}
No sólo elGetTicker
La interfaz necesita hacer el procesamiento tolerante a fallas, pero la interfaz con las solicitudes de red necesita hacer el procesamiento tolerante a fallas para el valor de retorno (si utiliza el valor de retorno de la función)
Hay muchos métodos de tolerancia a fallas._C()
función (consulte la documentación de la API FMZ) para escribir su propia función tolerante a fallas y diseñar su propio mecanismo y lógica tolerantes a fallas.
En lo que se refiere a la utilización de la_C()
En la actualidad, la mayoría de los nuevos estudiantes también utilizan incorrectamente la función._C()
La función es una referencia de función, no una llamada de función._C(funcName, param1, param2)
; la llamada es correcta; funcName no tiene paréntesis, y param1 y param2 son los parámetros a importar a la función funcName._C(funcName(param1, param2))
; la llamada es incorrecta; por lo general, si un principiante no lee la documentación de la API FMZ cuidadosamente, se escribirá así.
Valor de la orden de compra en el mercado al contado
Como se mencionó en el artículo anterior, el monto de la orden de la orden de compra del mercado al contado es generalmente la cantidad de dinero (sólo algunas de las plataformas pueden tener otros ajustes, y generalmente estos ajustes especiales de la plataforma se explicarán en la documentación de la API de FMZ).
Establecer el par de operaciones como:LTC_USDT
function main() {
exchange.IO("simulate", true) // switch to OKEX simulated bot
exchange.Buy(-1, 1) // the price is -1, representing the placed order is market order; the amount of 1 means the order amount of 1 USDT
}
Dado que las plataformas generalmente tienen un límite en el monto del pedido, los pedidos con un monto menor que el límite no se colocarán (por ejemplo, Binance Spot requiere que solo se puedan colocar con éxito pedidos con un monto superior a 5USDT). Por lo tanto, la colocación de un pedido como este reportará un error:
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:]
Dirección de las órdenes de futuros
Al hacer estrategias de futuros, los principiantes a menudo cometen errores en la dirección del orden. Tomando el ejemplo de escribir estrategias en FMZ Quant, veamos primero la descripción en la documentación de la API:https://www.fmz.com/api#exchange.setdirection...
Porque la función de orden sólo tieneBuy
ySell
Sin embargo, los futuros (por supuesto, no hay problema para el lugar, para el lugar sólo tiene comprar y vender) tiene las direcciones de apertura larga, cerrar largo, abrir corto, y cerrar corto, por lo que obviamente exchange.SetDirection()
de establecer las direcciones de negociación de futuros.
En FMZ,exchange.SetDirection("buy")
(que primero establece la dirección primero) se utiliza junto conexchange.Buy
, lo que significa que la orden puesta es una orden para abrir posiciones largas.
Y así sucesivamente:
Utilizaciónexchange.SetDirection("sell")
yexchange.Sell
la orden puesta es una orden para abrir posiciones cortas.
Utilizaciónexchange.SetDirection("closebuy")
yexchange.Sell
el valor de las posiciones largas que se han colocado en el mercado, que representa la orden puesta, es una orden para cerrar posiciones largas.
Utilizaciónexchange.SetDirection("closesell")
yexchange.Buy
La orden de cierre de posiciones cortas es una orden de cierre de posiciones cortas.
Los principiantes, por lo general, usaránexchange.SetDirection("sell")
yexchange.Buy
Entonces, un error será reportado (un error no puede ser reportado en el backtest, pero eso es obviamente un error lógico, que no puede ser ignorado por personas obsesivo-compulsivas como yo).
Este es otro error que suelen cometer los principiantes.
function main() {
exchange.SetContractType("quarter") // set the current contract to a quarterly contract
exchange.SetDirection("sell")
var id = exchange.Sell(-1, 1)
Log("placed market order, executed, get positions", exchange.GetPosition())
exchange.SetDirection("closebuy") // use closebuy and Sell together, yes, no problem
exchange.Sell(-1, 1)
}
Cuando se trata de aquí, usted podría preguntar:" Tengo posiciones, y utilizar closebuy y vender juntos, entonces, ¿por qué se informa un error y no puedo cerrar posiciones? "Yo diría:" dirección equivocada para cerrar posiciones!
Además, el error puede estar en otra situación: el ajuste de la dirección de posición cercana es correcto, el uso de la función de colocación de órdenes también es correcto, y también se mantienen las posiciones en la dirección, pero el error todavía se informa.
La razón podría ser: su programa ha colocado muchas órdenes, las órdenes al principio no se ejecutan, y las órdenes de posiciones cerradas están ahora en el mercado y esperando su ejecución.
Presentación de la información de exportación y comercio del registro
El diseño y escritura de estrategias comerciales programadas y cuantitativas es inseparable del diseño de las interacciones hombre-computadora, como print
¿ Qué pasa?
Utiliza el javascriptconsole.log
- ¿ Por qué?
Uso en el Golangfmt.Println()
- ¿ Por qué?
Utilizaciones de C++cout
.
Hablemos de la visualización de información en FMZ. En FMZ Quant, hay principalmente dos lugares para mostrar información.
Barra de estado Después de que el bot se inicia, la página del bot se muestra de la siguiente manera:
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 cambiantes en tiempo real (porque los cambios en tiempo real deben observarse en tiempo real, y no se pueden imprimir como un registro cada vez, por lo que este tipo de datos se pueden mostrar en la barra de estado. Si imprime el registro de cada uno, habrá muchos datos repetidos sin sentido, lo que afecta a la consulta).
Los datos que se muestran en la barra de estado utilizan elLogStatus
Para más detalles, consulte la documentación de la API de la FMZ.
Barra de registro También está en la página del bot, como se muestra en la siguiente imagen:
La parte de visualización es la barra de registro. La barra de registro se utiliza principalmente para registrar permanentemente ciertos datos en un momento determinado, o registrar una operación de una determinada estrategia en un momento determinado. Los troncos se dividen en varios tipos:
exchange.Sell
/exchange.Buy
en una estrategia FMZ automáticamente emitirá el registro en el registro.exchange.CancelOrder
se utiliza en una estrategia FMZ, y el registro de cancelación se emitirá automáticamente en el registro.Entre las funciones de la API de FMZ, las funciones que pueden generar salida de registro, como Log ((...), exchange.Buy ((Precio, Cantidad), exchange.CancelOrder ((Id), etc., pueden ser seguidas por algunos parámetros de salida adicionales después de los parámetros necesarios, como: exchange. CancelOrder ((ordenes[j].Id, órdenes[j]); es para extraer adicionalmente la información del pedido cuando se cancela el orden de pedidos[j]
function main() {
Log("data1", "data2", "data3", "...")
var data2 = 200
var id = exchange.Sell(100000, 0.1, "additional data1", data2, "...")
exchange.CancelOrder(id, "additional data1", data2, "...")
LogProfit(100, "additional data1", data2, "...")
}
Uso de las funciones de indicadores Antes de hablar de la función del indicador, primero entendamos qué es un indicador.
P: ¿Cómo se generan esos indicadores? R: Ciertamente son generados por cálculos.
P: ¿En qué se basan? R: Datos de la línea K.
P: ¿Puede dar un ejemplo? R: Tomando el indicador de promedio móvil más simple como ejemplo. Si usamos la línea K diaria (es decir, una línea yang o una línea yin representa un día) como fuente de datos para el cálculo del indicador. El parámetro del indicador de promedio móvil es 10, entonces el indicador de promedio móvil calculado es el promedio móvil de 10 días.
P: Si el número de BAR de la línea K es inferior a 10, ¿se puede calcular el indicador de la media móvil?
R: No solo no se puede calcular el indicador de la media móvil, sino que ningún indicador puede calcular el valor efectivo del indicador cuando el número de datos BAR de la línea K no cumple con el parámetro del período del indicador, y la posición correspondiente de la matriz calculada se llenará con valores vacíos, tales comonull
se muestra cuando elJavaScript
La estrategia imprime los datos de los indicadores calculados.
Hay un ejemplo de enseñanza en la Plaza:https://www.fmz.com/strategy/125770Prueba esta estrategia de ejemplo de enseñanza, y puedes ver el gráfico generado por el sistema de prueba de retroceso y el promedio móvil de 10 períodos:
Por estrategia dibujo personalizado, K-línea dibujada y gráfico de media móvil:
P: ¿Qué pasa si quiero usar una media móvil de 10 horas? A: utilizar los datos de la línea K de un período horario.
En pocas palabras, la línea K que vemos es una matriz después de que la digitalizamos (si no entiendes el concepto de matriz, puedes buscarla en Baidu), y cada elemento de la matriz es una barra de línea K, que está dispuesta en orden. Por lo general, la última barra de los datos de la línea K es la barra del período actual, que cambia en tiempo real y no se completa (se pueden observar los cambios iniciando sesión en una página de la plataforma y observando su línea K). Los indicadores calculados también están en correspondencia uno a uno con las barras de la línea K. En el ejemplo anterior, se puede ver que un valor de indicador corresponde a una barra de la línea K. Tenga en cuenta que la última barra de la línea K cambia en tiempo real, y el indicador calculado también cambiará con el cambio de la barra de la línea K.
En FMZ Quant Trading Platform, puede usar la biblioteca TA (la biblioteca implementada por FMZ, integrada en el docker, y puede usarse directamente en varios idiomas) o talib (la antigua famosa biblioteca de indicadores
function main() {
var records = exchange.GetRecords()
var ma = TA.MA(records, 10)
Log(ma) // print average
}
Utiliza el talib:
function main() {
var records = exchange.GetRecords()
var ma = talib.MA(records, 10)
Log(ma) // print average
}
El índice calculado de datos ma es una matriz, y cada elemento corresponde a la matriz de K-línea (registros) uno por uno, es decir,ma[ma.length -1]
corresponde arecords[records.length - 1]
, y así sucesivamente.
Es lo mismo para otros indicadores más complicados, y usted necesita prestar atención a indicadores como el MACD.
var macd = TA.MACD(records) // In this way, only the K-line data is passed in, and no indicator parameters are passed in. The indicator parameters use the default values, and that is the same for other indicator functions
En este momento, la variable macd es una matriz bidimensional (puedes Baidu, si no entiendes el concepto).
P: ¿Por qué los datos del indicador MACD son una matriz bidimensional? R: Porque el indicador macd se compone de dos líneas (línea dif y línea dea) y un conjunto de barras de volumen (los datos de la barra de volumen macd, de hecho, también se pueden considerar como una línea).
var dif = macd[0]
var dea = macd[1]
var macdbar = macd[2]
Aquí también hay un ejemplo de enseñanza ya hecho; si está interesado, puede estudiarlo:https://www.fmz.com/strategy/151972