Overall Statistics
Total Orders
264
Average Win
0.29%
Average Loss
-0.29%
Compounding Annual Return
-1.761%
Drawdown
1.500%
Expectancy
-0.036
Start Equity
100000
End Equity
98526.8
Net Profit
-1.473%
Sharpe Ratio
-19.549
Sortino Ratio
-19.971
Probabilistic Sharpe Ratio
0.001%
Loss Rate
52%
Win Rate
48%
Profit-Loss Ratio
0.99
Alpha
0
Beta
0
Annual Standard Deviation
0.003
Annual Variance
0
Information Ratio
-3.554
Tracking Error
0.003
Treynor Ratio
0
Total Fees
$343.20
Estimated Strategy Capacity
$3000.00
Lowest Capacity Asset
SPY YNW79RBVSJFQ|SPY R735QTJ8XC9X
Portfolio Turnover
0.96%
# region imports
from AlgorithmImports import *
# endregion

class GeekyAsparagusBarracuda(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2024, 1, 1)
        self.set_end_date(2024, 10, 31)
        self.set_cash(100000)        
        
        self.universe_settings.asynchronous = True
        option = self.add_option("SPY", Resolution.MINUTE)
        self.symbol = option.symbol
        self.indicator = self.add_data(Signal, "CUSTOM1", Resolution.MINUTE).symbol

        #call_spread(min_days_till_expiry: int, higher_strike_from_atm: float, lower_strike_from_atm: float)
        #Selects two call contracts to form Bull Call Spread or Bear Call Spread Option strategies.
        
        option.set_filter(lambda universe: universe.include_weeklys().iron_condor(30, 5, 10))

        self.set_brokerage_model(BrokerageName.INTERACTIVE_BROKERS_BROKERAGE, AccountType.CASH)

    def on_data(self, data: Slice):
        # Get the OptionChain
        chain = data.option_chains.get(self.symbol, None)

        if self.indicator in data:            
            received_signal = data[self.indicator].value
            if not chain:
                self.log(str(self.time) + str(' ') + str('No chanin available'))
                return
            
            if (not self.portfolio.invested and received_signal == 1):
                expiry = max([x.expiry for x in chain])
                chain = sorted([x for x in chain if x.expiry == expiry], key = lambda x: x.strike)

                put_contracts = [x for x in chain if x.right == OptionRight.PUT]
                call_contracts = [x for x in chain if x.right == OptionRight.CALL]

                if len(call_contracts) < 2 or len(put_contracts) < 2:
                    return
                
                # Select the strategy legs
                near_call = call_contracts[0]
                far_call = call_contracts[1]
                near_put = put_contracts[1]
                try:
                    far_put = [x for x in put_contracts if x.Strike == (near_put.strike - far_call.strike + near_call.strike)][0]
                except:
                    return
                iron_condor = OptionStrategies.iron_condor(
                                self.symbol, 
                                far_put.strike,
                                near_put.strike,
                                near_call.strike,
                                far_call.strike,
                                expiry)

                self.buy(iron_condor, 2)
            
            elif self.portfolio.invested and received_signal == 0:
                #option_invested = [x.key for x in self.portfolio if x.value.invested and x.value.type==SecurityType.OPTION ]
                
                self.liquidate()
                self.log("Sell Order" + str(self.time) + str('  ') + str(received_signal))
            
            else:
                # self.set_holdings(self.spy, 0)
                self.log("Do Nothing " + str(self.time) + str('  ') + str(received_signal))

class Signal(PythonData):   

    def get_source(self, config, date, isLive):
        source = "https://www.dropbox.com/scl/fi/mynxp0hpeexq2dfjeiset/ml_output_old.csv?rlkey=fd2jghurd7pgzraw8zpnw4fyf&st=yqtpi1fd&dl=1"
        return SubscriptionDataSource(source, SubscriptionTransportMedium.REMOTE_FILE)
    
    def reader(self, config, line, date, isLive):        
        if not (line.strip() and line[0].isdigit()):                
            return None
         
        csv = line.split(',')        
        xyz = Signal()        
        
        xyz.symbol = config.symbol
        xyz.time = datetime.strptime(csv[0], '%Y-%m-%d %H:%M:%S') 
                  
        
        xyz.value = int(csv[1])   
        return xyz