Overall Statistics
Total Orders
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Start Equity
100000
End Equity
100000
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
-4.645
Tracking Error
0.081
Treynor Ratio
0
Total Fees
$0.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
Portfolio Turnover
0%
Drawdown Recovery
0
# region imports
from AlgorithmImports import *
# endregion

class CalmBlueFox(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2025, 6, 1)
        self.universe_settings.data_normalization_mode = DataNormalizationMode.RAW
        self._universe = self.add_universe(self._fundamental_function)
        market = Symbol.create("SPY", SecurityType.EQUITY, Market.USA)
        self.schedule.on(self.date_rules.every_day(market),
            self.time_rules.before_market_open(market, 10),
            self._add_option_contracts_for_universe)
    
    def _fundamental_function(self, fundamental: list[Fundamental]) -> list[Symbol]:
        def criteria(f):
            return f.price > 10 and f.dollar_volume > 10_000_000
        return [x.symbol for x in sorted(filter(criteria, fundamental), key=lambda f: f.dollar_volume)][-3:]

    def _add_option_contracts_for_universe(self):
        for symbol in self._universe.selected:
            underlying = self.securities[symbol]
            
            # Get the chain and select contracts
            chain = self.option_chain(symbol)
            expiries = [x.expiry for x in chain]
            if not expiries: continue
            expiry = min([x.expiry for x in chain])
            symbols = [x for x in chain if x.expiry == expiry and abs(x.strike-underlying.price)<=2]
            
            # Let's add and save symbols of the contracts to use it later if we will
            underlying.contracts = [self.add_option_contract(x).symbol for x in symbols]

    def on_securities_changed(self, changes):
        # We want to warm up the Equity to have non-zero price for _add_option_contracts_for_universe
        for security in changes.added_securities:
            if not security.has_data and security.type == SecurityType.EQUITY:
                [security.set_market_price(data) for data in self.get_last_known_prices(security)]

        # Optionnal: Once the underlying in removed, we remove the contracts.
        # Expired will be automatically removed.
        for security in changes.removed_securities:
            if hasattr(security, 'contracts'):
                tag = 'Removed because of universe selection'
                [self.remove_security(x) for x in security.contracts]
                self.liquidate(security.symbol, tag)
                security.contracts.clear()

    def on_data(self, slice):
        for symbol in self._universe.selected:
            chain = slice.option_chains.get(Symbol.create_canonical_option(symbol))