Overall Statistics |
Total Orders 385 Average Win 1.03% Average Loss -0.99% Compounding Annual Return 8.475% Drawdown 20.600% Expectancy 0.057 Start Equity 100000 End Equity 108450.76 Net Profit 8.451% Sharpe Ratio 0.305 Sortino Ratio 0.255 Probabilistic Sharpe Ratio 23.165% Loss Rate 48% Win Rate 52% Profit-Loss Ratio 1.04 Alpha -0 Beta -0.461 Annual Standard Deviation 0.196 Annual Variance 0.039 Information Ratio 0.558 Tracking Error 0.342 Treynor Ratio -0.13 Total Fees $1272.87 Estimated Strategy Capacity $120000000.00 Lowest Capacity Asset JNJ R735QTJ8XC9X Portfolio Turnover 48.36% |
from AlgorithmImports import * class MeanReversionShortAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2022, 1, 1) self.SetEndDate(2023, 1, 1) self.SetCash(100000) # Define a list of 10 well-known, highly liquid stocks self.tickers = [ 'AAPL', 'MSFT', 'GOOGL', 'AMZN', 'NVDA', 'META', 'TSLA', 'JNJ', 'JPM', 'V' ] # Add Equity data for the tickers self.symbols = [] for ticker in self.tickers: self.symbols.append(self.AddEquity(ticker, Resolution.Daily).Symbol) # Add SPY for scheduling and market checks self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol # Dictionary to store previous close prices self.previous_close = {} # Warm-up the algorithm to get historical data for previous close prices self.SetWarmup(1) # Schedule event to sell all positions at 3:55 PM self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(15, 55), self.Rebalance) def OnData(self, data): if self.IsWarmingUp: return # Avoid trading near market close if self.Time.hour == 15 and self.Time.minute >= 55: return # Collect previous close prices for symbol in self.symbols: if symbol in data.Bars: self.previous_close[symbol] = data.Bars[symbol].Close # Calculate overnight percentage change overnight_changes = {} for symbol in self.symbols: if symbol in data.Bars and symbol in self.previous_close: open_price = data.Bars[symbol].Open prev_close_price = self.previous_close[symbol] overnight_change_pct = (open_price - prev_close_price) / prev_close_price * 100 overnight_changes[symbol] = overnight_change_pct # Find stocks with greater than 2% but less than 3% overnight upmove top_movers = [symbol for symbol, change in overnight_changes.items() if 2 < change < 3] # Open short positions for the stocks with greater than 2% but less than 3% upmove for symbol in top_movers: self.SetHoldings(symbol, -1.0 / len(top_movers)) # Short position # Reset previous close prices self.previous_close = {} def Rebalance(self): if self.IsWarmingUp: return # Ensure market is open before liquidating positions if not self.Securities[self.spy].Exchange.DateTimeIsOpen(self.Time): return # Liquidate all positions before market close for kvp in self.Portfolio: if kvp.Value.Invested: self.Liquidate(kvp.Key) # Log for debugging purposes self.Debug(f"Positions liquidated at {self.Time}") # Ensure the code runs correctly from AlgorithmImports import *