Skip to content

Commit 1c20cee

Browse files
authored
Create RSI_for_investing.py
Moving strategies
1 parent 2762484 commit 1c20cee

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

Strategies/RSI_for_investing.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
### AI generated from Faber, Meb, Relative Strength Strategies for Investing (April 1, 2010).
2+
### Available at SSRN: https://ssrn.com/abstract=1585517 or http://dx.doi.org/10.2139/ssrn.1585517
3+
4+
from AlgorithmImports import *
5+
6+
class MyTradingAlgorithm(QCAlgorithm):
7+
def Initialize(self):
8+
# Set the start and end date for backtesting
9+
self.SetStartDate(2024, 1, 1)
10+
self.SetEndDate(2024, 12, 1)
11+
12+
# Set the initial cash balance
13+
self.SetCash(100000)
14+
15+
# Add the assets to trade
16+
self.symbols = [self.AddEquity("SPY", Resolution.Daily).Symbol,
17+
self.AddEquity("SLV", Resolution.Daily).Symbol,
18+
self.AddEquity("GLD", Resolution.Daily).Symbol]
19+
20+
# Set the benchmark
21+
self.SetBenchmark(self.symbols[0])
22+
23+
# Initialize risk management parameters
24+
self.stopLossPercent = 0.05
25+
self.trailingStopPercent = 0.02
26+
27+
# Initialize portfolio construction parameters
28+
self.rebalancePeriod = timedelta(30)
29+
self.nextRebalanceTime = self.Time + self.rebalancePeriod
30+
31+
# Initialize alpha model parameters
32+
self.momentumPeriod = 20
33+
self.momentumThreshold = 0.01
34+
35+
# Schedule the rebalance function
36+
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 30), self.Rebalance)
37+
38+
# Initialize a dictionary to store stop prices
39+
self.stopPrices = {}
40+
41+
def OnData(self, data):
42+
# Check if it's time to rebalance the portfolio
43+
if self.Time >= self.nextRebalanceTime:
44+
self.Rebalance()
45+
self.nextRebalanceTime = self.Time + self.rebalancePeriod
46+
47+
# Implement trailing stop loss
48+
for symbol in self.Portfolio.Keys:
49+
if symbol in self.stopPrices and symbol in data and data[symbol]:
50+
if data[symbol].Close < self.stopPrices[symbol]:
51+
self.Liquidate(symbol)
52+
else:
53+
self.stopPrices[symbol] = max(self.stopPrices[symbol], data[symbol].Close * (1 - self.trailingStopPercent))
54+
55+
def Rebalance(self):
56+
# Calculate momentum for each symbol
57+
momentumScores = {}
58+
for symbol in self.symbols:
59+
history = self.History(symbol, self.momentumPeriod, Resolution.Daily)
60+
if not history.empty:
61+
momentum = (history['close'][-1] - history['close'][0]) / history['close'][0]
62+
momentumScores[symbol] = momentum
63+
64+
# Rank symbols by momentum
65+
rankedSymbols = sorted(momentumScores, key=momentumScores.get, reverse=True)
66+
67+
# Determine the number of positions to hold
68+
numPositions = min(3, len(rankedSymbols))
69+
70+
# Calculate the target weight for each position
71+
targetWeight = 1.0 / numPositions if numPositions > 0 else 0
72+
73+
# Liquidate positions not in the top ranked symbols
74+
for symbol in self.Portfolio.Keys:
75+
if symbol not in rankedSymbols[:numPositions]:
76+
self.Liquidate(symbol)
77+
78+
# Set target weights for the top ranked symbols
79+
for symbol in rankedSymbols[:numPositions]:
80+
self.SetHoldings(symbol, targetWeight)
81+
self.stopPrices[symbol] = self.Securities[symbol].Price * (1 - self.stopLossPercent)
82+
83+
def OnOrderEvent(self, orderEvent):
84+
# Log order events for debugging
85+
self.Debug(f"Order event: {orderEvent}")
86+
87+
def OnEndOfAlgorithm(self):
88+
# Log final portfolio value
89+
self.Debug(f"Final Portfolio Value: {self.Portfolio.TotalPortfolioValue}")
90+
91+
# Helper functions can be added here if needed

0 commit comments

Comments
 (0)