Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
AI4Finance-Foundation
GitHub Repository: AI4Finance-Foundation/FinRL
Path: blob/master/examples/Stock_NeurIPS2018_1_Data.ipynb
726 views
Kernel: Python 3

Stock NeurIPS2018 Part 1. Data

This series is a reproduction of paper the process in the paper Practical Deep Reinforcement Learning Approach for Stock Trading.

This is the first part of the NeurIPS2018 series, introducing how to use FinRL to fetch and process data that we need for ML/RL trading.

Other demos can be found at the repo of FinRL-Tutorials.

Part 1. Install Packages

## install finrl library !pip install git+https://github.com/AI4Finance-Foundation/FinRL.git
import pandas as pd import yfinance as yf from finrl.meta.preprocessor.yahoodownloader import YahooDownloader from finrl.meta.preprocessor.preprocessors import FeatureEngineer, data_split from finrl import config_tickers from finrl.config import INDICATORS from finrl.config import * import itertools

Part 2. Fetch data

yfinance is an open-source library that provides APIs fetching historical data form Yahoo Finance. In FinRL, we have a class called YahooDownloader that use yfinance to fetch data from Yahoo Finance.

OHLCV: Data downloaded are in the form of OHLCV, corresponding to open, high, low, close, volume, respectively. OHLCV is important because they contain most of numerical information of a stock in time series. From OHLCV, traders can get further judgement and prediction like the momentum, people's interest, market trends, etc.

Data for a single ticker

Here we provide two ways to fetch data with single ticker, let's take Apple Inc. (AAPL) as an example.

Using yfinance

TRAIN_START_DATE = '2020-01-01' TRADE_END_DATE = '2020-01-31' aapl_df_yf = yf.download(tickers = "aapl", start=TRAIN_START_DATE, end=TRADE_END_DATE)
[*********************100%***********************] 1 of 1 completed
aapl_df_yf.head()

Using FinRL

In FinRL's YahooDownloader, we modified the data frame to the form that convenient for further data processing process. We use adjusted close price instead of close price, and add a column representing the day of a week (0-4 corresponding to Monday-Friday).

aapl_df_finrl = YahooDownloader(start_date = TRAIN_START_DATE, end_date = TRAIN_END_DATE, ticker_list = ['aapl']).fetch_data()
[*********************100%***********************] 1 of 1 completed Shape of DataFrame: (20, 8)
aapl_df_finrl.head()

Data for the chosen tickers

config_tickers.DOW_30_TICKER
['AXP', 'AMGN', 'AAPL', 'BA', 'CAT', 'CSCO', 'CVX', 'GS', 'HD', 'HON', 'IBM', 'INTC', 'JNJ', 'KO', 'JPM', 'MCD', 'MMM', 'MRK', 'MSFT', 'NKE', 'PG', 'TRV', 'UNH', 'CRM', 'VZ', 'V', 'WBA', 'WMT', 'DIS', 'DOW']
TRAIN_START_DATE = '2009-01-01' TRAIN_END_DATE = '2020-07-01' TRADE_START_DATE = '2020-07-01' TRADE_END_DATE = '2021-10-29'
df_raw = YahooDownloader(start_date = TRAIN_START_DATE, end_date = TRADE_END_DATE, ticker_list = config_tickers.DOW_30_TICKER).fetch_data()
[*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed [*********************100%***********************] 1 of 1 completed Shape of DataFrame: (94301, 8)
df_raw.head()

Part 3: Preprocess Data

We need to check for missing data and do feature engineering to convert the data point into a state.

  • Adding technical indicators. In practical trading, various information needs to be taken into account, such as historical prices, current holding shares, technical indicators, etc. Here, we demonstrate two trend-following technical indicators: MACD and RSI.

  • Adding turbulence index. Risk-aversion reflects whether an investor prefers to protect the capital. It also influences one's trading strategy when facing different market volatility level. To control the risk in a worst-case scenario, such as financial crisis of 2007–2008, FinRL employs the turbulence index that measures extreme fluctuation of asset price.

Hear let's take MACD as an example. Moving average convergence/divergence (MACD) is one of the most commonly used indicator showing bull and bear market. Its calculation is based on EMA (Exponential Moving Average indicator, measuring trend direction over a period of time.)

fe = FeatureEngineer(use_technical_indicator=True, tech_indicator_list = INDICATORS, use_vix=True, use_turbulence=True, user_defined_feature = False) processed = fe.preprocess_data(df_raw)
Successfully added technical indicators [*********************100%***********************] 1 of 1 completed Shape of DataFrame: (3228, 8) Successfully added vix Successfully added turbulence index
list_ticker = processed["tic"].unique().tolist() list_date = list(pd.date_range(processed['date'].min(),processed['date'].max()).astype(str)) combination = list(itertools.product(list_date,list_ticker)) processed_full = pd.DataFrame(combination,columns=["date","tic"]).merge(processed,on=["date","tic"],how="left") processed_full = processed_full[processed_full['date'].isin(processed['date'])] processed_full = processed_full.sort_values(['date','tic']) processed_full = processed_full.fillna(0)
processed_full.head()

Part 4: Save the Data

Split the data for training and trading

train = data_split(processed_full, TRAIN_START_DATE,TRAIN_END_DATE) trade = data_split(processed_full, TRADE_START_DATE,TRADE_END_DATE) print(len(train)) print(len(trade))
83897 9715

Save data to csv file

For Colab users, you can open the virtual directory in colab and manually download the files.

For users running on your local environment, the csv files should be at the same directory of this notebook.

train.to_csv('train_data.csv') trade.to_csv('trade_data.csv')