| Overall Statistics |
|
Total Orders 72 Average Win 8.94% Average Loss -6.46% Compounding Annual Return 229.011% Drawdown 27.200% Expectancy 0.266 Start Equity 100000 End Equity 148388.4 Net Profit 48.388% Sharpe Ratio 2.602 Sortino Ratio 3.458 Probabilistic Sharpe Ratio 64.737% Loss Rate 47% Win Rate 53% Profit-Loss Ratio 1.38 Alpha 0 Beta 0 Annual Standard Deviation 0.71 Annual Variance 0.504 Information Ratio 2.679 Tracking Error 0.71 Treynor Ratio 0 Total Fees $2199.60 Estimated Strategy Capacity $2000.00 Lowest Capacity Asset SPY YIQ3S0PODCLI|SPY R735QTJ8XC9X Portfolio Turnover 9.41% |
# region imports
from AlgorithmImports import *
# endregion
class JumpingYellowGreenGaur(QCAlgorithm):
def initialize(self):
self.set_start_date(2024, 1, 1)
self.set_end_date(2024, 4, 30)
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):
# Find put and call contracts with the farthest expiry
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
far_put = put_contracts[0]
near_put = put_contracts[1]
near_call = call_contracts[0]
far_call = call_contracts[1]
quantity_far_put = self.portfolio.total_portfolio_value*0.25 / far_put.ask_price
quantity_near_put = self.portfolio.total_portfolio_value*0.25 / near_put.ask_price
quantity_near_call = self.portfolio.total_portfolio_value*0.25 / near_call.ask_price
quantity_far_call = self.portfolio.total_portfolio_value*0.25 / far_call.ask_price
quantity = min(quantity_far_put, quantity_near_put,quantity_near_call,quantity_far_call)
quantity = int(quantity/ 100)
short_iron_condor = OptionStrategies.short_iron_condor(
self.symbol,
far_put.strike,
near_put.strike,
near_call.strike,
far_call.strike,
expiry)
self.buy(short_iron_condor, quantity)
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