# region imports
from AlgorithmImports import *
import itertools
# endregion
class ComboLegLimitOrderDemoAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 12, 24)
self.SetEndDate(2015, 12, 24)
self.SetCash(100000)
option = self.AddOption("GOOG")
option.SetFilter(minStrike=-2, maxStrike=2, minExpiry=timedelta(days=0), maxExpiry=timedelta(days=180))
self.tickets = []
def OnData(self, slice: Slice):
if len(self.tickets) == 0:
for canonical_symbol, chain in slice.OptionChains.items():
# Select contracts
contracts = [contract for contract in chain if contract.Right == OptionRight.Call]
contracts = [(key, list(group)) for key, group in itertools.groupby(contracts, key=lambda x: x.Expiry)]
contracts.sort(key=lambda x: x[0])
contracts = contracts[0][1]
contracts.sort(key=lambda x: x.Strike)
if len(contracts) < 2:
return
# Create order legs
quantities = [1, -2]
legs = []
for i, contract in enumerate(contracts[:2]):
legs.append(Leg.Create(contract.Symbol, quantities[i], slice[contract.Symbol].Close * .999))
# Place order
self.tickets = self.ComboLegLimitOrder(legs, 1)
else:
if self.Time.hour == 10 and self.Time.minute == 45:
self.Quit()
return
for ticket in self.tickets:
order_direction = np.sign(ticket.Quantity)
limit_price = ticket.Get(OrderField.LimitPrice)
# Log the limit prices and contract prices
quote_bar = slice.QuoteBars[ticket.Symbol]
current_price = quote_bar.Ask.Low if order_direction == 1 else quote_bar.Bid.High
ready_to_fill = current_price < limit_price if order_direction == 1 else current_price > limit_price
self.Log(f"{self.Time} - {ticket.Symbol}. Current price: {current_price}; Limit price: {round(limit_price, 2)}; Direction: {order_direction}; Ready to fill: {ready_to_fill}")
# Update the leg orders
update_settings = UpdateOrderFields()
update_settings.Quantity = 2 * order_direction
update_settings.LimitPrice = limit_price + 0.01 * order_direction
update_settings.Tag = f"Update #{len(ticket.UpdateRequests) + 1}"
response = ticket.Update(update_settings)
def OnOrderEvent(self, orderEvent: OrderEvent) -> None:
if orderEvent.Status == OrderStatus.Filled:
self.Log(f"{self.Time} -- Order {orderEvent.OrderId} filled at {orderEvent.FillPrice}")