Predecir el precio de una acción de la bolsa de valores

En este proyecto vamos a desarrollar un programa para predecir el precio de una acción de la bolsa de valores de Nueva York. Para este programa te voy a llevar paso a paso, desde recolectar la data, construir el modelo y realizar la predicción, entonces empecemos con el desarrollo.

Lo primero que debemos realizar es importar las librerías que vamos a utilizar. Adicionalmente importamos pandas datareader. Esta seguramente es una nueva librería para ti, y se encarga de permitirnos un acceso remoto a páginas web en donde podemos encontrar los datos relacionas a las bolsas de valores de todo el mundo. Para nuestro análisis vamos a utilizar la pagina de Morningstar, que es especializada en esta área. A su vez vamos a importar la librería de datetime, ésta como su nombre lo indica, maneja el día y la hora y lo vamos a utilizar para obtener los datos.

#Se importan la librerias a utilizar
import pandas as pd
import numpy as np
import pandas_datareader.data as web
import datetime

Entonces empecemos a obtener los datos que vamos a utilizar para construir el modelo. Lo primero que debemos hacer es definir el periodo de tiempo que vamos utilizar. Este tiempo lo definimos nosotros y podemos cambiarlo a medida que avancemos en el desarrollo, en caso de que necesitemos más datos para construir nuestro modelo.

Para este análisis vamos a recolectar datos desde el primero de enero de 2013 hasta el día de hoy, para definir estas fechas utilizamos la librería datetime, que la importamos al principio.

#Se define el periodo periodo de tiempo a utilizar
start = datetime.datetime(2013, 1, 1)
end = datetime.date.today()

Definido estos intervalos procedamos ahora de definir la acción, para ello utilizamos la variable predict_stock en donde guardaremos el código de la acción, en este caso utilizaremos la acción de Netflix que el código vendría siendo NFLX. Recuerda acá que el código que coloquemos deberá ser exactamente el mismo con el que se cotice en la bolsa de valores porque de lo contraría al momento de correr nuestro programa nos dará un error, entonces te recomiendo que te fijes bien el código que coloques acá.

#Esta será la variable que se cambiará para colocar la acción que se quiera evaluar
predict_stock = 'NFLX'

En este momento ya tenemos definidos el periodo de tiempo y la acción que vamos a predecir, ahora procedemos a obtener los datos, para ello utilizamos la librería DataReader. Recuerda que para utilizar esta librería deberas instalarla en tu computador utilizando pip.

#Se obtiene la data de la página de morningstar
df = web.DataReader(predict_stock, "morningstar", start, end)

Obtenido los datos, ahora procedemos a guardarlo en un archivo en nuestro computador para que los tengamos disponibles sin necesidad estar leyendo constantemente la página.

#Se guarda la data en un archivo .csv
df.to_csv('predict_stock.csv')

#Lectura del archivo .csv para manipular la data
df = pd.read_csv('predict_stock.csv', parse_dates = True, index_col = 1) #analiza la columna 1 como fechas

En este momento tenemos que definir qué datos vamos a utilizar, por ejemplo tenemos dos columnas en donde se muestra los precios más altos y bajos obtenidos durante el día, por que lo que con estos puedo calcular un promedio, simplemente tomo estas dos columnas High y Low y realizo el calculo respectivo, de esta forma se crea una nueva columna llamada «HL».

Adicionalmente, tengo los datos del precio al momento que abrió y cerró la bolsa, por lo que también puedo crear una nueva columna llamada «Change» en donde guardo el promedio de los cambios durante el día.

#Calculo el porcentaje del promedio de cambios durante el día
df['HL'] = (df['High'] - df['Low']) / df['Low'] * 100.0
df['Change'] = (df['Close'] - df['Open']) / df['Open'] * 100.0

Creadas estas nuevas columnas ya puedo definir un nuevo dataset seleccionando las que voy utilizar para construir el modelo que sería la columna de Close, que sería el precio de la acción al momento del cierre de la bolsa, HL, que es el promedio entre los precios altos y bajos del día, Change, que es el promedio de los cambios del día y por el último Volume que es el volumen de transacciones. Estos serían todos los datos que utilizaremos, el resto los desechamos.

