import yfinance as yf
import matplotlib.pyplot as plt
import datetime as dt
import numpy as np
import pandas as pd
class MovingAverageRSIStrategy:
def __init__(self, capital, stock, start, end, short_period, long_period):
self.data = None
self.is_long = False
self.short_period = short_period
self.long_period = long_period
self.capital = capital
self.equity = [capital]
self.stock = stock
self.start = start
self.end = end
def download_data(self):
stock_data = {}
ticker = yf.download(self.stock, self.start, self.end)
stock_data['Price'] = ticker['Adj Close']
self.data = pd.DataFrame(stock_data)
def construct_signals(self):
self.data['Short_MA'] = self.data['Price'].ewm(span=self.short_period).mean()
self.data['Long_MA'] = self.data['Price'].ewm(span=self.long_period).mean()
self.data['Move'] = self.data['Price'] - self.data['Price'].shift(1)
self.data['Up'] = np.where(self.data['Move'] > 0, self.data['Move'], 0)
self.data['Down'] = np.where(self.data['Move'] < 0, self.data['Move'], 0)
self.data['Average_Gain'] = self.data['Up'].rolling(14).mean()
self.data['Average_Loss'] = self.data['Down'].abs().rolling(14).mean()
relative_strength = self.data['Average_Gain'] / self.data['Average_Loss']
self.data['RSI'] = 100.0 - (100.0 / (1.0 + relative_strength))
self.data = self.data.dropna()
def plot_signals(self):
plt.figure(figsize=(12, 6))
plt.plot(self.data['Price'], label='Stock Price')
plt.plot(self.data['Short_MA'], label='Short MA', color='blue')
plt.plot(self.data['Long_MA'], label='Long MA', color='green')
plt.title('Moving Average (MA) Crossover Trading Strategy With RSI')
plt.xlabel('Date')
plt.ylabel('Stock Price')
plt.show()
def simulate(self):
price_when_buy = 0
for index, row in self.data.iterrows():
if row['Short_MA'] < row['Long_MA'] and self.is_long:
self.equity.append(self.capital * row.Price / price_when_buy)
self.is_long = False
elif row['Short_MA'] > row['Long_MA'] and not self.is_long
and row['RSI'] < 30:
price_when_buy = row['Price']
self.is_long = True
def plot_equity(self):
plt.figure(figsize=(12, 6))
plt.title('Equity Curve')
plt.plot(self.equity, label='Stock Price', color='green')
plt.xlabel('Date')
plt.ylabel('Capital ($)')
plt.show()
def show_stats(self):
print("Profit Of The Trading Strategy: %.2f%%" % (
(float(self.equity[-1]) - float(self.equity[0])) /
float(self.equity[0]) * 100))
print("Actual Capital: %0.2f" % self.equity[-1])
returns = (self.data['Price'] - self.data['Price'].shift(1)) / self.data['Price'].shift(1)
ratio = returns.mean() / returns.std() * np.sqrt(252)
print('Sharpe Ratio: %.2f' % ratio)
if __name__ == '__main__':
start_date = dt.datetime(2010, 1, 1)
end_date = dt.datetime(2020, 1, 1)
model = MovingAverageRSIStrategy(100, 'IBM', start_date, end_date, 40, 150)
model.download_data()
model.construct_signals()
model.plot_signals()
model.simulate()
model.plot_equity()
model.show_stats()