<jupyter_start><jupyter_text>MAF1731 - Microestructura y Sistemas de trading        Ingeniería Financiera                                                <NAME>     Abril 2022  |   Repositorio: Link      Lab 2      Trading Algorítmico     Abstract    En este proyecto se creará un sistema de trading, que permita al usuario optimizar la estrategia para escoger la que tenga una mayor o menor función de utilidad (dependiendo el caso).       1. Introducción     Usando el broker online FXCM, obtendremos información del símbolo de nuestra preferencia, para poder aplicar técnicas de trading.     El primer paso es descargar información y dividirla en los siguientes periodos. A) Pre-pandemia: 31-01-2018 a 31-01-2020.B) En-pandemia-1: 28-02-2020 a 31-03-2021C) En-pandemia-2: 01-04-2021 a 31-12-2021 Ahora, para definir un sistema de trading necesitamos de 4 criterios:1) Criterio de uso de datosEn este caso, utilizaremos el par "BTC/USD" con temporalidad de 4 horas (debido a que el servidor no deja descargar más datos), y utilizaremos los "Adj. Open" y "Adj. Close", dependiendo de la situación.2) Criterio de generación de señalesSe calcularán 2 promedios móviles exponenciales (EMA), uno de longitud corta, y otro de longitud más larga que el anterior. La señal de compra se dará cuando el EMA corto cruce hacia arriba al EMA largo y la de venta cuando lo cruce hacia abajo.La lógica detrás de esta técnica nos dice que, cuando EMA corto cruza hacia arriba, significa que la tendencia en el corto plazo está cambiando de direción respecto a la del largo plazo, es este caso, la tendencia es alcista, por eso escogemos esta sencilla técnica.3) Criterio de toma de pérdidas y gananciasTake profit: Será el momento en el que cerremos la operación con un rendimiento positivo.Stop loss: Será el momento en el que cerremos la operación con un rendimiento negativo, lo hacemos para no arriesgar el capital.4) Criterio de dimensionamiento de posicionesSe utilizará todo el capital disponible para esta técnica, y únicamente entraremos a operaciones en largo, es decir, de compra.<jupyter_code>import time
inicio = time.time()
import system_desing as sd
import system_optimization as so
import functions as fn
#import data as dt
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Se realiza un gráfico del histórico de los precios para comprobar que han sido descargados correctamente. GRÁFICO 1<jupyter_code>plt.plot(sd.data_ohlc['close'])
plt.title("BTC/USD")
plt.xlabel("Días")
plt.ylabel("Precios")
plt.show()<jupyter_output><empty_output><jupyter_text>La primera prueba del proceso de trading se hará con parámetros al azar, y observaremos como se comporta la técnica sin ningún tipo de optimización.<jupyter_code>proceso_prueba = sd.proceso_completo(sd.train_ohlc['close'], sd.train_ohlc['open'], .001,\
                short_length=13, long_length=36, take_profit=.01, stop_loss=-.01, capital=20000)
