# -*- coding: utf-8 -*-
"""
Created on Sun Jan 5 11:02:36 2020
@author: Bruce1
"""
# =======================================================================
# Import Pandas Library
# =======================================================================
import pandas as pd
import pandas_datareader.data as web
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
# =======================================================================
# Setup Variables to data fetch
# =======================================================================
sym = 'AAPL'
startDate = '01/01/2000'
savedFile = Path('./{}.xlsx'.format(sym))
refreshData = False
lookback = 21
lookbackSlow = 200
lookbackEMA = 9
capital = 100000
# =======================================================================
# Gather data
# =======================================================================
if savedFile.exists() == False or refreshData == True:
print("")
print("-> Fetching data from the web")
df = web.DataReader(sym, data_source='yahoo', start=startDate)
print("")
print("-> Save data to file")
df.to_excel("{}.xlsx".format(sym))
else:
print("")
print("-> Fetching data from file")
df = pd.read_excel(savedFile, index_col='Date', parse_dates=True)
# =======================================================================
# Inspect/Report on data
# =======================================================================
firstIndex = df.index.min()
lastIndex = df.index.max()
records = len(df)
print("")
print("-> Importing ", sym)
print("First Date = ", firstIndex)
print("Last Date = ", lastIndex)
print("Total Days = ", records)
if df.isnull().values.any() == True:
print("WARNING: there are {} NaN in the data".format(df.isnull().values.sum()))
print(df.isnull().values)
# =======================================================================
# Add Indicator Columns
# =======================================================================
print("")
print("-> Add Indicator Columns")
df.loc[:,'SMA'] = df.Close.rolling(lookback).mean()
df.loc[:,'SMASlow'] = df.Close.rolling(lookbackSlow).mean()
df.loc[:,'EMA'] = df.Close.ewm(span=lookbackEMA, adjust=False).mean()
# =======================================================================
# Visualize Data
# =======================================================================
#import pdb; pdb.set_trace()
print("")
print("-> Generating Plot")
plt.figure()
df[['Close','SMA', 'SMASlow', 'EMA']].plot(kind='line')
plt.show()
plt.figure()
df['2019'][['Close','SMA', 'SMASlow', 'EMA']].plot(kind='line')
plt.show()
# =======================================================================
# Trading Rules
# =======================================================================
df.loc[:,'e1'] = (df.Close > df.SMA) & (df.Close.shift(1) < df.SMA.shift(1))
df.loc[:,'e2'] = (df.Close > df.SMASlow)
df.loc[:,'x1'] = (df.Close < df.EMA) & (df.Close.shift(1) > df.EMA.shift(1))
df.loc[:,'enterNow'] = df.e1 & df.e2
# =======================================================================
# Trading Decisions Loop
# =======================================================================
#import pdb; pdb.set_trace()
# Variables
inTrade = False
exitTrade = False
tradeList = []
#Loop through each day
for idx,row in df.iterrows():
if not inTrade:
# Enter Trade?
if row.enterNow == True:
inTrade = True
eDate = idx
ePrice = row.Close
xDate = ""
xPrice = np.NaN
else:
# Exit Trade?
if row.x1 == True:
inTrade = False
exitTrade = True
xDate = idx
xPrice = row.Close
# Record Trade
if exitTrade == True:
exitTrade = False
tradeList.append (
{'eDate' : eDate,
'ePrice' : ePrice,
'xDate' : xDate,
'xPrice' : xPrice })
tdf = pd.DataFrame(tradeList)
#import pdb; pdb.set_trace()
# =======================================================================
# Metrics
# =======================================================================
tdf.loc[:,'TradePnL'] = capital * (tdf.xPrice - tdf.ePrice) / tdf.ePrice
tdf.loc[:,'PnL'] = tdf.TradePnL.cumsum()
tdf.loc[:,'DD'] = tdf.PnL - tdf.PnL.cummax()
tdf.loc[:,'DIT'] = tdf.xDate - tdf.eDate
tRet = tdf.iloc[-1].PnL
mdd = tdf.DD.min()
winPct = len(tdf[tdf.TradePnL > 0]) / len(tdf)
dit = tdf.DIT.mean().days
startDate = tdf.iloc[0].eDate
endDate = tdf.iloc[-1].xDate
years = (endDate - startDate).days/365.25
aRet = tRet/years
print("")
print("==================================================================")
print(" Strategy Metrics for {}".format(sym))
print("==================================================================")
print(" Capital/Trade : ${:,.0f}".format(capital))
print(" Model Years : {:4.1f}".format(years))
print(" Model Trades : {}".format(len(tdf)))
print(" Max Drawdown : ${:,.0f}".format(mdd))
print(" Total Return : ${:,.0f}".format(tRet))
print(" Annual Return : ${:,.0f}".format(aRet))
print(" aRet/MDD : {:4.1f}".format(aRet/-mdd))
print(" Win Percent : {:4.1%}".format(winPct))
print(" Average DIT : {:3.0f}".format(dit))
print("")
#import pdb; pdb.set_trace()
# =======================================================================
# Plot
# =======================================================================
plt.figure()
title = "{} Returns, SMA-{}, SMASlow-{}, EMA{}".format(sym, lookback, \
lookbackSlow, lookbackEMA)
tdf[['PnL','DD']].plot(kind='line', title = title, grid=True)
plt.show()
plt.figure()
title = "{} Trade PnL Hisogram, SMA-{}, SMASlow-{}, EMA{}".format(sym, lookback, \
lookbackSlow, lookbackEMA)
tdf.TradePnL.plot(kind='hist', title = title, bins=15, grid=True)
plt.show()
# =======================================================================
# Store data
# =======================================================================
df.to_excel("{}_processed.xlsx".format(sym))
tdf.to_excel("{}_trades.xlsx".format(sym))