Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -10.106 Tracking Error 0.021 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
from QuantConnect.Algorithm import QCAlgorithm from QuantConnect.Data.Custom import * from QuantConnect.Orders import * from QuantConnect.Securities.Option import OptionPriceModels from datetime import timedelta, datetime import csv import io class SPXWTradingAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2023, 11, 3) self.SetCash(100000) spx = self.AddIndex("SPX").Symbol option = self.AddIndexOption(spx, "SPXW") option.SetFilter(lambda universe: universe.IncludeWeeklys().Strikes(-100, 100).Expiration(timedelta(0), timedelta(2))) self.symbol = option.Symbol option.PriceModel = OptionPriceModels.CrankNicolsonFD() option.EnableGreekApproximation = True self.last_row = None self.Schedule.On(self.DateRules.EveryDay(self.symbol), self.TimeRules.Every(timedelta(seconds=30)), self.Trade) def Trade(self): try: csv_string = self.Download('https://docs.google.com/spreadsheets/d/1wwadCU8msu6FEUJt1ANoZS2qMO2MWiheARrdm7zaQlM/export?format=csv') csv_reader = csv.DictReader(io.StringIO(csv_string)) new_row = None for i, order in enumerate(csv_reader): new_row = order if new_row is None or new_row == self.last_row: return self.last_row = new_row self.Debug(','.join([v for v in self.last_row.values()])) expiry = datetime.strptime(str(self.last_row['TWS Contract Date']), '%Y%m%d') optionchain = self.OptionChainProvider.GetOptionContractList(self.symbol, self.Time.date()) contracts = [i for i in optionchain if i.ID.Date.date() == expiry.date()] for security in self.Securities.Values: self.Debug(str(security.Symbol)) if len(contracts) < 1: self.Debug(f"Not enough option contracts for order: {self.last_row}") return legs = [] total_limit_price = 0 leg_details = [] for i in range(1, 5): if self.last_row[f'Strike {i}'].strip(): strike = float(self.last_row[f'Strike {i}'].strip()) contracts.sort(key=lambda x: abs(x.ID.StrikePrice - strike)) if len(contracts) > 0: if self.Securities.ContainsKey(contracts[0]): contract = self.Securities[contracts[0]] if self.last_row[f'Right {i}']: right = OptionRight.Call if self.last_row[f'Right {i}'] == 'C' else OptionRight.Put self.Debug(f"Right {i}: {self.last_row[f'Right {i}']}") limit_price = (contract.AskPrice + contract.BidPrice) / 2 action = self.last_row[f'Action {i}'] if action == 'BUY': quantity = int(self.last_row['Order Quantity']) elif action == 'SELL': quantity = -int(self.last_row['Order Quantity']) else: self.Debug(f"Invalid action: {action}") continue legs.append(Leg.Create(contracts[0], quantity, limit_price)) total_limit_price += limit_price leg_details.append(f"{right} Strike {strike}") self.Debug(f"Added leg: {contracts[0].Symbol.Value}, {right}, {quantity}") else: self.Debug(f"Contract not found in Securities: {contracts[0]}") else: self.Debug(f"No contracts found for strike {strike}") self.Debug(f"Last row detected on the sheet has {len(legs)} legs in it, {', '.join(leg_details)} at the expiration date {expiry.strftime('%Y%m%d')}.") if legs: ticket = self.ComboLegLimitOrder(legs, total_limit_price) self.Debug(f"Symbol: {ticket.Symbol}; Quantity filled: {ticket.QuantityFilled}; Fill price: {ticket.AverageFillPrice}") else: self.Debug("No valid legs for combo order") except Exception as e: self.Debug(f"Error in Trade: {str(e)}") def OnOrderEvent(self, orderEvent): if orderEvent.Status == OrderStatus.Filled: self.Debug("Order filled: " + str(orderEvent))