#Selecciono solo los datos que voy a utilizar en el análisis
df = df[['Close', 'HL', 'Change', 'Volume']]

En cuanto al preprocesamiento no tenemos que hacer mucho ya que estos datos datos son reales y se recolectan automáticamente durante los días que se encuentra la bolsa de valores, pero por si acaso que haya algún valor faltante o NAN se rellena con 99.999 para evitar algún error, para ello utilizamos fillna.

#En caso que alguna data no se encuentre NAN se rellena con el valor 99999
df.fillna(value=-99999, inplace=True)

Ahora si empecemos a construir el modelo, por lo que procedemos a importar las librerías. Vamos a utilizar scikit-learn y exportamos los algoritmos de Regresión Lineal y Vectores de Soporte para Regresión, recuerda que queremos predecir un valor por lo que este proyecto debemos utilizar algoritmos de regresión.

from sklearn import preprocessing, svm
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split

Si refrescamos un poco la memoria con los principios básicos del aprendizaje supervisado, para desarrollar el modelo se necesita los datos de entrada que serían “X” y los datos con las etiquetas o respuestas de ellos, que vendrían siendo “y”. Sabiendo esto, debemos separar esta información de nuestro dataset, en este caso las respuestas estarían en la columna “Close”, por lo que creamos una variable llamada data_etiqueta con este nombre.

#Se define la columna con las etiquetas o respuestas
data_etiquetada = 'Close'

Ahora bien, el proyecto se trata de predecir el precio de una acción, si llevamos esto a la practica lo que queremos hacer es predecir el precio con que va a cerrar la acción el día de hoy, por lo que el pronostico o datos que voy proyectar sería de un día. Esta variable la defino como número por eso la declaro como integer.

#Se define el número de datos a predecir
pronostico = int(1)

Ahora si, creo una nueva columna llamada Pronostico con la información que vamos utilizar para predecir el valor. Esta columna se forma con la variable que declaramos anteriormente en “data_etiquetada” pero desplazamos los datos por la cantidad de días que queremos proyectar, en este caso será uno.

#Se crea una nueva columna con el pronostico de la data
df['Pronostico'] = df[data_etiquetada].shift(-pronostico)

Finalizado con este paso procedemos a separar los datos con las características, “X”, y las etiquetas, “y”. Entonces para “X”, vamos a utilizar todas las columnas menos la de Pronostico, razón por la cual la desechamos.

#Se crea el conjunto de datos con las características
X = np.array(df.drop(['Pronostico'], 1))

Seguidamente utilizamos la instrucción preprocessing scale, que se encarga de estandarizar y escalar el dataset. Por lo general los datos referentes a acciones y bolsa de valores están bastante limpios y completos, pero por si acaso utilizamos esta instrucción para corregir esto.

#Se realiza el escalamiento de los datos 
X = preprocessing.scale(X)

En la variable X tenemos todas las características pero recuerda que una vez que construyamos el modelo queremos predecir un valor por lo que tenemos que separar esta data en dos una que vamos a utilizar para construir el modelo y otra para implementarlo y obtener una predicción. Como previamente creamos la variable pronostico en donde definimos la cantidad de datos a predecir, ahora utilizamos esta misma variable para hacer este separación. Al final X serán las filas hasta la penultima, ya que el valor de pronostico será igual a 1. Por su parte, creamos X_predicción que sera igual a todas las filas que desechamos en el anterior paso.

#Se elimina las filas de los datos a predecir
X = X[:-pronostico]

#Se crea una variable que contiene solamente los datos para predecir
X_prediccion = X[-pronostico:]

Ya tenemos X con las características, ahora tenemos que definir “y” con las etiquetas o respuestas. Para “y” definimos que sera igual a la columna de Pronostico, ya que acá están todos los precios con que cerro la acción, que es precisamente lo que queremos definir.

