Investigación avanzada de plataformas Análisis de datos y estrategia de Python

El autor:No lo sé., Creado: 2022-04-13 09:12:47, Actualizado: 2022-04-28 11:06:13

Investigación avanzada de plataformas Análisis de datos y estrategia de Python Backtest.ipynb

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.

Uso de Jupyter

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.

Tutorial

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.

Adquisición de datos

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=BTC,comenzar=2020-8-10,fin=2021-8-10,período=1h): Las cuerdas = [] tiempo de inicio = int ((tiempo.mktiempo(tiempo de fecha.strptiempo(inicio, %Y-%m-%d).tiempo múltiple))) *1000 tiempo final = int ((tiempo.mktiempo(tiempo de fecha.strptiempo(fin, %Y-%m-%d).tiempo múltiple))) *1000 mientras que el tiempo de inicio < tiempo de fin: res = requests.get ((https://fapi.binance.com/fapi/v1/klines?simbolo=%sUSDT&interval=%s&startTime=%s&limit=1000% ((simbolo,período,tiempo de inicio)) res_list = res.json() Klines += res_list #print ((datetime.utcfromtimestamp ((tiempo de inicio/1000).strftime ((%Y-%m-%d %H:%M:%S), len ((res_list)) tiempo de inicio = res_list[-1][0] return pd.DataFrame ((Klines,columns=[time,open,high,low,close,amount,end_time,volume,count,buy_amount,buy_volume,null]).astype ((float) En [85]: df = GetKlines ((símbolo=BTC,comenzar=2021-1-1,fin=2021-8-10,período=1h)

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 ((btc_klines.csv) df = pd.read_csv ((btc_klines.csv,index_col=0) En [87]: Df Fuera[87]: ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, tiempo de apertura alto bajo cantidad de cierre final_tiempo de volumen de cuenta buy_amount buy_volume nulo 0 11575.08 11642.00 11566.07 11591.37 6541.466 1596992399999 7.592336e+07 25724 3127.898 3.630633e+07 0 1 1596992400000 11591.39 11610.23 11526.90 11534.39 6969.252 1596995999999 8.057780e+07 27403 3390.424 3.920162e+07 0 2 1596996000000 11534.39 11656.69 11527.93 11641.07 6439.365 1596999599999 7.469135e+07 25403 3446.186 3.997906e+07 0 3 1596999600000 11641.06 11665.90 11624.20 11635.30 3911.582 1597003199999 4.555459e+07 17820 1842.413 2.145768e+07 0 4 1597003200000 11635.29 11684.00 11635.29 11673.81 3461.004 1597006799999 4.036804e+07 15513 1660.575 1.936981e+07 0 ........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... 8805 1628658000000 45627.72 45894.53 45540.00 45801.45 10296.202 1628661599999 4.710187e+08 112187 4988.565 2.282399e+08 0 En el caso de las empresas de servicios de telecomunicaciones, las empresas de servicios de telecomunicaciones y las empresas de servicios de telecomunicaciones se beneficiarán de la ayuda de la Comisión. En el caso de las empresas de servicios de telecomunicaciones, las empresas de servicios de telecomunicaciones y las empresas de servicios de telecomunicaciones se beneficiarán de la ayuda de la Comisión. 8808 1628668800000 46367.37 46643.13 46002.01 46217.01 23472.769 1628672399999 1.086549e+09 229533 12334.292 5.711837e+08 0 En el caso de las empresas de servicios de telecomunicaciones, las empresas de servicios de telecomunicaciones y las empresas de servicios de telecomunicaciones se benefician de la ayuda de la Comisión. - ¿ Por qué? 8810 filas × 12 columnas

- ¿ Por qué? En [88]: df.index = pd.to_datetime ((df.time,unit=ms) #convertir el índice en una fecha, lo cual es conveniente para trazar En [89]: df.close.plot ((figsize=(15,6), cuadrícula = Verdadero); #precio de cierre Fuera[89]:imgEn [92]: (df.buy_amount.rolling(150).mean()/df.amount.rolling(150.mean)).grafico (figsize=(15,6),cuadrícula = Verdadero); #después de plano, la proporción del importe de la compra de iniciativa # la situación en la que la proporción del importe de compra de iniciativa aumenta después de haber alcanzado el fondo normalmente responde a la situación de aumento de precios, pero el promedio a largo plazo de la proporción del importe de compra de iniciativa es del 49% Fuera[92]:imgEn [93]: (df[count].rolling(100).mean (()).plot ((figsize=(15,6),grid = True); #el importe ejecutado después del plano,y las cotizaciones del mercado podrían prepararse en una ubicación baja Fuera de juego[1]:img

Motor de prueba posterior

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[USDT][beneficio no realizado] = 0 para el símbolo en self.trade_symbols: el valor de las acciones de la empresa es el valor de las acciones de la empresa, y el valor de las acciones de la empresa es el valor de las acciones de la empresa. el valor de las acciones de la entidad es igual al valor de las acciones de la entidad. auto.cuenta[símbolo][valor] = abs(auto.cuenta[símbolo][cantidad]) * precio cerrado[símbolo] Cuenta propia[USDT][beneficio no realizado] += cuenta propia[símbolo][beneficio no realizado] cuenta propia[USDT][total] = redonda(cuenta propia[USDT][beneficio realizado] + saldo inicial+cuenta propia[USDT][beneficio no realizado],6) En el [117]: #En la prueba, se puede ver que no hay énfasis en si la plataforma es USDT-marginada o spot. e = Exchange([BTC], tarifa=0.0004, balance inicial_=10000) #crear un objeto Exchange, y sólo un par de operaciones de BTC e.Comprar BTC ,40000, 0.1) #comprar 0.1 BTC al precio de 40.000 e.Vender BTC ,41000, 0.1) # vender 0,1 BTC al precio de 41.000 e.Actualizar la información de la cuenta Imprimir ((e.account) #la información final de la cuenta imprimir (("Ganancia: ', redonda ((e.cuenta[USDT][total]-e.saldo inicial,2)) Fuera[117]:{USDT: {beneficio realizado: 96.76, beneficio no realizado: 0.0, total: 10096.76, tarifa: 3.24}, BTC: {cantidad: 0.0, precio de retención: 0, valor: 0.0, precio: 000, 41 beneficio realizado: 100.0, beneficio no realizado: 0.0, tarifa: 3.24}} ganancia: 96,76

Prueba de retroceso de la estrategia de red

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 Live, hay un bot oficial, comenzado el 4 de abril de 2021; el valor de posición es 150, el espaciado de la cuadrícula es 0.01, y la ganancia actual es 3600USDT. Usando los mismos parámetros y la línea K de 5min para backtest, la ganancia es 3937USDT. Dado que el valor de posición al comienzo del bot es menor a 150 USDT, el resultado es bastante preciso. Si cambia el espaciado de la cuadrícula a 0.005, la ganancia será de 5226U. Un espaciado de la cuadrícula de 0.005 es obviamente un parámetro mejor que 0.01, que necesita ser backtestado para averiguarlo.

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 = TRX df = GetKlines ((símbolo=símbolo,comenzar=2021-4-4,fin=2021-8-11,período=5m) En [286]: valor = 150 pct = 0,01

e = Intercambio (([símbolo], tasa=0.0002, saldo inicial_10000) init_price = df.loc[0,close] res_list = [] #se utiliza para almacenar el resultado medio para la fila en df.iterrows ((): kline = fila [1] #que solo probará una línea K y solo obtendrá una orden de compra o una orden de venta, lo que no es muy preciso buy_price = (valor / pct - valor) / ((valor / pct) / init_price + e.account[símbolo][cantidad]) #precio de la orden de venta, ya que es una ejecución del fabricante, es también el precio final de correspondencia el precio de venta = (valor / pct + valor) / ((valor / pct) / init_price + e.account[símbolo][cantidad])

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=[tiempo,precio,cantidad,beneficio]) res.index = pd.to_datetime ((res.time,unidad=ms) En [287]: e.cuenta Fuera[287]:{USDT: {realizada_ ganancia: 3866.633149565143, ganancias no realizadas: 70.54622281993666, total: 13937.179372, tarifa : 177,51000000000596}, TRX: {cantidad: 36497.43208747655, precio de retención: 0,08203709078461048, valor: 3064.689372385406, precio : 0,08397, beneficio obtenido: 4044.143149565462, ganancias no realizadas: 70.54622281993666, fees: 177.51000000000596}} En [288]: res.profit.plot ((figsize=(15,6), cuadrícula = Verdadero); Fuera de juego:imgEn el [170]: res.price.plot ((figsize=(15,6), cuadrícula = Verdadero); #precio cerrado Fuera[170]:img

Estrategia de equilibrio puntual Prueba posterior

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 = [BTC,ETH,LTC,XRP] datos = {} para el símbolo en símbolos: df = GetKlines ((símbolo=símbolo,comenzar=2020-8-11,fin=2021-8-11,período=1h) el número de datos [símbolo] = df.close En [291]: df = pd.DataFrame (([datos[símbolo].valores del símbolo en los símbolos],index=símbolos).T En [302]: e = intercambio ((símbolos, tarifa=0.0004, saldo inicial=10000) Res_list = [] para la fila en df.iterrows ((): precios = fila [1] Total = cuenta electrónica[USDT][total] e.Actualización de los precios para el símbolo en símbolos: pct = e.cuenta[símbolo][valor]/total si el pct es > 0,26: e.Vender (símbolo,precios (símbolo), punto 0.25) *total/precios (símbolo)) si el pct es < 0,24: e.Comprar (símbolo,precios (símbolo)) res_list.append (([e.account[símbolo][valor] para símbolo en símbolos] + [e.account[USDT][total]]) res = pd.DataFrame ((datos=res_list, columnas=símbolos+[total]) En el [303]: (df/df.iloc[0,:]).plot(figsize=(15,6),grid = True); #plot la tendencia por normalización Fuera[303]:imgEn el [304]: (res.total/10000-(df/df.iloc[0,:]).medio ((eje=1)).grafía (figsize=(15,6),cuadrícula = Verdadero); #enheance el efecto Fuera[304]:img

Estrategia de la tortuga

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 = ETH df = GetKlines ((símbolo=símbolo,comenzar=2019-8-11,fin=2021-8-11,período=6h) En el [425]: df.index = pd.to_datetime ((df.time,unidad=ms) En [568]: M = 5 # volumen del período del canal de Donchian pct = 0,003 #la proporción de las posiciones añadidas en el total de las posiciones df[up] = df[high].rolling ((M).max().shift(1) #upBanda del canal de Donchian, utilizada para hacer largo y juzgar para romper t df[abajo] = df[bajo].rollo ((M).máximo().cambio(1) df[medio] = (df[arriba]+df[abajo])/2 df[true_range] = pd.concat([df[high]-df[low],df[high]-df[close].shift(1),df[close].shift(1)-df[low]], eje=1).max (eje=1) df[N] = df[true_range].rolling(50).mean() #N es igual a la volatilidad reciente, utilizada para juzgar la compra y el stop loss En [572]: Open_times = 0.3 #juicio de apertura de una posición tiempo de parada = 2,5 #pérdida de parada e = Intercambio (([símbolo], tarifa=0.0004, saldo inicial=10000) #establecer el tomador a 0.0004 Res_list = [] último_precio = 0 #último precio de la posición abierta para la fila en df.iterrows ((): línea = fila [1] si kline.isnull().sum() > 0: #salta la sección sin datos Sigue adelante. Unidad = e.cuenta[USDT][total]*pct/kline.N #valor unitario de la posición abierta

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=[tiempo,precio,valor,total]) res.index = pd.to_datetime ((res.time,unidad=ms) imprimir ((Valor de mercado final:,res[total][-1]) Salida[572]:Valor de mercado final: 280760.566996 En [573]: res.total.plot ((figsize=(15,6), cuadrícula = Verdadero); Fuera[573]:imgEn [571]: (res.value/res.total).plot ((figsize=(15,6), cuadrícula = Verdadero); Fuera[571]:img

Conclusión

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 [ ]:


Más.