-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSPYtrading_main
95 lines (73 loc) · 3.56 KB
/
SPYtrading_main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import matplotlib
matplotlib.use('Agg') # Set the backend to Agg for non-interactive plotting
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# List of S&P 500 component stocks (for demonstration purposes)
sp500_tickers = pd.read_html("https://en.wikipedia.org/wiki/List_of_S%26P_500_companies")
sp500_tickers = sp500_tickers[0] #take just the first table from the webpage
# Initialize capital and equity curve list
initial_capital = 1_000_000
capital = initial_capital
equity_curve = [] # To store portfolio value over time
# Define trading parameters
rsi_buy_threshold = 35
rsi_sell_threshold = 55
rsi_short_threshold = 75
investment_percentage = 0.005 # Use 0.5% of capital
# Function to calculate RSI
def calculate_rsi(prices, period=14):
delta = prices.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
# Iterate through each stock in the S&P 500
for ticker in sp500_tickers:
print(f"Processing {ticker}...")
# Fetch historical market data for each stock (5 years)
stock_data = yf.Ticker(ticker).history(period="5y")
# Calculate RSI and add it to the DataFrame
stock_data['RSI'] = calculate_rsi(stock_data['Close'])
position_size = 0
for i in range(len(stock_data)):
current_rsi = stock_data['RSI'].iloc[i]
current_price = stock_data['Close'].iloc[i]
# Buy condition (RSI <= 35)
if current_rsi <= rsi_buy_threshold and position_size == 0:
position_size = (capital * investment_percentage) / current_price
capital -= position_size * current_price
print(f"Buying {position_size:.2f} shares of {ticker} at {current_price:.2f}")
# Sell condition (RSI >= 55) when holding a position
elif current_rsi >= rsi_sell_threshold and position_size > 0:
capital += position_size * current_price
print(f"Selling {position_size:.2f} shares of {ticker} at {current_price:.2f}")
position_size = 0
# Short condition (RSI >= 75)
elif current_rsi >= rsi_short_threshold and position_size == 0:
position_size = -(capital * investment_percentage) / current_price
capital += -position_size * current_price
print(f"Shorting {abs(position_size):.2f} shares of {ticker} at {current_price:.2f}")
# Cover condition (RSI <= 55) when holding a short position
elif current_rsi <= rsi_sell_threshold and position_size < 0:
capital += abs(position_size) * current_price
print(f"Covers {abs(position_size):.2f} shares of {ticker} at {current_price:.2f}")
position_size = 0
# Append the current portfolio value to equity_curve list
equity_curve.append(capital + (position_size * current_price if position_size != 0 else 0))
# Final capital after trading across all stocks
final_capital = capital + (position_size * stock_data['Close'].iloc[-1] if position_size != 0 else 0)
print(f"Final Capital after trading all stocks: ${final_capital:.2f}")
# Step for Visualization of the equity curve
# Create a plot for the equity curve over time
plt.figure(figsize=(14, 7))
plt.plot(equity_curve, label='Portfolio Equity Curve', color='blue')
plt.title('Portfolio Equity Curve Over Time')
plt.xlabel('Time (Days)')
plt.ylabel('Equity ($)')
plt.legend()
plt.grid()
# Save the plot as an image file instead of displaying it interactively.
plt.savefig("portfolio_equity_curve.png")