Investigación avanzada de plataformas
FMZ tiene un cuaderno jupyter incorporado para ayudar a los usuarios a familiarizarse con la API de la plataforma y llevar a cabo la investigación de estrategias, y admite los entornos de aprendizaje de Python3 C++11/17 y Javascript. Notebook+Python es una herramienta muy poderosa, que es casi indispensable para el análisis de datos y la investigación de estrategias. Aunque el backtest que viene con la plataforma FMZ es muy útil, no es adecuado para estrategias con volúmenes de datos complejos y grandes.
El ambiente de investigación dentro de FMZ se puede utilizar, pero la red es inconveniente. Se recomienda instalar en su propio dispositivo el anaconda3, con cuaderno y bibliotecas relacionadas comúnmente utilizadas para cálculos matemáticos; puede compartir el entorno de red local y tener un mejor rendimiento. También se recomienda usar Google colab. Aunque hay algunas limitaciones de almacenamiento, es gratuito y potente, adecuado para la investigación relacionada con el estudio de robots.
Hay muchos tutoriales en línea para el uso específico de habilidades de cuaderno y Python. Puedes encontrar mucha información buscando palabras clave, como cuantificación de Python y tutorial de cuaderno jupyter.
Las plataformas generalmente proporcionan API para obtener K-lines con datos de historial, y algunas también proporcionan datos de ejecución de comercio por comercio. Necesitamos usar el rastreador para obtener y guardar los datos. También puede recibir directamente los datos enviados por la plataforma y crear un almacenamiento de base de datos local por sí mismo.
A continuación, vamos a demostrar cómo obtener y almacenar los datos de la línea K de los contratos perpetuos en Binance.
Primero, encuentra la documentación de Binance Perpetual Swap:https://binance-docs.github.io/apidocs/futures/cn/#c59e471e81. Puede ver los parámetros requeridos y los formatos de datos devueltos. Por lo general, el número de líneas K adquiridas por API es limitado, y Binance tiene un máximo de 1000, por lo que debe adquirirse por iteración de bucle. La situación en otras plataformas es similar a Binance. Tenga en cuenta que la red necesita estar conectada a la red extranjera (en comparación con la red doméstica en China) para rastrear las líneas K.
Los períodos que soporta Binance: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M.
En [24]:
solicitudes de importación #solicitudes de red para la biblioteca común
desde la fecha-hora-fecha de importación,fecha-hora
tiempo de importación
Importar pandas como pd
En el [160]:
def GetKlines ((símbolo=
El almacenamiento y la lectura de datos pueden utilizar las funciones dentro de la biblioteca de pandas.
Además del precio más alto, el precio más bajo, el precio de apertura, el precio de cierre y el volumen ejecutado, los datos de línea K devueltos por Binance también incluyen el monto total de operaciones, el monto de compra de iniciativas, el monto de ejecución, etc. Esta es información valiosa que se puede utilizar para construir estrategias.
En [86]:
Df.to_csv ((
- ¿ Por qué?
En [88]:
df.index = pd.to_datetime ((df.time,unit=
El artículo anterior también dio el motor de backtest de Python, pero aquí hay una versión optimizada. Los contratos perpetuos con margen de USDT (u otros contratos de cotización con margen de moneda) son muy similares a los contratos al contado. La diferencia es que los contratos perpetuos pueden aprovecharse y mantener una cantidad negativa (equivalente a hacer un corto) y pueden compartir un motor de backtest. Los contratos de entrega con margen de criptomonedas son especiales, ya que se liquidan en moneda y requieren una backtest específica.
Aquí se da un ejemplo simple, que puede implementar spot de símbolos múltiples o backtesting perpetuo de símbolos múltiples. Se ignoran muchos detalles: como apalancamiento de futuros, ocupación de margen, tasa de financiación, mecanismo de liquidación, creación de mercado y transacciones de tomadores de pedidos, así como mantenimiento de pedidos, pero generalmente no afecta los resultados normales de backtest. Y el precio y la cantidad de la coincidencia y la actualización de la cuenta todos necesitan ser importados externamente. Los lectores pueden mejorarlo sobre esta base.
Introducción de la clase de intercambio:
cuenta:USDT indica la moneda de base, que no es necesaria; realized_profit: las ganancias y pérdidas ya realizadas; unrealised_profit: las ganancias y pérdidas aún no realizadas; total: el capital total; comisión: la comisión de gestión. Para otros pares de operaciones, importe (que es un número negativo cuando se hace un corto); hold_price: el precio de tenencia; valor: el valor de la tenencia; precio: el precio actual.
trade_symbols: matriz de pares de operaciones; también puede pasar en un par de operaciones; la moneda de cotización predeterminada es USDT, pero también puede usar otros símbolos de divisas de cotización para backtest.
Compensación: la comisión de entrega; para ser sencillos, no hay que distinguir entre el que hace y el que recibe.
inicial_saldo: los activos iniciales; el importe inicial de los pares de negociación por defecto es 0.
Función de compra: comprar, que corresponde a hacer largo y cerrar corto de contratos perpetuos, sin un mecanismo de correspondencia.
Función de venta: vender.
Función de actualización: actualizar la información de la cuenta, que debe pasar en el diccionario de precios de todos los pares de operaciones. En [98]: clase Intercambio:
def Iniciar(auto, símbolos_de comercio, tasa=0.0004, saldo_inicial=10000): El saldo inicial de la entidad será el mismo que el saldo inicial de la entidad. auto.fee = cuota Se trata de un elemento de la lista de datos que se incluye en el anexo I del Reglamento (UE) n.o 1095/2010. En el caso de las entidades de crédito, el importe de las pérdidas se calculará en función de las pérdidas anuales de las entidades de crédito. para el símbolo en trade_symbols: En el caso de las empresas de servicios financieros, el importe de la ayuda se calculará en función de la situación de las empresas de servicios financieros.
def Comercio ((propio, símbolo, dirección, precio, cantidad):
cover_amount = 0 if direction*self.account[symbol]['amount'] >=0 else min(abs(self.account[symbol]['amount']), amount)
open_amount = amount - cover_amount
self.account['USDT']['realised_profit'] -= price*amount*self.fee #take out the fee
self.account['USDT']['fee'] += price*amount*self.fee
self.account[symbol]['fee'] += price*amount*self.fee
if cover_amount > 0: #close first
self.account['USDT']['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount #profit
self.account[symbol]['realised_profit'] += -direction*(price - self.account[symbol]['hold_price'])*cover_amount
self.account[symbol]['amount'] -= -direction*cover_amount
self.account[symbol]['hold_price'] = 0 if self.account[symbol]['amount'] == 0 else self.account[symbol]['hold_price']
if open_amount > 0:
total_cost = self.account[symbol]['hold_price']*direction*self.account[symbol]['amount'] + price*open_amount
total_amount = direction*self.account[symbol]['amount']+open_amount
self.account[symbol]['hold_price'] = total_cost/total_amount
self.account[symbol]['amount'] += direction*open_amount
def Comprar (solo, símbolo, precio, cantidad):self.Trade(símbolo 1, precio, cantidad)
def Vender (sólo, símbolo, precio, cantidad):self.Trade(símbolo -1, precio, cantidad)
def Actualizar ((self, close_price): #actualizar los activos
Cuenta propia[
En primer lugar, vamos a backtest una estrategia clásica de red perpetua. Esta estrategia es muy popular en nuestra plataforma recientemente. En comparación con la red al contado, no necesita mantener moneda y puede agregar apalancamiento, que es mucho más conveniente que la red al contado. Sin embargo, ya que no se puede backtestar directamente, no es propicio para seleccionar símbolos de moneda. Aquí usamos el motor de backtest ahora para probarlo.
En la parte superior de
Cuanto más corto sea el período de la línea K, más precisos serán los resultados de la prueba de retroceso correspondientes y mayor será la cantidad de datos requeridos.
En el [241]:
el símbolo =
e = Intercambio (([símbolo], tasa=0.0002, saldo inicial_10000)
init_price = df.loc[0,
if kline.low < buy_price: #the lowest price of K-line is less than the current maker price; the buy order is executed
e.Buy(symbol,buy_price,value/buy_price)
if kline.high > sell_price:
e.Sell(symbol,sell_price,value/sell_price)
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount'], e.account['USDT']['total']-e.initial_balance])
res = pd.DataFrame ((data=res_list, columnas=[
Este tipo de estrategia también es relativamente popular, pero la plataforma FMZ no es muy buena en backtesting de estrategias de símbolos múltiples, solo use este motor de backtest para intentarlo. Seleccionamos cuatro símbolos de divisas principales, BTC, ETH, LTC y XRP, y configuramos el 25% del valor de mercado respectivamente, y equilibramos cada desviación del 1%.
Primero, obtenga los precios de cierre de los cuatro símbolos en el último año. Se puede ver que ETH tiene el mayor aumento, y los otros tres tienen aumentos similares. Si mantiene estos cuatro símbolos en promedio, el valor neto final es de 4.5.
En el [290]:
los símbolos = [
La estrategia de tortuga es una estrategia de tendencia clásica, que incluye una lógica completa de stop-loss para agregar posiciones.https://zhuanlan.zhihu.com/p/27987938Vamos a implementar una versión simple aquí para backtest.
El período de estrategia de tortuga tiene una gran influencia en la estrategia, y no es aconsejable elegir un período que sea demasiado corto. Aquí, elegimos 6h. El período del canal de Donchian se selecciona como 5, y la relación de posición se selecciona como 0.003 de acuerdo con la prueba de retroceso. Cuando el precio rompe la banda ascendente del canal para abrir 1 unidad de posición larga, y el precio continúa aumentando en 0.3 volatilidad después de abrir las posiciones, continúa agregando 1 unidad, y el precio cae por debajo de 2.5 Volatilidad del último precio abierto para detener la pérdida. El principio de la orden corta es el mismo. Debido al gran mercado alcista de ETH, la estrategia de tortuga ha capturado la tendencia principal y finalmente ha logrado 27 veces las ganancias, con un apalancamiento máximo de 4 veces durante el período.
Los parámetros de la estrategia de tortuga están estrechamente relacionados con el período y deben seleccionarse mediante pruebas de retroceso.
Se puede ver en el gráfico final del valor neto que la estrategia de tortuga es una estrategia a largo plazo, durante la cual puede no haber ganancias durante 3 a 4 meses, y pérdidas de parada repetidas, pero una vez que hay una gran cotización de mercado en un lado, la estrategia de tortuga puede aprovechar la tendencia para acumular una posición grande, mantenerla hasta el final de la tendencia, obtener muchas ganancias. Al final del aumento, la estrategia acumulará muchas posiciones. En este momento, la volatilidad será relativamente grande, y a menudo se retirarán grandes ganancias. El uso de la estrategia de tortuga requiere que acepte sus deficiencias y su paciencia.
En el [424]:
el símbolo =
if kline.high > kline.up and e.account[symbol]['amount'] == 0: #first time to open long position
e.Buy(symbol,kline.up,unit) #notice the trading price here
last_price = kline.up
if e.account[symbol]['amount'] > 0 and kline.high > last_price + open_times*kline.N: #long position, buy in
e.Buy(symbol,last_price + open_times*kline.N,unit)
last_price = last_price + open_times*kline.N
if e.account[symbol]['amount'] > 0 and kline.low < last_price - stop_times*kline.N: #long position, stop loss
e.Sell(symbol,last_price - stop_times*kline.N,e.account[symbol]['amount'])
if kline.low < kline.down and e.account[symbol]['amount'] == 0: #open short
e.Sell(symbol,kline.down,unit)
last_price = kline.down
if e.account[symbol]['amount'] < 0 and kline.low < last_price - open_times*kline.N: #short position, buy in
e.Sell(symbol,last_price - open_times*kline.N,unit)
last_price = last_price - open_times*kline.N
if e.account[symbol]['amount'] < 0 and kline.high > last_price + stop_times*kline.N: #short position, stop loss
e.Buy(symbol,last_price + stop_times*kline.N,-e.account[symbol]['amount'])
e.Update({symbol:kline.close})
res_list.append([kline.time, kline.close, e.account[symbol]['amount']*kline.close, e.account['USDT']['total']])
res = pd.DataFrame ((datos=res_list, columnas=[
Si usted es experto en el uso de la plataforma de investigación jupyter notebook, usted puede realizar fácilmente operaciones, como la adquisición de datos, análisis de datos, estrategia backtest, visualización de gráficos, etc., que es la forma inevitable para el comercio cuantitativo.
Utilice Python para realizar el análisis de datos:https://wizardforcel.gitbooks.io/pyda-2e/content/
Tutorial cuantitativo de Python:https://wizardforcel.gitbooks.io/python-quant-uqer/content/
En [ ]: