Fix trade statistics for option assignment underlying fills (#9627)
* Fix option assignment trade statistics Resolve the security from each order event when updating TradeBuilder so physically settled underlying fills use the underlying multiplier and conversion rate. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 716a0df4-0117-458b-b4ac-7d8aeeb9bf48 * Resolve order event security from the event symbol Option exercises emit the underlying fill under the option's order id, so resolving the security from the order symbol handed the option's contract multiplier and quote currency conversion rate to the underlying fill, inflating closed trade statistics. Extend the option assignment regression algorithm, in both C# and Python, to assert every closed trade's profit and loss against its own security's contract multiplier. --------- Co-authored-by: Kapil Yadav <kapyadav@microsoft.com> Co-authored-by: Jhonathan Abreu <jdabreu25@gmail.com>
This commit is contained in:
@@ -47,3 +47,22 @@ class OptionAssignmentRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
if self.time < self.call_option_symbol.id.date:
|
||||
self.market_order(self.call_option_symbol, -1)
|
||||
|
||||
def get_security(self, symbol):
|
||||
if symbol == self.stock.symbol:
|
||||
return self.stock
|
||||
if symbol == self.call_option_symbol:
|
||||
return self.call_option
|
||||
if symbol == self.put_option_symbol:
|
||||
return self.put_option
|
||||
raise RegressionTestException(f"Unexpected symbol: {symbol}")
|
||||
|
||||
def on_end_of_algorithm(self):
|
||||
for trade in self.trade_builder.closed_trades:
|
||||
symbol, = trade.symbols
|
||||
direction = 1 if trade.direction == TradeDirection.LONG else -1
|
||||
multiplier = self.get_security(symbol).symbol_properties.contract_multiplier
|
||||
expected_profit_loss = round((trade.exit_price - trade.entry_price) * trade.quantity * direction * multiplier, 2)
|
||||
|
||||
if trade.profit_loss != expected_profit_loss:
|
||||
raise RegressionTestException(f"Expected underlying trade profit/loss to be {expected_profit_loss}. Actual: {trade.profit_loss}")
|
||||
|
||||
Reference in New Issue
Block a user