Hi all,
Can anyone help provide with a potential cleaner/simpler MA crossover strategy code with Python? I'm also trying to figure out how to get the stock performance to plot along with the equity curve in one. Thank you for your help.
import pandas_datareader as pdr
import pandas as pd
import datetime
import numpy as np
import matplotlib.pyplot as plt
def get(tickers, startdate, enddate):
def data(ticker):
return (pdr.get_data_yahoo(ticker, start=startdate, end=enddate))
datas = map (data, tickers)
return(pd.concat(datas, keys=tickers, names=['Ticker', 'Date']))
tickers = ['XIV', 'MSFT', 'IBM', 'GOOG']
all_data = get(tickers, datetime.datetime(2006, 10, 1), datetime.datetime(2017, 10, 27))
aapl = pdr.get_data_yahoo('XIV',
start=datetime.datetime(2006, 10, 1),
end=datetime.datetime(2017, 10, 27))
Initialize the short and long windows
short_window = 50
long_window = 100
Initialize the signals
DataFrame with the signal
column
signals = pd.DataFrame(index=aapl.index)
signals['signal'] = 0.0
Create short simple moving average over the short window
signals['short_mavg'] = aapl['Close'].rolling(window=short_window, min_periods=1, center=False).mean()
Create long simple moving average over the long window
signals['long_mavg'] = aapl['Close'].rolling(window=long_window, min_periods=1, center=False).mean()
Create signals
signals['signal'][short_window:] = np.where(signals['short_mavg'][short_window:]
> signals['long_mavg'][short_window:], 1.0, 0.0)
Generate trading orders
signals['positions'] = signals['signal'].diff()
Initialize the plot figure
fig = plt.figure()
Add a subplot and label for y-axis
ax1 = fig.add_subplot(111, ylabel='Price in $')
Plot the closing price
aapl['Close'].plot(ax=ax1, color='r', lw=2.)
Plot the short and long moving averages
signals[['short_mavg', 'long_mavg']].plot(ax=ax1, lw=2.)
Plot the buy signals
ax1.plot(signals.loc[signals.positions == 1.0].index,
signals.short_mavg[signals.positions == 1.0],
'^', markersize=10, color='m')
Plot the sell signals
ax1.plot(signals.loc[signals.positions == -1.0].index,
signals.short_mavg[signals.positions == -1.0],
'v', markersize=10, color='k')
Set the initial capital
initial_capital= float(100000.0)
Create a DataFrame positions
positions = pd.DataFrame(index=signals.index).fillna(0.0)
Buy a 1000 shares
positions['AAPL'] = 1000*signals['signal']
Initialize the portfolio with value owned
portfolio = positions.multiply(aapl['Adj Close'], axis=0)
Store the difference in shares owned
pos_diff = positions.diff()
Add holdings
to portfolio
portfolio['holdings'] = (positions.multiply(aapl['Adj Close'], axis=0)).sum(axis=1)
Add cash
to portfolio
portfolio['cash'] = initial_capital - (pos_diff.multiply(aapl['Adj Close'], axis=0)).sum(axis=1).cumsum()
Add total
to portfolio
portfolio['total'] = portfolio['cash'] + portfolio['holdings']
Add returns
to portfolio
portfolio['returns'] = portfolio['total'].pct_change()
Create a figure
fig = plt.figure()
ax1 = fig.add_subplot(111, ylabel='Portfolio value in $')
Plot the equity curve in dollars
portfolio['total'].plot(ax=ax1, lw=2.)
ax1.plot(portfolio.loc[signals.positions == 1.0].index,
portfolio.total[signals.positions == 1.0],
'^', markersize=10, color='m')
ax1.plot(portfolio.loc[signals.positions == -1.0].index,
portfolio.total[signals.positions == -1.0],
'v', markersize=10, color='k')
Show the plot
plt.tight_layout()
plt.show()
Isolate the returns of your strategy
returns = portfolio['returns']
annualized Sharpe ratio
sharpe_ratio = np.sqrt(252) * (returns.mean() / returns.std())
Print the Sharpe ratio
print(sharpe_ratio)
Define a trailing 252 trading day window
window = 252
Calculate the max drawdown in the past window days for each day
rolling_max = aapl['Adj Close'].rolling(window, min_periods=1).max()
daily_drawdown = aapl['Adj Close']/rolling_max - 1.0
Calculate the minimum (negative) daily drawdown
max_daily_drawdown = daily_drawdown.rolling(window, min_periods=1).min()
Plot the results
daily_drawdown.plot()
max_daily_drawdown.plot()
Show the plot
plt.show()