# Importamos librerías
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pandas_datareader import data
%matplotlib inline

# Descargamos datos...
# Instrumento: Apple
ticker = ['AAPL']
# Fuente: Yahoo Finance
data_source = 'yahoo'
# Fechas de interés (inicio y fin): 2016
start_date = '2016-01-04'
end_date = '2016-12-31'
# Función DataReader
panel_data = data.DataReader(ticker, data_source, start_date, end_date)

# Solo nos interesa los precios de cierre ajustados...
closes = panel_data.loc['Adj Close']
# Generamos todos los días del 2016 en orden
all_weekdays = pd.date_range(start_date, end_date)
# Reindizamos
closes = closes.reindex(all_weekdays)
# Llenamos huecos en los precios de cierre
closes = closes.fillna(method='ffill')

# Graficamos
closes.plot(figsize=(8,6));

"""
Explanation: Aplicando Python para análisis de precios: simulación de escenarios futuros de precios
<img style="float: right; margin: 0px 0px 15px 15px;" src="https://upload.wikimedia.org/wikipedia/commons/d/d7/Philippine-stock-market-board.jpg" width="400px" height="125px" />

En la clase anterior vimos como importar datos de activos de la base de datos de Yahoo Finance, tanto descargándolos como archivos separados por comas (.csv), como usando el paquete pandas-datareader. En esta clase, veremos como pronosticar escenarios de evolución de precios, suponiendo que los rendimientos diarios se distribuyen normalmente.

Referencias:
- http://pandas.pydata.org/
- http://www.learndatasci.com/python-finance-part-yahoo-finance-api-pandas-matplotlib/
1. Motivación
Hace menos de una década, los instrumentos financieros estaban en la cúspide de la popularidad. Las instituciones financieras de todo el mundo estaban negociando miles de millones de dólares de estos instrumentos a diario, y los analistas cuantitativos estaban modelándolos utilizando el cálculo estocástico y el poderoso C++.
Sin embargo, el avance en los últimos años ha sido impresionante y las cosas han cambiado. Por una parte, la crisis financiera del 2008 fue producida por los instrumentos financieros llamados derivados. Por otra parte, los volúmenes transaccionales han bajado y la demanda de modelado con C++ se ha marchitado con ellos. Además, un nuevo jugador entró en la competencia... ¡Python!
Python ha estado ganando muchos seguidores en la industria financiera en los últimos años y con razón. No en vano, junto a R son los lenguajes de programación más utilizados en cuanto a análisis financiero.
2. Recordemos como descargar datos...
Antes que nada, para poder hacer simular escenarios de predicción de precios, vamos a recordar lo que hicimos en la clase pasada de descargar los datos de Yahoo Finance, utilizando el paquete data de la librería pandas_datareader.
Esta vez, utilizaremos los datos de precios de cierre ajustados de activos de la compañía Apple en el año 2016 para nuestra aplicación.
End of explanation
"""


# Función para calcular los rendimientos diarios a partir de los precios de cierre...
def calc_daily_returns(closes):
    return np.log(closes/closes.shift(1))[1:]

# Calcular rendimientos diarios y graficarlos
daily_returns = calc_daily_returns(closes)
daily_returns.plot(figsize=(8,6));

"""
Explanation: 3. Rendimientos diarios
Los rendimientos diarios se pueden calcular con los precios de cierre de la siguiente manera:
$$r_i=\frac{p_i-p_{i-1}}{p_{i-1}},$$
donde $r_i$ es el rendimiento en el día $i$ y $p_i$ es el precio de cierre ajustado en el día $i$.
Ver en el pizarrón: aproximación con logaritmo, además mencionar validez estadística suponiendo distribución lognormal.
Entonces, los rendimientos diarios se pueden calcular como:
End of explanation
"""


mu=daily_returns.mean().AAPL
sigma=daily_returns.std().AAPL
mu, sigma

"""
Explanation: Entonces, suponemos que la diferencia logaritmica de los precios (rendimientos diarios) tiene una distribución normal.
¿Cómo se caracteriza una distribución normal?
End of explanation
"""


help(np.random.randn)

"""
Explanation: 4. Simulación de varios escenarios
Habiendo caracterizado los rendimientos diarios como una variable aleatoria normal con la media y la varianza muestral obtenida de los datos del 2016, podemos generar números aleatorios con estas características para simular el comportamiento de los precios de las acciones en el 2017.
Sin embargo, cada simulación que hagamos nos conducirá a distintos resultados (los precios siguen evolucionando aleatoriamente). Entonces, lo que haremos es simular varios escenarios para así ver alguna tendencia y tomar decisiones (próxima clase).
Pero, ¿cómo generar vectores de números aleatorios que distribuyen normalmente con una media y varianza dadas?
End of explanation
"""


ndays = 360
ntraj=10
dates=pd.date_range('20170101',periods=ndays)
simret = pd.DataFrame(sigma*np.random.randn(ndays,ntraj)+mu,index=dates)
simret

"""
Explanation: Generamos un data frame de rendimientos diarios proyectados (10 trayectorias)
End of explanation
"""


simdata=(closes.loc['2016-12-30',:].AAPL)*np.exp(simret.cumsum())
simdata

"""
Explanation: Con los rendimientos, calculamos los precios de cierre... (explicar en el tablero)
End of explanation
"""


simul=pd.concat([closes.T, simdata.T]).T
simul.plot(figsize=(8,6),legend=False);

"""
Explanation: Concatenamos y graficamos...
End of explanation
"""


