Overall Statistics
Total Orders
208
Average Win
5.12%
Average Loss
-0.66%
Compounding Annual Return
61.965%
Drawdown
23.100%
Expectancy
0.680
Start Equity
100000
End Equity
162107.21
Net Profit
62.107%
Sharpe Ratio
1.531
Sortino Ratio
1.92
Probabilistic Sharpe Ratio
70.466%
Loss Rate
81%
Win Rate
19%
Profit-Loss Ratio
7.76
Alpha
0.158
Beta
1.945
Annual Standard Deviation
0.252
Annual Variance
0.064
Information Ratio
1.504
Tracking Error
0.179
Treynor Ratio
0.198
Total Fees
$388.64
Estimated Strategy Capacity
$3500000.00
Lowest Capacity Asset
UPST XKEDQOEEEPUT
Portfolio Turnover
5.66%
from AlgorithmImports import *

class RsiTakeProfitStopLossAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2024, 1, 1)
        self.SetEndDate(2024, 12, 31)
        self.SetCash(100000)

        self.tickers = ["TSLA", "GOOGL", "NVDA", "MSFT", "META", "HIMS", "UPST", "ORCL", "COIN", "AMD"]
        self.symbols = []
        self.rsi = {}
        self.entry_prices = {}  # Track entry prices per symbol
        self.stop_loss_percent = 0.05 # 5% stop-loss

        for ticker in self.tickers:
            symbol = self.AddEquity(ticker, Resolution.Minute).Symbol
            self.symbols.append(symbol)

            # Set up 15-minute consolidator and RSI
            consolidator = TradeBarConsolidator(timedelta(minutes=15))
            self.SubscriptionManager.AddConsolidator(symbol, consolidator)

            rsi = RelativeStrengthIndex(14, MovingAverageType.Wilders)
            self.rsi[symbol] = rsi
            self.RegisterIndicator(symbol, rsi, consolidator)

            consolidator.DataConsolidated += self.OnDataConsolidated

    def OnDataConsolidated(self, sender, bar):
        symbol = bar.Symbol
        rsi = self.rsi[symbol]

        if not rsi.IsReady:
            return

        price = bar.Close
        holdings = self.Portfolio[symbol].Quantity

        # Buy condition: RSI <= 30 and no holdings
        if rsi.Current.Value <= 30 and holdings == 0:
            self.SetHoldings(symbol, 0.1)
            self.entry_prices[symbol] = price
            self.Debug(f"{self.Time} BUY {symbol.Value} | RSI: {rsi.Current.Value:.2f} | Entry: {price:.2f}")

        # Sell conditions:
        elif holdings > 0 and symbol in self.entry_prices:
            entry_price = self.entry_prices[symbol]
            target_price = entry_price * 1.50
            stop_loss_price = entry_price * (1 - self.stop_loss_percent)

            if price >= target_price:
                self.Liquidate(symbol)
                del self.entry_prices[symbol] # Clean up entry price
                self.Debug(f"{self.Time} SELL (Take Profit) {symbol.Value} | Gain: {(price - entry_price) / entry_price:.2%} | Price: {price:.2f}")
            elif price <= stop_loss_price:
                self.Liquidate(symbol)
                del self.entry_prices[symbol] # Clean up entry price
                self.Debug(f"{self.Time} SELL (Stop Loss) {symbol.Value} | Loss: {(price - entry_price) / entry_price:.2%} | Price: {price:.2f}")

    def OnData(self, data):
        pass