operaciones_prueba= proceso_prueba[2]
rend_operacion_prueba = proceso_prueba[3]
rendimiento_prueba = proceso_prueba[4]
flujo_prueba = proceso_prueba[5]<jupyter_output><empty_output><jupyter_text>Este es un DataFrame con los rendimientos obtenidos por algunas operaciones de la prueba.<jupyter_code>pd.DataFrame(rendimiento_prueba).head()<jupyter_output><empty_output><jupyter_text>Y así se movió el flujo durante el periodo de entrenamiento sin ninguna optimización. GRÁFICO 2<jupyter_code>plt.plot(flujo_prueba)
plt.title("Flujo capital sin optimización")
plt.xlabel("Operaciones")
plt.ylabel("Precios")
plt.show()<jupyter_output><empty_output><jupyter_text>2. Proceso    Lo que se busca optimizar con este código es el rendimiento final, la intención es maximizarlo, por lo que el dato que tenga un mayor flujo al final del periodo, será considerado el óptimo.Los parámetros a optimizar son los siguientes:Parámetro: 1Nombre: Longitud de EMA cortaDescripción: Longitud del promedio móvil exponencial corto, que cruzando hacia arriba nos dará señal de compra.Tipo de valor: numéricoRango de valores: 1 - 15Tamaño de paso mínimo: 1Parámetro: 2Nombre: Longitud de EMA largoDescripción: Longitud del promedio móvil exponencial larfo, que cruzando hacia abajo nos dará señal de compra.Tipo de valor: numéricoRango de valores: 1 - 15Tamaño de paso mínimo: 1Parámetro: 3Nombre: Take profitDescripción: Rendimiento positivo con el que abandonamos la operación sin esperar una señal de venta.Tipo de valor: numéricoRango de valores: $2.5\%$ - $5\%$Tamaño de paso mínimo: $.5\%$Parámetro: 4Nombre: Stop lossDescripción: Rendimiento negativo con el que abandonamos la operación sin esperar una señal de venta.Tipo de valor: numéricoRango de valores: $-.5\%$ - $-2.5\%$Tamaño de paso mínimo: $-.5\%$  El rendimiento máximo obtenido fue de:<jupyter_code>so.rend_max<jupyter_output><empty_output><jupyter_text>Y los parámetros fueron los siguientes:Short length : 1Long length : 17Take profit : $3\%$Stop loss : $-2\%$<jupyter_code>so.parametros<jupyter_output><empty_output><jupyter_text>Se obtienen flujos y rendimientos del periodo de entrenamiento pero ahora con los parámetros óptimos<jupyter_code>proceso_train = sd.proceso_completo(sd.data_ohlc['close'], sd.data_ohlc['open'], .001,\
                short_length=so.parametros[0], long_length=so.parametros[1],\
                take_profit=so.parametros[2], stop_loss=so.parametros[3], capital=20000)
operaciones_train= proceso_train[2]
rend_operacion_train = proceso_train[3]
rendimiento_train = proceso_train[4]
flujo_train = proceso_train[5]<jupyter_output><empty_output><jupyter_text>Movimiento del capital en el periodo. Gráfico 3<jupyter_code>plt.plot(flujo_train)
plt.title("Flujo capital periodo entrenamiento")
plt.xlabel("Operaciones")
plt.ylabel("Precios")
plt.show()<jupyter_output><empty_output><jupyter_text>Pips de la divisa con la que se está trabajando.<jupyter_code>fn.f_pip_size("btc/USD")<jupyter_output><empty_output><jupyter_text>Duración de cada operación en el periodo.<jupyter_code>columnas_tiempos = fn.columnas_tiempos(rend_individual = rend_operacion_train, operaciones=operaciones_train, \
                    take_profit = so.parametros[2], stop_loss = so.parametros[3])
columnas_tiempos.head()<jupyter_output><empty_output><jupyter_text>Profit y pips del periodo, así como la suma acumulada de los mismos, podemos ver que al final del periodo el valor acumulado es positivo.<jupyter_code>columnas_pips = fn.f_columnas_pips(pips = fn.f_pip_size("btc/USD"), rendimiento=rendimiento_train)
columnas_pips.head()<jupyter_output><empty_output><jupyter_text>Estadísticas sobre las operaciones realizadas en el periodo.<jupyter_code>fn.f_estadísticas_ba(rendimiento_train, operaciones_train, "df_1_tabla")<jupyter_output><empty_output><jupyter_text>Estadísticas sobre los días con mejor rendimiento de operaciones positivas.<jupyter_code>fn.f_estadísticas_ba(rendimiento_train, operaciones_train, "df_2_ranking")<jupyter_output><empty_output><jupyter_text>Evolución del capital durante el periodo, es el gráfico 3 desglozado.<jupyter_code>evolucion_capital = fn.f_evolucion_capital(sd.train_ohlc['close'], operaciones_train, rend_operacion_train,\
                                     take_profit=so.parametros[2], stop_loss=so.parametros[3],\
                                        capital =20000, rendimiento= rendimiento_train)
evolucion_capital.tail()<jupyter_output><empty_output><jupyter_text>Se calculó:Sharpe Ratio = $\frac{Rend - R_f}{\sigma Rend}$Drawdown = Máxima minusvalía registrada durante el periodo.Drawup = Máxima plusvalía registrada durante el periodo.Con estos elementos nos podemos dar cuenta si el riesgo valió la pena.<jupyter_code>fn.f_estadisticas_mad(evolucion_capital)<jupyter_output><empty_output><jupyter_text>A continuación se realizará exactamente el mismo proceso, ahora en los periodos de validación y prueba, al final se dará una conclusión<jupyter_code>proceso_val = sd.proceso_completo(sd.val_ohlc['close'], sd.val_ohlc['open'], .001,\
                short_length=so.parametros[0], long_length=so.parametros[1],\
                take_profit=so.parametros[2], stop_loss=so.parametros[3], capital=20000)