#Se crea una variable con las etiquetas o respuestas
y = np.array(df['Pronostico'])

Ahora bien, igual que anteriormente debemos eliminar las filas con los datos que queremos predecir, ya que si no hacemos esto la cantidad de datos entre “X” y “y” será distinta dando un error una vez que ejecutemos el programa. Observa que acá solamente eliminamos las filas y esas filas eliminadas no las volvemos a usar ya que eso es precisamente lo que vamos a predecir con nuestro modelo.

#Se elimina las filas de los datos a predecir
y = y[:-pronostico]

Con “X” y “y” definidos, ahora procedemos a separar los datos en entrenamiento y prueba, para ello utilizamos la instrucción train_test_split y separamos solamente el 20% del dataset para usarlo en prueba.

#Se selecciona el 20% de la data entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

En este momento ya podemos aplicar nuestros alogritmos de Machine Learning para construir el modelo.

Primero vamos a utilizar el algoritmo de vectores de soporte regresión para ver que tal funciona este algoritmo con este problema. Para esto definimos algoritmo igual a svm.SVR que es la forma que se utiliza esta instrucción.

#Tipo de analisis para el pronostico
algoritmo = svm.SVR() #Support Vector Regression.

Seguidamente entrenamos el modelo, para ello utilizamos los datos de entrenamiento que separamos anteriormente y empleamos la instrucción fit.

#Entrenamos el algoritmo
algoritmo.fit(X_train, y_train)

Ahora calculamos la confianza del modelo utilizando los datos de prueba.

#Calculamos la confianza tomando en cuanta los datos de prueba
confianza = algoritmo.score(X_test, y_test)
print('Confianza = ', confianza)

Utilizando este algoritmo nos da una confianza de 0,648 valor que no es para nada bueno.

Veamos ahora haciendo una predicción con este modelo con los datos que separamos previamente.

#Utilizando el modelo realizamos una predicción
prediccion_manana = algoritmo.predict(X_prediccion)
print(prediccion_manana)

El resultado es de 155,69.

Como podemos observar los resultados obtenidos con este algoritmo no son para nada confiables por lo que ahora vamos hacer este mismo procedimiento pero utilizando otro algoritmo de regresión, como lo es el de regresión lineal. Entonces definamos el algoritmo que será LinearRegression.

#Tipo de analisis para el pronostico
algoritmo = LinearRegression() #linear regression

Posteriormente entrenamos el algoritmo con los datos de entrenamiento que separamos previamente.

#Entrenamos el algoritmo
algoritmo.fit(X_train, y_train)

Y ahora calculamos la confianza utilizando los datos de entrenamiento.

#Calculamos la confianza tomando en cuanta los datos de prueba
confianza = algoritmo.score(X_test, y_test)
print('Confianza = ', confianza)

Como podemos observar acá la confianza es de 0,998 este valor es mucho mejor que el obtenido con el anterior algoritmo.

Ahora hagamos una predicción con los datos X_prediccion y este nuevo modelo.

#Utilizando el modelo realizamos una predicción
prediccion_manana = algoritmo.predict(X_prediccion)
print(prediccion_manana)

El resultado es de 410,098, esto lo que significa que la acción de Netflix cerrará en xxx la próxima vez que este la bolsa abierta.

Como se puede observar, claramente, es que con el algoritmo de Regresión Lineal se obtuvieron mejores resultados que con el algoritmo de Vectores de Soporte Regresión. Esto no quiere decir que este último algoritmo sea mala sino más bien que no es adecuado para este proyecto y estos datos mas nada.

Ahora bien, ¿puedes utilizar este algoritmo para predecir realmente el precio de una acción en la bolsa?, en mi opinión no, porque los precios de la bolsa se ve afectado por muchos factores externos que acá no se tomaron en cuenta, aunque este algoritmo dio una confianza muy alta se debe considerar por ejemplo noticias sobre Netflix, e inclusive noticias de otras empresas similares a ella para que una acción pueda subir o bajar.

