How Much Money We Can Make?#

import numpy as np
import pandas as pd
import json
import os

import sys
sys.path.append("../../")

# import our modules
import lstm
import strat
import profit

Load Data#

stocks: pd.DataFrame = pd.read_csv("../../data/stocks.csv", index_col=0, parse_dates=True)
stocks
Company Sector Open High Low Close Volume
Date
2017-11-02 AAPL Technology 41.650002 42.125000 41.320000 42.027500 165573600
2017-11-03 AAPL Technology 43.500000 43.564999 42.779999 43.125000 237594400
2017-11-06 AAPL Technology 43.092499 43.747501 42.930000 43.562500 140105200
2017-11-07 AAPL Technology 43.477501 43.812500 43.400002 43.702499 97446000
2017-11-08 AAPL Technology 43.665001 44.060001 43.582500 44.060001 97638000
... ... ... ... ... ... ... ...
2022-10-26 COP Energy 124.720001 128.179993 124.580002 126.570000 8139100
2022-10-27 COP Energy 127.699997 129.449997 126.239998 126.639999 8948500
2022-10-28 COP Energy 128.500000 128.990005 124.010002 127.169998 7293200
2022-10-31 COP Energy 125.580002 129.990005 125.570000 126.089996 7121000
2022-11-01 COP Energy 128.740005 129.320007 126.889999 127.779999 5874800

63377 rows × 7 columns

Profit Rate for Each Company#

profit_report = {}

companies: list[str] = json.load(open("../../data/companies.json", "r"))
num_days_left_out = 90
for company in companies:
    
    profit_dict = {}
    
    # select stock
    stock = stocks.query(f"Company == '{company}'").drop(columns=["Company", "Sector"])
    
    # load model
    price_predictor = lstm.load_price_predictor(os.path.join("../../models", f"{company}-3-day-predictor.pkl"))
    
    # test data
    stock_test = stock[-num_days_left_out:]
    start_date = stock_test.index[0]
    
    # decide when to buy and sell for SMA
    buy_dates, sell_dates = strat.sma(
        stock,long_period=20
    )
    
    # profit rate
    profit_rate = profit.calc_profit(stock, buy_dates, sell_dates, start_date)
    
    profit_dict["SMA"] = profit_rate
    
    # decide when to buy and sell for prediction-based strategy (LSTM)
    buy_dates, sell_dates = strat.trade_by_pred(
        stock_test, 
        price_predictor, 
        num_days_ahead=2,
    )
    
    # profit rate
    profit_rate = profit.calc_profit(stock, buy_dates, sell_dates, start_date)
    
    profit_dict["LSTM"] = profit_rate
    
    profit_report[company] = profit_dict
    
profit_report = pd.DataFrame(profit_report)
pd.options.display.float_format = "{:.2%}".format

profit_report
META TSLA XOM BAC UNH BA AAPL
SMA -19.97% 9.19% -2.80% -2.12% 0.77% 0.00% 17.77%
LSTM 9.44% 17.05% 2.06% 11.74% 0.19% 8.91% 15.18%

Note that sometimes applying SMA will lose money even though sometimes SMA has higher profit rate, e.g., UNH, AAPL.

The profit rate for LSTM is always positive for this data, which means we will always earn some money.

Total Profit#

weight = strat.determine_portfolio(stocks, companies, num_days_left_out, random_seed=7008)
profit_report.loc["Weight"] = weight
profit_report.loc["Weighted SMA"] = profit_report.loc["Weight"] * profit_report.loc["SMA"]
profit_report.loc["Weighted LSTM"] = profit_report.loc["Weight"] * profit_report.loc["LSTM"]

capital = 10000
summary = profit_report.sum(1).loc[["Weighted SMA", "Weighted LSTM"]]
pd.options.display.float_format = "{:.2f}".format
summary * capital
Weighted SMA    -336.22
Weighted LSTM    510.95
dtype: float64

We will lose $336.22 by applying SMA, while we will earn $510.95 using LSTM!