| Overall Statistics |
|
Total Orders 2 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Start Equity 100000 End Equity 99222 Net Profit 0% Sharpe Ratio 0 Sortino 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 0 Tracking Error 0 Treynor Ratio 0 Total Fees $1.00 Estimated Strategy Capacity $180000.00 Lowest Capacity Asset SPY Y05J8KTZA1K6|SPY R735QTJ8XC9X Portfolio Turnover 38.80% |
# region imports
from AlgorithmImports import *
# endregion
class CustomExerciseModelAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2022, 7, 1)
self.set_end_date(2022, 7, 10)
self.set_cash(100000)
self.set_security_initializer(MySecurityInitializer(self))
option = self.add_option("SPY")
self.option_symbol = option.symbol
def on_data(self, data: Slice):
if self.portfolio.invested:
return
chain = data.option_chains.get(self.option_symbol)
if chain:
contract = sorted([x for x in chain if x.right == OptionRight.CALL],
key=lambda x: x.strike)[0]
self.market_order(contract.symbol, 1)
self.exercise_option(contract.symbol, 1)
self.quit()
class MySecurityInitializer(BrokerageModelSecurityInitializer):
def __init__(self, algorithm) -> None:
super().__init__(algorithm.brokerage_model, FuncSecuritySeeder(algorithm.get_last_known_prices))
self.algorithm = algorithm
def initialize(self, security: Security) -> None:
super().initialize(security)
if security.type == SecurityType.OPTION:
security.set_option_exercise_model(MyOptionExerciseModel(self.algorithm))
# This custom model implements the default model in LEAN (written in C#)
class MyOptionExerciseModel(DefaultExerciseModel):
def __init__(self, algorithm):
self.algorithm = algorithm
def option_exercise(self, option: Option, order: OptionExerciseOrder) -> List[OrderEvent]:
order_events = []
underlying = option.underlying
utc_time = Extensions.convert_to_utc(option.local_time, option.exchange.time_zone)
in_the_money = option.is_auto_exercised(underlying.close)
is_assignment = in_the_money and option.holdings.is_short
messages = Messages.DefaultExerciseModel
order_event = OrderEvent(
order.id,
option.symbol,
utc_time,
OrderStatus.FILLED,
Extensions.get_order_direction(order.quantity),
0,
order.quantity,
OrderFee.ZERO,
messages.contract_holdings_adjustment_fill_tag(in_the_money, is_assignment, option)
)
order_event.is_assignment = is_assignment
order_event.is_in_the_money = in_the_money
order_events.append(order_event)
if in_the_money and option.exercise_settlement == SettlementType.PHYSICAL_DELIVERY:
exercise_quantity = option.get_exercise_quantity(order.quantity);
order_event = OrderEvent(
order.id,
underlying.symbol,
utc_time,
OrderStatus.FILLED,
Extensions.get_order_direction(exercise_quantity),
option.strike_price,
exercise_quantity,
OrderFee.ZERO,
messages.option_assignment if is_assignment else messages.option_exercise
)
order_event.is_in_the_money = True
order_events.append(order_event)
return order_events