Acá puedes encontrar un programa en donde realice un análisis sentimental para conocer el comportamiento de la bolsa, inclusive utilice como acción la de Netflix.

A continuación se encuentra el código completo:

"""
Predecir el precio de una acción de la bolsa

@author: ligdigonzalez
"""

########## LIBRERÍAS A UTILIZAR ##########

#Se importan la librerias a utilizar
import pandas as pd
import numpy as np
import pandas_datareader.data as web
import datetime
from sklearn import preprocessing, svm
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split


########## PREPARAR LA DATA ##########

#Se define el periodo periodo de tiempo a utilizar
start = datetime.datetime(2013, 1, 1)
end = datetime.date.today()

#Esta será la variable que se cambiará para colocar la acción que se quiera evaluar
predict_stock = 'NFLX'

#Se obtiene la data de la página de morningstar
df = web.DataReader(predict_stock, "morningstar", start, end)

#Se guarda la data en un archivo .csv
df.to_csv('predict_stock.csv')

#Lectura del archivo .csv para manipular la data
df = pd.read_csv('predict_stock.csv', parse_dates = True, index_col = 1) #analiza la columna 1 como fechas

#Calculo el porcentaje del promedio de cambios durante el día
df['HL'] = (df['High'] - df['Low']) / df['Low'] * 100.0
df['Change'] = (df['Close'] - df['Open']) / df['Open'] * 100.0

#Selecciono solo los datos que voy a utilizar en el análisis
df = df[['Close', 'HL', 'Change', 'Volume']]

#En caso que alguna data no se encuentre NAN se rellena con el valor 99999
df.fillna(value=-99999, inplace=True)

########## DESARROLLO DEL MODELO ##########

#Se define la columna con las etiquetas o respuestas
data_etiquetada = 'Close'

#Se define el número de datos a predecir
pronostico = int(1)

#Se crea una nueva columna con el pronostico de la data
df['Pronostico'] = df[data_etiquetada].shift(-pronostico)
print(df['Pronostico'])

#Se crea el conjunto de datos con las características
X = np.array(df.drop(['Pronostico'], 1))

#Se realiza el escalamiento de los datos 
X = preprocessing.scale(X)

#Se elimina las filas de los datos a predecir
X = X[:-pronostico]

#Se crea una variable que contiene solamente los datos para predecir
X_prediccion = X[-pronostico:]

#Se crea una variable con las etiquetas o respuestas
y = np.array(df['Pronostico'])

#Se elimina las filas de los datos a predecir
y = y[:-pronostico]

#Se selecciona el 20% de la data entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

#Tipo de analisis para el pronostico
algoritmo = svm.SVR() #Support Vector Regression.

#Entrenamos el algoritmo
algoritmo.fit(X_train, y_train)

#Calculamos la confianza tomando en cuanta los datos de prueba
confianza = algoritmo.score(X_test, y_test)
print('Confianza = ', confianza)

#Utilizando el modelo realizamos una predicción
prediccion_manana = algoritmo.predict(X_prediccion)
print(prediccion_manana)

#Tipo de analisis para el pronostico
algoritmo = LinearRegression() #linear regression

#Entrenamos el algoritmo
algoritmo.fit(X_train, y_train)

#Calculamos la confianza tomando en cuanta los datos de prueba
confianza = algoritmo.score(X_test, y_test)
print('Confianza = ', confianza)

#Utilizando el modelo realizamos una predicción
prediccion_manana = algoritmo.predict(X_prediccion)
print(prediccion_manana)

 

2 thoughts on “Predecir el precio de una acción de la bolsa de valores”

  1. Hola Ligdieli !

    Gracias nuevamente por tu trabajo !

    te queria compartir el siguiente error :

    «ModuleNotFoundError: No module named ‘pandas_datareader'»

    cabe destacar que ya instale en mi pc el «pandas-datareader», a través del «cmd» de windows :

    «$ pip install pandas-datareader»

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *