Overall Statistics
Total Orders
36
Average Win
41.69%
Average Loss
-6.18%
Compounding Annual Return
-80.287%
Drawdown
85.000%
Expectancy
-0.742
Start Equity
200000
End Equity
39308
Net Profit
-80.346%
Sharpe Ratio
-1.135
Sortino Ratio
-0.78
Probabilistic Sharpe Ratio
0.003%
Loss Rate
97%
Win Rate
3%
Profit-Loss Ratio
6.74
Alpha
-0.825
Beta
1.261
Annual Standard Deviation
0.548
Annual Variance
0.3
Information Ratio
-1.832
Tracking Error
0.428
Treynor Ratio
-0.493
Total Fees
$0.00
Estimated Strategy Capacity
$1000.00
Lowest Capacity Asset
VIX XNUJM2J12SJ2|VIX 31
Portfolio Turnover
1.80%
from AlgorithmImports import *
from QuantConnect.DataSource import *

class IndexOptionsDataAlgorithm(QCAlgorithm):
    def initialize(self) -> None:
        self.set_start_date(2020, 1, 1)
        self.set_end_date(2021, 1, 1)
        self.set_cash(200000)
        self.universe_settings.asynchronous = True
        index = self.add_index("VIX")
        option = self.add_option(index.symbol)
        option.set_filter(-2, +2, 0, 180)
        self.option_symbol = option.symbol

    def on_data(self, slice: Slice) -> None:
        if not self.portfolio.invested and self.is_market_open(self.option_symbol):
            chain = slice.option_chains.get(self.option_symbol)
            if not chain:
                return
            
            call_contracts = [c for c in chain if c.right == OptionRight.CALL]
            if call_contracts:
                    
                expiry = max([c.expiry for c in call_contracts])
                call_contracts = sorted([c for c in call_contracts if c.expiry == expiry],
                    key=lambda c: c.strike)
                        
                if len(call_contracts) < 2:
                    return
                
                longCall, shortCall = call_contracts[0:2]
                
                # Use all the buying power
                quantity = min([
                    abs(self.calculate_order_quantity(shortCall.symbol, -1)),
                    abs(self.calculate_order_quantity(longCall.symbol, 1))])
                
                self.market_order(shortCall.symbol, -quantity)
                self.market_order(longCall.symbol, quantity)
                
                expected_margin_usage = max((longCall.strike - shortCall.strike) * self.securities[longCall.symbol].symbol_properties.contract_multiplier * quantity, 0)
                if expected_margin_usage != self.portfolio.total_margin_used:
                    raise Exception("Unexpect margin used!")


    def on_securities_changed(self, changes: SecurityChanges) -> None:
        for security in changes.added_securities:
            if security.type == SecurityType.INDEX_OPTION:
                # Historical data
                history = self.history(security.symbol, 10, Resolution.MINUTE)
                self.debug(f"We got {len(history)} from our history request for {security.symbol}")