operaciones_val= proceso_val[2]
rend_operacion_val = proceso_val[3]
rendimiento_val = proceso_val[4]
flujo_val = proceso_val[5]<jupyter_output><empty_output><jupyter_text>Gráfico 4<jupyter_code>plt.plot(flujo_val)
plt.title("Flujo capital periodo validación")
plt.xlabel("Operaciones")
plt.ylabel("Precios")
plt.show()
columnas_tiempos = fn.columnas_tiempos(rend_individual = rend_operacion_val, operaciones=operaciones_val, \
                    take_profit = so.parametros[2], stop_loss = so.parametros[3])
columnas_tiempos.head()
columnas_pips = fn.f_columnas_pips(pips = fn.f_pip_size("btc/USD"), rendimiento=rendimiento_val)
columnas_pips.head()
evolucion_capital = fn.f_evolucion_capital(sd.val_ohlc['close'], operaciones_val, rend_operacion_val,\
                                     take_profit=so.parametros[2], stop_loss=so.parametros[3],\
                                        capital =20000, rendimiento= rendimiento_val)
evolucion_capital.tail()
fn.f_estadisticas_mad(evolucion_capital)
proceso_test = sd.proceso_completo(sd.test_ohlc['close'], sd.test_ohlc['open'], .001,\
                short_length=so.parametros[0], long_length=so.parametros[1],\
                take_profit=so.parametros[2], stop_loss=so.parametros[3], capital=20000)
operaciones_test= proceso_test[2]
rend_operacion_test = proceso_test[3]
rendimiento_test = proceso_test[4]
flujo_test = proceso_test[5]<jupyter_output><empty_output><jupyter_text>Gráfico 5<jupyter_code>plt.plot(flujo_test)
plt.title("Flujo capital periodo prueba")
plt.xlabel("Operaciones")
plt.ylabel("Precios")
plt.show()
columnas_tiempos = fn.columnas_tiempos(rend_individual = rend_operacion_test, operaciones=operaciones_test, \
                    take_profit = so.parametros[2], stop_loss = so.parametros[3])
columnas_tiempos.head()
columnas_pips = fn.f_columnas_pips(pips = fn.f_pip_size("btc/USD"), rendimiento=rendimiento_test)
columnas_pips.head()
fn.f_estadísticas_ba(rendimiento_test, operaciones_test, "df_1_tabla")
fn.f_estadísticas_ba(rendimiento_test, operaciones_test, "df_2_ranking")
evolucion_capital = fn.f_evolucion_capital(sd.test_ohlc['close'], operaciones_test, rend_operacion_test,\
                                     take_profit=so.parametros[2], stop_loss=so.parametros[3],\
                                        capital =20000, rendimiento= rendimiento_test)
evolucion_capital.tail()
fn.f_estadisticas_mad(evolucion_capital)<jupyter_output><empty_output><jupyter_text>Número de iteraciones que se realizaron en la optimizacón.<jupyter_code>fn.metrica_optimizacion(range(1,15), range(15,30), np.arange(.025,.055,.005), np.arange(-.005,-.03,-.005))<jupyter_output><empty_output><jupyter_text>Tiempo que tardó en correr el código.<jupyter_code>print("El código tarda en correr", (time.time() - inicio)/60, "minutos" )<jupyter_output>El código tarda en correr 5.303676931063334 minutos
{'fraction_non_alphanumeric': 0.0894522408329561, 'fraction_numerical': 0.021729289271163424, 'mean_word_length': 5.463428905792862, 'pattern_counts': {'":': 0, '<': 85, '<?xml version=': 0, '>': 85, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '21', 'dir': 'jupyter-structured-clean-dedup', 'id': '606139', 'license': 'MIT', 'n_tokens_mistral': 4093, 'n_tokens_neox': 3881, 'n_words': 931, 'path': 'notebook.ipynb', 'repo_name': 'LuisCarlosAlvarado/myst_lab2_lcag', 'size': '11064'}