Overall Statistics |
Total Orders 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 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 0 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
from AlgorithmImports import * from collections import deque import statistics as stats import config class PremiumThresholdAdjuster(): def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol self.Avg_Premium_Length = config.PREMIUM_ADJUST_LENGTH self.Avg_Premium_1_Queue = deque(maxlen=self.Avg_Premium_Length) self.Avg_Premium_15_Queue = deque(maxlen=self.Avg_Premium_Length) self.Avg_Premium_20_Queue = deque(maxlen=self.Avg_Premium_Length) self.Avg_Premium_25_Queue = deque(maxlen=self.Avg_Premium_Length) self.Avg_Premium_30_Queue = deque(maxlen=self.Avg_Premium_Length) self.Avg_Premium_1 = None self.Avg_Premium_15 = None self.Avg_Premium_20 = None self.Avg_Premium_25 = None self.Avg_Premium_30 = None self.One_Premium = None self.One_Five_Premium = None self.Two_Premium = None self.Two_Five_Premium = None self.Three_Premium = None def receive_condors(self, c_1, c_1_5, c_2, c_2_5, c_3): self.One_Premium = c_1 self.One_Five_Premium = c_1_5 self.Two_Premium = c_2 self.Two_Five_Premium = c_2_5 self.Three_Premium = c_3 def return_premium_today(self, range_today): if range_today == 0.01: if self.Avg_Premium_1 is not None: return self.Avg_Premium_1 else: return config.FIXED_PREMIUM_1 elif range_today == 0.015: if self.Avg_Premium_15 is not None: return self.Avg_Premium_15 else: return config.FIXED_PREMIUM_1_5 elif range_today == 0.02: if self.Avg_Premium_20 is not None: return self.Avg_Premium_20 else: return config.FIXED_PREMIUM_2 elif range_today == 0.025: if self.Avg_Premium_25 is not None: return self.Avg_Premium_25 else: return config.FIXED_PREMIUM_2_5 elif range_today == 0.03: if self.Avg_Premium_30 is not None: return self.Avg_Premium_30 else: return config.FIXED_PREMIUM_3 def Update_Highest_Premiums(self): if self.Two_Premium is not None: premium = self.Two_Premium.calculate_premium() if premium > self.Two_Premium.Highest_Premium: #self.algorithm.Debug(premium) self.Two_Premium.Highest_Premium = premium if self.Two_Five_Premium is not None: premium = self.Two_Five_Premium.calculate_premium() if premium > self.Two_Five_Premium.Highest_Premium: self.Two_Five_Premium.Highest_Premium = premium if self.One_Five_Premium is not None: premium = self.One_Five_Premium.calculate_premium() if premium > self.One_Five_Premium.Highest_Premium: self.One_Five_Premium.Highest_Premium = premium if self.Three_Premium is not None: premium = self.Three_Premium.calculate_premium() if premium > self.Three_Premium.Highest_Premium: self.Three_Premium.Highest_Premium = premium def run_append(self): self.append_1() self.append_15() self.append_20() self.append_25() self.append_30() def append_1(self): if self.One_Premium is not None: premium = self.One_Premium.Highest_Premium if premium is not None: self.Avg_Premium_1_Queue.appendleft(premium) if len(self.Avg_Premium_1_Queue) == self.Avg_Premium_Length: self.Avg_Premium_1 = sum(self.Avg_Premium_1_Queue) / len(self.Avg_Premium_1_Queue) self.algorithm.Plot("Average Premium 1%", "Premium", self.Avg_Premium_1) def append_15(self): if self.One_Five_Premium is not None: premium = self.One_Five_Premium.Highest_Premium if premium is not None: self.Avg_Premium_15_Queue.appendleft(premium) if len(self.Avg_Premium_15_Queue) == self.Avg_Premium_Length: self.Avg_Premium_15 = sum(self.Avg_Premium_15_Queue) / len(self.Avg_Premium_15_Queue) self.algorithm.Plot("Average Premium 1.5%", "Premium", self.Avg_Premium_15) def append_20(self): if self.Two_Premium is not None: premium = self.Two_Premium.Highest_Premium if premium is not None: self.Avg_Premium_20_Queue.appendleft(premium) if len(self.Avg_Premium_20_Queue) == self.Avg_Premium_Length: self.Avg_Premium_20 = sum(self.Avg_Premium_20_Queue) / len(self.Avg_Premium_20_Queue) self.algorithm.Plot("Average Premium 2%", "Premium", self.Avg_Premium_20) def append_25(self): if self.Two_Five_Premium is not None: premium = self.Two_Five_Premium.Highest_Premium if premium is not None: self.Avg_Premium_25_Queue.appendleft(premium) if len(self.Avg_Premium_25_Queue) == self.Avg_Premium_Length: self.Avg_Premium_25 = sum(self.Avg_Premium_25_Queue) / len(self.Avg_Premium_25_Queue) self.algorithm.Plot("Average Premium 2.5%", "Premium", self.Avg_Premium_25) def append_30(self): if self.Three_Premium is not None: premium = self.Three_Premium.Highest_Premium if premium is not None: self.Avg_Premium_30_Queue.appendleft(premium) if len(self.Avg_Premium_30_Queue) == self.Avg_Premium_Length: self.Avg_Premium_30 = sum(self.Avg_Premium_30_Queue) / len(self.Avg_Premium_30_Queue) self.algorithm.Plot("Average Premium 3%", "Premium", self.Avg_Premium_30) def reset_premium_adjuster(self): #self.algorithm.Debug(f"{self.Avg_Premium_1} {self.Avg_Premium_15} {self.Avg_Premium_20} {self.Avg_Premium_25} {self.Avg_Premium_30}") self.One_Premium = None self.One_Five_Premium = None self.Two_Premium = None self.Two_Five_Premium = None self.Three_Premium = None
from AlgorithmImports import * from collections import deque import config class AvgDown(): def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol self.use_avg_down = config.USE_AVG_DOWN self.avg_down_mode = config.AVG_DOWN_MODE self.fixed_avg_down_premium = config.FIXED_AVG_DOWN_PREMIUM self.avg_down_percentage = config.AVG_DOWN_PERCENTAGE self.avg_down_x_times = config.AVG_DOWN_X_TIMES self.use_most_recent_entry = config.USE_MOST_RECENT_ENTRY self.pivot_queue = deque(maxlen=3) self.entered_condor = None self.entered_key = None self.avg_down_counter = 0 self.first_entry = None ####################################################################################################### self.use_trading_quantity = config.TRADING_QUANTITY_ACTIVE self.avg_down_layers = { config.TRADING_ENTRY_THRESHOLD: [config.TRADING_ENTRY_QUANTITY, False], config.TRADING_ENTRY_THRESHOLD_2: [config.TRADING_ENTRY_QUANTITY_2, False], config.TRADING_ENTRY_THRESHOLD_3: [config.TRADING_ENTRY_QUANTITY_3, False], } def append_pivot(self): if self.entered_condor is not None: self.entered_condor.calculate_premium() self.pivot_queue.appendleft(self.entered_condor.Premium) def check_avg_down(self, condor): if self.entered_condor is not None: condor = self.entered_condor condor.calculate_premium() if self.use_avg_down: if self.avg_down_mode == "PERCENTAGE": if self.check_percentage_avg_down(): return True, 0, "" else: return False, 0, "" elif self.avg_down_mode == "PIVOT POINT": if self.check_pivot_avg_down(): return True, 0, "" else: return False, 0, "" elif self.avg_down_mode == "PERCENTAGE PIVOT POINT": if self.check_percentage_avg_down() and self.check_pivot_avg_down(): return True, 0, "" else: return False, 0, "" elif self.avg_down_mode == "FIXED": if condor.Premium >= self.fixed_avg_down_premium: return True else: return False, 0, "" elif self.avg_down_mode == "FIXED PIVOT POINT": if condor.Premium >= self.fixed_avg_down_premium and self.check_pivot_avg_down(): return True, 0, "" else: return False, 0, "" elif self.avg_down_mode == "LAYERED": quantity_to_enter = 0 premium_return = [] for premium, entry in self.avg_down_layers.items(): quantity, entered = entry if condor.Premium >= float(premium) and not entered: quantity_to_enter += quantity premium_return.append(premium) self.avg_down_layers[premium][1] = True if quantity_to_enter != 0: return True, quantity_to_enter, premium_return else: return False, 0, "" else: return False, 0, "" else: return False, 0, "" def check_percentage_avg_down(self): if not self.use_most_recent_entry: self.entered_condor.Calculate_Premium() if self.entered_condor.Premium >= self.first_entry * self.avg_down_percentage: return True else: return False else: self.entered_condor.Calculate_Premium() if self.entered_condor.Premium >= self.entered_condor.Entry_Premium * self.avg_down_percentage: return True else: return False def check_pivot_avg_down(self): if len(self.pivot_queue) == 3 and self.pivot_queue[0] < self.pivot_queue[1] > self.pivot_queue[2]: return True else: return False def reset(self): self.use_avg_down = config.USE_AVG_DOWN self.avg_down_mode = config.AVG_DOWN_MODE self.fixed_avg_down_premium = config.FIXED_AVG_DOWN_PREMIUM self.avg_down_percentage = config.AVG_DOWN_PERCENTAGE self.avg_down_x_times = config.AVG_DOWN_X_TIMES self.use_most_recent_entry = config.USE_MOST_RECENT_ENTRY self.pivot_queue = deque(maxlen=3) self.entered_condor = None self.entered_key = None self.avg_down_counter = 0 self.first_entry = None self.avg_down_layers = { config.TRADING_ENTRY_THRESHOLD: [config.TRADING_ENTRY_QUANTITY, False], config.TRADING_ENTRY_THRESHOLD_2: [config.TRADING_ENTRY_QUANTITY_2, False], config.TRADING_ENTRY_THRESHOLD_3: [config.TRADING_ENTRY_QUANTITY_3, False], # "1": [5, False], # "1": [5, False], }
#region imports from AlgorithmImports import * USE_POWELL = False POWELL = [ #datetime(2021, 1, 14).strftime("%Y%-m%-d"), #Powell 12:30 # #datetime(2021, 2, 10).strftime("%Y%-m%-d"), #Powell 14:00 # datetime(2021, 2, 23).strftime("%Y%-m%-d"), #Powell 10:00 datetime(2021, 2, 24).strftime("%Y%-m%-d"), #Powell 10:00 #datetime(2021, 3, 4).strftime("%Y%-m%-d"), #Powell 12:05 # datetime(2021, 3, 22).strftime("%Y%-m%-d"), #Powell 08:00 datetime(2021, 3, 23).strftime("%Y%-m%-d"), #Powell 11:00 datetime(2021, 3, 24).strftime("%Y%-m%-d"), #Powell 09:00 datetime(2021, 4, 8).strftime("%Y%-m%-d"), #Powell 11:00 datetime(2021, 4, 14).strftime("%Y%-m%-d"), #Powell 11:00 #datetime(2021, 5, 3).strftime("%Y%-m%-d"), #Powell 13:20 # datetime(2021, 6, 4).strftime("%Y%-m%-d"), #Powell 06:00 #datetime(2021, 6, 22).strftime("%Y%-m%-d"), #Powell 13:00 # datetime(2021, 7, 14).strftime("%Y%-m%-d"), #Powell 11:00 datetime(2021, 7, 15).strftime("%Y%-m%-d"), #Powell 08:30 #datetime(2021, 8, 17).strftime("%Y%-m%-d"), #Powell 12:30 # datetime(2021, 8, 27).strftime("%Y%-m%-d"), #Powell 09:00 datetime(2021, 9, 24).strftime("%Y%-m%-d"), #Powell 09:00 datetime(2021, 9, 28).strftime("%Y%-m%-d"), #Powell 09:00 datetime(2021, 9, 29).strftime("%Y%-m%-d"), #Powell 09:45 datetime(2021, 10, 22).strftime("%Y%-m%-d"), #Powell 10:00 datetime(2021, 11, 8).strftime("%Y%-m%-d"), #Powell 10:30 datetime(2021, 11, 9).strftime("%Y%-m%-d"), #Powell 9:00 # datetime(2021, 11, 29).strftime("%Y%-m%-d"), #Powell 15:05 # datetime(2021, 11, 30).strftime("%Y%-m%-d"), #Powell 10:00 datetime(2021, 12, 1).strftime("%Y%-m%-d"), #Powell 10:00 datetime(2022, 1, 11).strftime("%Y%-m%-d"), #Powell 10:00 datetime(2022, 3, 2).strftime("%Y%-m%-d"), #Powell 10:00 datetime(2022, 3, 3).strftime("%Y%-m%-d"), #Powell 10:00 datetime(2022, 3, 21).strftime("%Y%-m%-d"), #Powell 11:00 datetime(2022, 3, 23).strftime("%Y%-m%-d"), #Powell 07:00 datetime(2022, 4, 21).strftime("%Y%-m%-d"), #Powell 10:00 # datetime(2022, 5, 17).strftime("%Y%-m%-d"), #Powell 13:00 # datetime(2022, 5, 24).strftime("%Y%-m%-d"), #Powell 11:20 datetime(2022, 6, 17).strftime("%Y%-m%-d"), #Powell 07:45 datetime(2022, 6, 22).strftime("%Y%-m%-d"), #Powell 08:30 datetime(2022, 6, 23).strftime("%Y%-m%-d"), #Powell 09:00 datetime(2022, 6, 29).strftime("%Y%-m%-d"), #Powell 08:00 datetime(2022, 8 ,26).strftime("%Y%-m%-d"), #Powell 09:00 datetime(2022, 9, 8).strftime("%Y%-m%-d"), #Powell 08:10 # datetime(2022, 9, 23).strftime("%Y%-m%-d"), #Powell 13:00 # datetime(2022, 9, 27).strftime("%Y%-m%-d"), #Powell 06:30 datetime(2022, 9, 28).strftime("%Y%-m%-d"), #Powell 09:15 #datetime(2022, 11, 30).strftime("%Y%-m%-d"), #Powell 13:30 # ] USE_POWELL_NEXTDAY = False POWELL_NEXTDAY = [ datetime(2021, 1, 15).strftime("%Y%-m%-d"), #DayAfterPowell datetime(2021, 2, 11).strftime("%Y%-m%-d"), #DAP datetime(2021, 3, 5).strftime("%Y%-m%-d"), #DAP datetime(2021, 3, 25).strftime("%Y%-m%-d"), #DAP datetime(2021, 4, 9).strftime("%Y%-m%-d"), #DAP datetime(2021, 4, 15).strftime("%Y%-m%-d"), #DAP datetime(2021, 5, 4).strftime("%Y%-m%-d"), #DAP datetime(2021, 6, 5).strftime("%Y%-m%-d"), #DAP datetime(2021, 6, 23).strftime("%Y%-m%-d"), #DAP datetime(2021, 7, 16).strftime("%Y%-m%-d"), #DAP datetime(2021, 9, 30).strftime("%Y%-m%-d"), #DAP datetime(2021, 11, 10).strftime("%Y%-m%-d"), #DAP datetime(2021, 12, 2).strftime("%Y%-m%-d"), #DAP datetime(2022, 1, 12).strftime("%Y%-m%-d"), #DAP datetime(2022, 3, 4).strftime("%Y%-m%-d"), #DAP datetime(2022, 3, 22).strftime("%Y%-m%-d"), #DAP datetime(2022, 3, 24).strftime("%Y%-m%-d"), #DAP datetime(2022, 4, 22).strftime("%Y%-m%-d"), #DAP datetime(2022, 5, 17).strftime("%Y%-m%-d"), #DAP datetime(2022, 5, 25).strftime("%Y%-m%-d"), #DAP datetime(2022, 6, 24).strftime("%Y%-m%-d"), #DAP datetime(2022, 8, 27).strftime("%Y%-m%-d"), #DAP datetime(2022, 9, 9).strftime("%Y%-m%-d"), #DAP datetime(2022, 9, 29).strftime("%Y%-m%-d"), #DAP datetime(2022, 12, 1).strftime("%Y%-m%-d"), #DAP ] USE_FED_INTEREST_RATE_DECISION = False FED_INTEREST_RATE_DECISION = [ datetime(2021, 1, 27).strftime("%Y%-m%-d"), datetime(2021, 3, 17).strftime("%Y%-m%-d"), datetime(2021, 4, 28).strftime("%Y%-m%-d"), datetime(2021, 6, 16).strftime("%Y%-m%-d"), datetime(2021, 7, 28).strftime("%Y%-m%-d"), datetime(2021, 9, 22).strftime("%Y%-m%-d"), datetime(2021, 11, 3).strftime("%Y%-m%-d"), datetime(2021, 12, 15).strftime("%Y%-m%-d"), datetime(2022, 1, 26).strftime("%Y%-m%-d"), datetime(2022, 3, 16).strftime("%Y%-m%-d"), datetime(2022, 5, 4).strftime("%Y%-m%-d"), datetime(2022, 6, 15).strftime("%Y%-m%-d"), datetime(2022, 7, 27).strftime("%Y%-m%-d"), datetime(2022, 9, 21).strftime("%Y%-m%-d"), datetime(2022, 11, 2).strftime("%Y%-m%-d"), datetime(2022, 12, 14).strftime("%Y%-m%-d"), ] USE_FED_INTEREST_RATE_DECISION_NEXTDAY = False FED_INTEREST_RATE_DECISION_NEXTDAY = [ datetime(2021, 1, 28).strftime("%Y%-m%-d"), datetime(2021, 3, 18).strftime("%Y%-m%-d"), datetime(2021, 4, 29).strftime("%Y%-m%-d"), datetime(2021, 6, 17).strftime("%Y%-m%-d"), datetime(2021, 7, 29).strftime("%Y%-m%-d"), datetime(2021, 9, 23).strftime("%Y%-m%-d"), datetime(2021, 11, 4).strftime("%Y%-m%-d"), datetime(2021, 12, 16).strftime("%Y%-m%-d"), datetime(2022, 1, 27).strftime("%Y%-m%-d"), datetime(2022, 3, 17).strftime("%Y%-m%-d"), datetime(2022, 5, 5).strftime("%Y%-m%-d"), datetime(2022, 6, 17).strftime("%Y%-m%-d"), datetime(2022, 7, 28).strftime("%Y%-m%-d"), datetime(2022, 9, 22).strftime("%Y%-m%-d"), datetime(2022, 11, 3).strftime("%Y%-m%-d"), datetime(2022, 12, 15).strftime("%Y%-m%-d"), ] USE_FOMC_MEETINGS_FIRSTDAY = False FOMC_MEETINGS_FIRSTDAY = [ datetime(2021, 1, 26).strftime("%Y%-m%-d"), datetime(2021, 3, 16).strftime("%Y%-m%-d"), datetime(2021, 4, 27).strftime("%Y%-m%-d"), datetime(2021, 6, 16).strftime("%Y%-m%-d"), datetime(2021, 7, 27).strftime("%Y%-m%-d"), datetime(2021, 9, 21).strftime("%Y%-m%-d"), datetime(2021, 11, 2).strftime("%Y%-m%-d"), datetime(2021, 12, 14).strftime("%Y%-m%-d"), datetime(2022, 1, 25).strftime("%Y%-m%-d"), datetime(2022, 3, 15).strftime("%Y%-m%-d"), datetime(2022, 5, 3).strftime("%Y%-m%-d"), datetime(2022, 6, 14).strftime("%Y%-m%-d"), datetime(2022, 7, 26).strftime("%Y%-m%-d"), datetime(2022, 9, 20).strftime("%Y%-m%-d"), datetime(2022, 11, 1).strftime("%Y%-m%-d"), datetime(2022, 12, 13).strftime("%Y%-m%-d"), ] USE_FOMC_MEETINGS = False FOMC_MEETINGS = [ datetime(2021, 1, 27).strftime("%Y%-m%-d"), datetime(2021, 3, 17).strftime("%Y%-m%-d"), datetime(2021, 4, 28).strftime("%Y%-m%-d"), datetime(2021, 6, 15).strftime("%Y%-m%-d"), datetime(2021, 7, 28).strftime("%Y%-m%-d"), datetime(2021, 9, 22).strftime("%Y%-m%-d"), datetime(2021, 11, 3).strftime("%Y%-m%-d"), datetime(2021, 12, 15).strftime("%Y%-m%-d"), datetime(2022, 1, 26).strftime("%Y%-m%-d"), datetime(2022, 3, 16).strftime("%Y%-m%-d"), datetime(2022, 5, 4).strftime("%Y%-m%-d"), datetime(2022, 6, 15).strftime("%Y%-m%-d"), datetime(2022, 7, 27).strftime("%Y%-m%-d"), datetime(2022, 9 ,21).strftime("%Y%-m%-d"), datetime(2022, 11, 2).strftime("%Y%-m%-d"), datetime(2022, 12, 14).strftime("%Y%-m%-d"), ] USE_FOMC_MINUTES = False FOMC_MINUTES = [ datetime(2021, 1 ,6).strftime("%Y%-m%-d"), datetime(2021, 2 ,17).strftime("%Y%-m%-d"), datetime(2021, 4 ,7).strftime("%Y%-m%-d"), datetime(2021, 5 ,19).strftime("%Y%-m%-d"), datetime(2021, 7 ,7).strftime("%Y%-m%-d"), datetime(2021, 8 ,18).strftime("%Y%-m%-d"), datetime(2021, 10 ,13).strftime("%Y%-m%-d"), datetime(2021, 11 ,24).strftime("%Y%-m%-d"), datetime(2022, 1 ,5).strftime("%Y%-m%-d"), datetime(2022, 2 ,16).strftime("%Y%-m%-d"), datetime(2022, 4, 6).strftime("%Y%-m%-d"), datetime(2022, 5, 25).strftime("%Y%-m%-d"), datetime(2022, 7, 6).strftime("%Y%-m%-d"), datetime(2022, 8, 17).strftime("%Y%-m%-d"), datetime(2022, 10, 12).strftime("%Y%-m%-d"), datetime(2022, 11, 23).strftime("%Y%-m%-d"), ] USE_CPI = False CPI = [ datetime(2021, 1, 13).strftime("%Y%-m%-d"), datetime(2021, 2, 10).strftime("%Y%-m%-d"), datetime(2021, 3, 10).strftime("%Y%-m%-d"), datetime(2021, 4, 13).strftime("%Y%-m%-d"), datetime(2021, 5, 12).strftime("%Y%-m%-d"), datetime(2021, 6, 10).strftime("%Y%-m%-d"), datetime(2021, 7, 13).strftime("%Y%-m%-d"), datetime(2021, 8, 11).strftime("%Y%-m%-d"), datetime(2021, 9, 14).strftime("%Y%-m%-d"), datetime(2021, 10, 13).strftime("%Y%-m%-d"), datetime(2021, 11, 10).strftime("%Y%-m%-d"), datetime(2021, 12, 10).strftime("%Y%-m%-d"), datetime(2022, 1, 12).strftime("%Y%-m%-d"), datetime(2022, 2, 10).strftime("%Y%-m%-d"), datetime(2022, 3, 10).strftime("%Y%-m%-d"), datetime(2022, 4, 12).strftime("%Y%-m%-d"), datetime(2022, 5, 11).strftime("%Y%-m%-d"), datetime(2022, 6, 10).strftime("%Y%-m%-d"), datetime(2022, 7, 13).strftime("%Y%-m%-d"), datetime(2022, 8, 10).strftime("%Y%-m%-d"), datetime(2022, 9, 13).strftime("%Y%-m%-d"), datetime(2022, 10, 13).strftime("%Y%-m%-d"), datetime(2022, 11, 10).strftime("%Y%-m%-d"), datetime(2022, 12, 13).strftime("%Y%-m%-d"), ] USE_CPI_NEXTDAY = False CPI_NEXTDAY = [ datetime(2021, 1, 14).strftime("%Y%-m%-d"), datetime(2021, 2, 11).strftime("%Y%-m%-d"), datetime(2021, 3, 11).strftime("%Y%-m%-d"), datetime(2021, 4, 14).strftime("%Y%-m%-d"), datetime(2021, 5, 13).strftime("%Y%-m%-d"), datetime(2021, 6, 11).strftime("%Y%-m%-d"), datetime(2021, 7, 14).strftime("%Y%-m%-d"), datetime(2021, 8, 12).strftime("%Y%-m%-d"), datetime(2021, 9, 15).strftime("%Y%-m%-d"), datetime(2021, 10, 14).strftime("%Y%-m%-d"), datetime(2021, 11, 11).strftime("%Y%-m%-d"), datetime(2021, 12, 11).strftime("%Y%-m%-d"), datetime(2022, 1, 13).strftime("%Y%-m%-d"), datetime(2022, 2, 11).strftime("%Y%-m%-d"), datetime(2022, 3, 11).strftime("%Y%-m%-d"), datetime(2022, 4, 13).strftime("%Y%-m%-d"), datetime(2022, 5, 12).strftime("%Y%-m%-d"), datetime(2022, 6, 11).strftime("%Y%-m%-d"), datetime(2022, 7, 14).strftime("%Y%-m%-d"), datetime(2022, 8, 11).strftime("%Y%-m%-d"), datetime(2022, 9, 14).strftime("%Y%-m%-d"), datetime(2022, 10, 14).strftime("%Y%-m%-d"), datetime(2022, 11, 11).strftime("%Y%-m%-d"), datetime(2022, 12, 14).strftime("%Y%-m%-d"), ] DISABLE_SPX_WRONG_DATES = False SPX_WRONG_DATES = [ datetime(2021, 3, 23).strftime("%Y%-m%-d"), datetime(2021, 3, 24).strftime("%Y%-m%-d"), datetime(2021, 5, 10).strftime("%Y%-m%-d"), datetime(2021, 5, 11).strftime("%Y%-m%-d"), datetime(2021, 8, 19).strftime("%Y%-m%-d"), datetime(2021, 8, 20).strftime("%Y%-m%-d"), datetime(2021, 12, 3).strftime("%Y%-m%-d"), datetime(2022, 2, 25).strftime("%Y%-m%-d"), datetime(2022, 3, 4).strftime("%Y%-m%-d"), datetime(2022, 5, 6).strftime("%Y%-m%-d"), datetime(2022, 9, 30).strftime("%Y%-m%-d"), datetime(2023, 1, 26).strftime("%Y%-m%-d"), ] DISABLE_SPX_POTENTIALLY_WRONG_DATES = False SPX_POTENTIALLY_WRONG_DATES = [ datetime(2019, 8, 12).strftime("%Y%-m%-d"), datetime(2019, 11, 29).strftime("%Y%-m%-d"), datetime(2021, 11, 26).strftime("%Y%-m%-d"), datetime(2022, 7, 19).strftime("%Y%-m%-d"), datetime(2022, 7, 27).strftime("%Y%-m%-d"), datetime(2022, 7, 28).strftime("%Y%-m%-d"), datetime(2022, 8, 22).strftime("%Y%-m%-d"), datetime(2022, 9, 2).strftime("%Y%-m%-d"), datetime(2022, 9, 6).strftime("%Y%-m%-d"), datetime(2022, 9, 22).strftime("%Y%-m%-d"), datetime(2022, 9, 23).strftime("%Y%-m%-d"), datetime(2022, 9, 26).strftime("%Y%-m%-d"), datetime(2022, 9, 27).strftime("%Y%-m%-d"), datetime(2022, 9, 28).strftime("%Y%-m%-d"), datetime(2022, 9, 29).strftime("%Y%-m%-d"), datetime(2022, 10, 14).strftime("%Y%-m%-d"), datetime(2022, 10, 18).strftime("%Y%-m%-d"), datetime(2022, 10, 25).strftime("%Y%-m%-d"), datetime(2022, 10, 27).strftime("%Y%-m%-d"), datetime(2022, 11, 10).strftime("%Y%-m%-d"), datetime(2022, 11, 17).strftime("%Y%-m%-d"), datetime(2022, 11, 18).strftime("%Y%-m%-d"), datetime(2022, 11, 30).strftime("%Y%-m%-d"), datetime(2022, 12, 15).strftime("%Y%-m%-d"), datetime(2022, 12, 16).strftime("%Y%-m%-d"), ]
from AlgorithmImports import * import calendar_info import config class CheckCalendar(): def __init__(self, algorithm, close_trading_window, open_window, close_window): self.algorithm = algorithm # POWELL self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 1, 14), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 2, 10), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 3, 4), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 5, 3), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 6, 22), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 8, 17), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 11, 29), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 5, 17), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 9, 23), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 11, 30), self.algorithm.TimeRules.At(12,0), close_trading_window) # FED INTEREST RATE self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 1, 27), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 3, 17), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 4, 28), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 6, 16), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 7, 28), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 9, 22), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 11, 3), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 12, 15), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 1, 26), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 3, 16), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 5, 4), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 6, 15), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 7, 27), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 9, 21), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 11, 2), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 12, 4), self.algorithm.TimeRules.At(12,0), close_trading_window) # FOMC MINUTES self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 1, 6), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 2, 17), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 4, 7), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 5, 19), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 7, 7), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 8, 18), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 10, 13), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2021, 11, 24), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 1, 5), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 2, 16), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 4, 6), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 5, 25), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 7, 6), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 8, 17), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 10, 12), self.algorithm.TimeRules.At(12,0), close_trading_window) self.algorithm.Schedule.On(self.algorithm.DateRules.On(2022, 11, 23), self.algorithm.TimeRules.At(12,0), close_trading_window) if config.USE_9_31: self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Friday), self.algorithm.TimeRules.At(9, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Friday), self.algorithm.TimeRules.At(15, 59), close_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Monday), self.algorithm.TimeRules.At(9, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Monday), self.algorithm.TimeRules.At(15, 59), close_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Wednesday), self.algorithm.TimeRules.At(9, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Wednesday), self.algorithm.TimeRules.At(15, 59), close_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Tuesday), self.algorithm.TimeRules.At(9, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Tuesday), self.algorithm.TimeRules.At(15, 59), close_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Thursday), self.algorithm.TimeRules.At(9, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Thursday), self.algorithm.TimeRules.At(15, 59), close_window) elif config.USE_10_31: self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Friday), self.algorithm.TimeRules.At(10, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Friday), self.algorithm.TimeRules.At(15, 59), close_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Monday), self.algorithm.TimeRules.At(10, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Monday), self.algorithm.TimeRules.At(15, 59), close_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Wednesday), self.algorithm.TimeRules.At(10, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Wednesday), self.algorithm.TimeRules.At(15, 59), close_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Tuesday), self.algorithm.TimeRules.At(10, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Tuesday), self.algorithm.TimeRules.At(15, 59), close_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Thursday), self.algorithm.TimeRules.At(10, 31), open_window) self.algorithm.Schedule.On(self.algorithm.DateRules.Every(DayOfWeek.Thursday), self.algorithm.TimeRules.At(15, 59), close_window) def check_calendar(self): if calendar_info.USE_FOMC_MINUTES: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.FOMC_MINUTES: return True if calendar_info.USE_FOMC_MEETINGS: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.FOMC_MEETINGS: return True if calendar_info.USE_CPI: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.CPI: return True if calendar_info.USE_CPI_NEXTDAY: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.CPI_NEXTDAY: return True if calendar_info.USE_POWELL: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.POWELL: return True if calendar_info.USE_POWELL_NEXTDAY: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.POWELL_NEXTDAY: return True if calendar_info.USE_FED_INTEREST_RATE_DECISION: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.FED_INTEREST_RATE_DECISION: return True if calendar_info.USE_FED_INTEREST_RATE_DECISION_NEXTDAY: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.FED_INTEREST_RATE_DECISION_NEXTDAY: return True if calendar_info.USE_FOMC_MEETINGS_FIRSTDAY: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.FOMC_MEETINGS_FIRSTDAY: return True if calendar_info.DISABLE_SPX_WRONG_DATES: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.SPX_WRONG_DATES: return True if calendar_info.DISABLE_SPX_POTENTIALLY_WRONG_DATES: if self.algorithm.Time.strftime("%Y%-m%-d") in calendar_info.SPX_POTENTIALLY_WRONG_DATES: return True return False
#region imports from AlgorithmImports import * from datetime import * data_dictionary = {} QUANTITY = 20 USE_9_31 = True USE_10_31 = False ################################################################## RE ENTRY ######################################################################## USE_RE_ENTRY = False # Pick between "SAME CONDOR" and "ANY CONDOR" # SAME CONDOR will make it so that only the previously invested Iron Condor is Re entered, # ANY CONDOR will re enter any Iron Condor RE_ENTRY_MODE = "SAME CONDOR" # Pick between "STATIC" and "ENTRY MULTIPLIER" # STATIC is a static threshold, # ENTRY MULTIPLIER multiplies the previous entry premium and sets that as the new entry premium for the re-entry RE_ENTRY_THRESHOLD_MODE = "STATIC" # ENTRY MULTIPLIER multiplies the previous entry premium and sets that as the new entry premium for the re-entry RE_ENTRY_MULTIPLIER = 1.33 # STATIC is a static threshold RE_ENTRY_STATIC_PREMIUM = 0.50 RE_ENTRY_X_TIMES = 1 ################################################################## AVG DOWN ######################################################################## USE_AVG_DOWN = True # Pick between "PERCENTAGE" or "PIVOT POINT" or "PERCENTAGE PIVOT POINT" or "FIXED" or "FIXED PIVOT POINT" AVG_DOWN_MODE = "LAYERED" # True or False, # If True the most recent entry price of the condor will be used to calculate the AVG_DOWN_PERCENTAGE, otherwise the first entry of the day USE_MOST_RECENT_ENTRY = False # Fixed premium threshold at which we will average down FIXED_AVG_DOWN_PREMIUM = 2.50 # Percentage that premium needs to be higher than entry in order to average down, # 1.4 here would multiply the last entry premium by 1.4 AVG_DOWN_PERCENTAGE = 1.33 # The maximum amount of times averaging down is allowed per day AVG_DOWN_X_TIMES = 1 AVG_DOWN_QUANTITY = 10 ################################################################## SL AT ENTRY ######################################################################## USE_SL_AT_ENTRY = False # Profit Percentage that needs to be reached before allowing a stop loss at entry premium SL_AT_ENTRY_THRESHOLD = 75 # Pick between "FIRST ENTRY" or "MOST RECENT ENTRY" or "AVG ENTRY" # "FIRST ENTRY" will use the first entry to calculate the Profit Percentage, # "MOST RECENT ENTRY" will use the most recent entry to calculate the Profit Percentage, # "AVG ENTRY" will calculate the total average entry price and use that to calculate the Profit Percentage SL_AT_ENTRY_MODE = "FIRST ENTRY" ################################################################## STOP LOSS ######################################################################## # Pick between True or False USE_STOP_LOSS = False # Pick between "FIRST ENTRY" or "MOST RECENT ENTRY" or "AVG ENTRY" # "FIRST ENTRY" will use the first entry to calculate the Stop Percentage, # "MOST RECENT ENTRY" will use the most recent entry to calculate the Stop Percentage, # "AVG ENTRY" will calculate the total average entry price and use that to calculate the Stop Percentage STOP_LOSS_MODE = "FIRST ENTRY" # Multiplier applied to entry premium STOP_LOSS_MULTIPLIER = 10 # Pick between True or False USE_ABSOLUTE_STOP_LOSS = False # Premium above entry at which position will be closed ABSOLUTE_STOP_LOSS = 3 ################################################################## IRON CONDOR SETTINGS RANGE ######################################################################## # Pick between "FIXED" or "AUTOMATIC" # Fixed will use the MINIMUM and MAXIMUM DISTANCE below # Automatic will use the AUTOMATIC RANGE PERCENTAGES below RANGE_MODE = "AUTOMATIC" # Fixed Minimum Distance the Iron Condor needs to have from opening price of the day MINIMUM_DISTANCE = 1.5 # Fixed Maximum Distance the Iron Condor is allowed to have from opening price of the day # Need a maximum here since there will not always be an Iron Condor at an exact percentage, recommended for this to be 0.3% higher than, # the minimum above MAXIMUM_DISTANCE = 1.8 # Minimum Strike Difference MINIMUM_STRIKE_DIFFERENCE = 30 # Maximum Strike Difference MAXIMUM_STRIKE_DIFFERENCE = 30 # Control which range it is allowed to automatically select # Pick between 1, 1.5, 2, 2.5, 3 # If a number is included the set logic will be applied to automatically select that range if the conditions are met # Below are the conditions for each range: # 3% = VIX above 30 # 2.5% = VIX above 25 and ATR% above 2% # 2% = VIX below 25 or ATR% below 2% # 1.5% = VIX below 25 and ATR% below 2% # 1% = VIX below 20 and ATR% below 1.5% AUTOMATIC_RANGE_PERCENTAGES = [1, 1.5, 2, 2.5, 3] # Percentage added to the minimums in the list above to create the maximum for the ranges AUTOMATIC_RANGE_MAX_ADD = 0.3 # VIX Threshold for deciding if 3% range is needed VIX_THRESHOLD_1 = 30 # VIX Threshold for deciding if 2.5% or 2% range is needed VIX_THRESHOLD_2 = 25 # VIX Threshold for deciding if 1% or 1.5% range is needed VIX_THRESHOLD_3 = 20 # ATR Threshold for deciding if 1.5% or 2% or 2.5% range is needed ATR_THRESHOLD_1 = 0.02 # ATR Threshold for deciding if 1% or 1.5%range is needed ATR_THRESHOLD_2 = 0.02 ################################################################## IRON CONDOR SETTINGS PREMIUM ######################################################################## # Pick between "FIXED" or "ADJUSTED PREMIUM" or "FIXED PER RANGE" # "FIXED" selects the same fixed minimum premium for every range, # "ADJUSTED PREMIUM" uses the premium adjuster to automatically select the minimum premium for any range # "FIXED PER RANGE" selects a different fixed minimum premium per range PREMIUM_THRESHOLD_MODE = "ADJUSTED PREMIUM" # Lookback Length for the Average Premium that the Premium Adjuster Uses PREMIUM_ADJUST_LENGTH = 10 # Fixed Premium for all Ranges FIXED_PREMIUM = 0.70 # Fixed Premium if the range is 1% FIXED_PREMIUM_1 = 2.5 # Fixed Premium if the range is 1.5% FIXED_PREMIUM_1_5 = 2.50 # Fixed Premium if the range is 2% FIXED_PREMIUM_2 = 2.50 # Fixed Premium if the range is 2.5% FIXED_PREMIUM_2_5 = 2.50 # Fixed Premium if the range is 3% FIXED_PREMIUM_3 = 2.50 ################################################################## OTHER EXIT SETTINGS ######################################################################## # Pick between "FIRST ENTRY" or "MOST RECENT ENTRY" or "AVG ENTRY" # "FIRST ENTRY" will use the first entry to calculate the Profit Percentage, # "MOST RECENT ENTRY" will use the most recent entry to calculate the Profit Percentage, # "AVG ENTRY" will calculate the total average entry price and use that to calculate the Profit Percentage PROFIT_TAKING_MODE = "FIRST ENTRY" # Pick between True or False # This enables/disables the regular profit taking USE_REGULAR_PROFIT_TAKE = True # Profit percentage for regular profit taking, 50 = 50% profit REGULAR_PROFIT_PERCENTAGE = 50 # Pick between True or False # If within X Minutes after entry there is atleast X% of Profit then exit USE_TIMED_PROFIT_EXIT = False # If within X Minutes after entry there is atleast X% of Profit then exit MINUTES_AFTER_ENTRY = timedelta(minutes=60) # If within X Minutes after entry there is atleast X% of Profit then exit TIMED_PROFIT_PERCENTAGE = 50 # Pick between True or False # A simple timed exit in minutes after entry or fixed time of day, USE_TIMED_EXIT = True # Pick between "SIMPLE" or "FIXED TIME" # "SIMPLE" exits the position after X minutes regardless of time of day, profit/loss etc. # "FIXED TIME" exits the position at a fixed time of day regardless of how many minutes after entry, profit/loss etc. TIMED_EXIT_MODE = "SIMPLE" # "SIMPLE" exits the position after X minutes regardless of time of day, profit/loss etc. TIMED_EXIT_MINUTES = timedelta(minutes=10) # "FIXED TIME" exits the position at a fixed time of day regardless of how many minutes after entry, profit/loss etc. TIMED_EXIT_FIXED = time(hour=12, minute=0) ######################################################################################################################################## REGULAR_ENTRY_ACTIVE = False # Enables or disables use of trading quantity # True/False TRADING_QUANTITY_ACTIVE = True # If trading quantity profit taking mode is set to FIXED then this is applied TRADING_QUANTITY_FIXED_PROFIT = 1.50 # If trading quantity profit taking mode is set to PERCENTAGE then this is applied TRADING_PROFIT_PERCENTAGE = 50 # "PERCENTAGE" "FIXED" TRADING_PROFIT_TAKING_MODE = "PERCENTAGE" # This enables or disables the ATR entry for the trading quantity TRADING_ATR_ENTRY_ACTIVE = False TRADING_ENTRY_QUANTITY = 5 TRADING_ENTRY_QUANTITY_2 = 10 TRADING_ENTRY_QUANTITY_3 = 5 TRADING_ENTRY_THRESHOLD = 1 TRADING_ENTRY_THRESHOLD_2 = 3 TRADING_ENTRY_THRESHOLD_3 = 6 PREMIUM_THRESHOLD_REDUCE = 3 NEW_PREMIUM = 1.5 DAYS_BELOW_THRESHOLD = 5 DROP_PREMIUM_BY = 0.25 NO_ENTRY_AFTER = 1700
from AlgorithmImports import * from iron_condor import IronCondor import config class CreateCondors(): def __init__(self, algorithm): self.algorithm = algorithm def populate_lists(self, symbol, symbolData, open_price, min_range, max_range): put_list = [] call_list = [] #if optionschain is None: #return #for i in optionschain: #if i.Key != symbolData.option_symbol: continue # optionchain = i.Value #if (optionschain.Count == 0): #return price = self.algorithm.Securities[symbol].Price price = math.floor(price) if open_price is None: open_price = self.algorithm.Securities[symbol].Open #self.algorithm.Debug(f"{self.algorithm.Time} {open_price}") price = self.algorithm.Securities[symbol].Price price = math.floor(price) if open_price is None: open_price = self.algorithm.Securities[symbol].Open #self.algorithm.Debug(f"{self.algorithm.Time} {open_price}") put_3_expiry = self.generate_price_list(open_price, direction="PUT")#[x for x in optionschain if x.Right == OptionRight.Put and ((x.Expiry - self.algorithm.Time).days) == -1 and (x.Strike - price) < 1] call_3_expiry = self.generate_price_list(open_price, direction="CALL")#[x for x in optionschain if x.Right == OptionRight.Call and ((x.Expiry - self.algorithm.Time).days) == -1 and (price - x.Strike) < 1] self.algorithm.Debug(f"LEN PUTS {len(put_3_expiry)}") self.algorithm.Debug(f"LEN CALLS {len(call_3_expiry)}") self.algorithm.Debug(put_3_expiry) self.algorithm.Debug(call_3_expiry) put_3_min_distances_sorted_sell = sorted(put_3_expiry, reverse=True) call_3_min_distances_sorted_sell = sorted(call_3_expiry, reverse=False) put_3_min_distances_sorted_buy = sorted(put_3_expiry, reverse=True) call_3_min_distances_sorted_buy = sorted(call_3_expiry, reverse=False) for x in put_3_min_distances_sorted_sell: for y in put_3_min_distances_sorted_buy: strike_diff = x - y if x > y and strike_diff >= config.MINIMUM_STRIKE_DIFFERENCE and strike_diff <= config.MAXIMUM_STRIKE_DIFFERENCE: open_put_range = abs((x - open_price) / open_price) if open_put_range >= min_range and open_put_range <= max_range: combo = (x, y) put_list.append(combo) # for x in put_3_min_distances_sorted_sell: # for y in put_3_min_distances_sorted_buy: # strike_diff = x.Strike - y.Strike # if x.Strike > y.Strike and strike_diff >= config.MINIMUM_STRIKE_DIFFERENCE and strike_diff <= config.MAXIMUM_STRIKE_DIFFERENCE: # combo = (x, y) # put_list.append(combo) # put_list = [(x, y) for x in put_3_min_distances_sorted_sell for y in put_3_min_distances_sorted_buy if x.Strike > y.Strike and x.Strike - y.Strike >= config.MINIMUM_STRIKE_DIFFERENCE and x.Strike - y.Strike <= config.MAXIMUM_STRIKE_DIFFERENCE] # call_list = [(x, y) for x in call_3_min_distances_sorted_sell for y in call_3_min_distances_sorted_buy if y.Strike > x.Strike and y.Strike - x.Strike >= config.MINIMUM_STRIKE_DIFFERENCE and y.Strike - x.Strike <= config.MAXIMUM_STRIKE_DIFFERENCE] #call_list = [(x, y) for x, y in product(call_3_min_distances_sorted_sell, call_3_min_distances_sorted_buy) if y.Strike > x.Strike and y.Strike - x.Strike >= config.MINIMUM_STRIKE_DIFFERENCE and y.Strike - x.Strike <= config.MAXIMUM_STRIKE_DIFFERENCE] for x in call_3_min_distances_sorted_sell: for y in call_3_min_distances_sorted_buy: strike_diff = y - x if y > x and strike_diff >= config.MINIMUM_STRIKE_DIFFERENCE and strike_diff <= config.MAXIMUM_STRIKE_DIFFERENCE: open_call_range = ((x - open_price) / open_price) if open_call_range >= min_range and open_call_range <= max_range: combo = (x, y) call_list.append(combo) return self.create_combinations(min_range, max_range, put_list, call_list, open_price, symbol) def generate_price_list(self, open_price, increment=5, percentage_range=0.02, direction="CALL"): # Calculate the price variation variation = open_price * percentage_range # Calculate the lower and upper bounds, rounded to the nearest increment lower_bound = round((open_price - variation) / increment) * increment upper_bound = round((open_price + variation) / increment) * increment if direction == "CALL": lower_bound = round((open_price) / increment) * increment if direction == "PUT": upper_bound = round((open_price) / increment) * increment # Generate the list of prices price_list = list(range(lower_bound, upper_bound + increment, increment)) # Ensure the open price is included and is the first element, rounded to nearest increment open_price_rounded = round(open_price / increment) * increment if open_price_rounded not in price_list: price_list.insert(0, open_price_rounded) return price_list def create_combinations(self, min_range, max_range, put_list, call_list, open_price, symbol): keys = [] condors = {} appended_1 = None appended_1_5 = None appended_2 = None appended_2_5 = None appended_3 = None #symbol = Symbol.Create("SPX", SecurityType.Index, Market.USA) self.algorithm.Debug("IN CREATE COMBINATIONS") for ps, pb in put_list: for cs, cb in call_list: p_diff = ps - pb c_diff = cb- cs if cs > ps and p_diff == c_diff and open_price is not None: open_call_range = ((cs - open_price) / open_price) open_put_range = abs((ps - open_price) / open_price) Strikes = f"{pb} {ps} {cs} {cb} {open_call_range} {open_put_range} {p_diff}" if Strikes not in condors: cb_1 = Symbol.CreateOption(symbol, "SPXW", Market.USA, OptionStyle.European, OptionRight.Call, cb, datetime(self.algorithm.Time.year, self.algorithm.Time.month, self.algorithm.Time.day)) cs_1 = Symbol.CreateOption(symbol, "SPXW", Market.USA, OptionStyle.European, OptionRight.Call, cs, datetime(self.algorithm.Time.year, self.algorithm.Time.month, self.algorithm.Time.day)) ps_1 = Symbol.CreateOption(symbol, "SPXW", Market.USA, OptionStyle.European, OptionRight.Put, ps, datetime(self.algorithm.Time.year, self.algorithm.Time.month, self.algorithm.Time.day)) pb_1 = Symbol.CreateOption(symbol, "SPXW", Market.USA, OptionStyle.European, OptionRight.Put, pb, datetime(self.algorithm.Time.year, self.algorithm.Time.month, self.algorithm.Time.day)) cb_1 = self.algorithm.AddIndexOptionContract(cb_1, Resolution.Minute) cs_1 = self.algorithm.AddIndexOptionContract(cs_1, Resolution.Minute) ps_1 = self.algorithm.AddIndexOptionContract(ps_1, Resolution.Minute) pb_1 = self.algorithm.AddIndexOptionContract(pb_1, Resolution.Minute) condors[Strikes] = IronCondor(self.algorithm, pb_1, ps_1, cb_1, cs_1, open_call_range, open_put_range, ps_1.Expiry) max_max = (max_range + 0.003) if open_put_range >= min_range and open_call_range >= min_range and open_put_range <= max_max and open_call_range <= max_max: diff = abs(open_call_range - open_put_range) percent = (open_call_range + open_put_range) / 2 tup = (Strikes, percent, diff, p_diff) keys.append(tup) if appended_2_5 is None and open_call_range >= 0.024 and open_call_range <= 0.027 and open_put_range >= 0.024 and open_put_range <= 0.027: condor = condors[Strikes] appended_2_5 = condor if appended_2 is None and open_call_range >= 0.02 and open_call_range <= 0.022 and open_put_range >= 0.02 and open_put_range <= 0.022: condor = condors[Strikes] appended_2 = condor if appended_3 is None and open_call_range >= 0.03 and open_call_range <= 0.032 and open_put_range >= 0.03 and open_put_range <= 0.032: condor = condors[Strikes] appended_3 = condor if appended_1_5 is None and open_call_range >= 0.015 and open_call_range <= 0.017 and open_put_range >= 0.015 and open_put_range <= 0.017: condor = condors[Strikes] appended_1_5 = condor if appended_1 is None and open_call_range >= 0.01 and open_call_range <= 0.013 and open_put_range >= 0.01 and open_put_range <= 0.013: condor = condors[Strikes] appended_1 = condor return condors, keys, appended_1, appended_1_5, appended_2, appended_2_5, appended_3
from AlgorithmImports import * class DataManager(): def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol self.callables = config.data_dictionary self.consolidators = {} self.indicators = {} for key, value in self.callables.items(): for tup in value: # tup is one of the tuples in the list # you can unpack the tuple into variables here function, indicator_name, indicator, period, consolidator_name, resolution, delta = tup if consolidator_name not in self.consolidators: function_receive = self.create_receive_bar_function() self.consolidators[consolidator_name] = TradeBarConsolidator(delta) self.algorithm.SubscriptionManager.AddConsolidator(self.symbol, self.consolidators[consolidator_name]) self.consolidators[consolidator_name].DataConsolidated += function_receive
from AlgorithmImports import * import config class EntryManager(): def __init__(self, algorithm, symbol, re_entry_manager, avg_down_manager): self.algo = algorithm self.symbol = symbol self.re_entry_manager = re_entry_manager self.avg_down_manager = avg_down_manager ############################################################################################ self.use_trading_quantity = config.TRADING_QUANTITY_ACTIVE def check_re_entry(self, condors, keys, min_range, max_range, premium_threshold): price = self.algo.Securities[self.symbol].Price if self.algo.Portfolio.Invested > 0: invested = True else: invested = False if self.re_entry_manager.check_permission(invested): for key in keys: condor = condors[key[0]] if self.re_entry_manager.re_entry_mode == "SAME CONDOR" and key != self.re_entry_manager.allowed_condor: continue else: if condor.calculate_premium() >= self.re_entry_manager.get_new_threshold() and condor.check_range(min_range, max_range): self.algo.MarketOrder(condor.Put_Buy.Symbol, config.QUANTITY, tag =f"RE ENTRY {condor.open_put_range} Strike {condor.Put_Buy.Strike} pm {condor.Premium} Price {price}") self.algo.MarketOrder(condor.Put_Sell.Symbol, -config.QUANTITY, tag =f"RE ENTRY {condor.open_put_range} Strike {condor.Put_Sell.Strike} pm {condor.Premium} Price {price}") self.algo.MarketOrder(condor.Call_Buy.Symbol, config.QUANTITY, tag =f"RE ENTRY {condor.open_call_range} Strike {condor.Call_Buy.Strike} pm {condor.Premium} Price {price}") self.algo.MarketOrder(condor.Call_Sell.Symbol, -config.QUANTITY, tag =f"RE ENTRY {condor.open_call_range} Strike {condor.Call_Sell.Strike} pm {condor.Premium} Price {price}") self.re_entry_manager.allowed_condor = key self.re_entry_manager.previous_premium = condor.Premium self.re_entry_manager.entered_today = True self.re_entry_manager.entry_count_today += 1 condor.entry_premiums.clear() condor.entry_premium = condor.Premium condor.calculate_avg_entry() condor.entry_time = self.algo.Time condor.first_entry = condor.Premium return condor def get_target_quantity(self, contract, target_quantity): total_quantity = 0 # Iterate over each entry for entry, info in self.avg_down_manager.avg_down_layers.items(): # Check if the boolean value is True if info[1]: # Add the quantity to the total total_quantity += info[0] if target_quantity < 0: total_quantity = -total_quantity target_quantity += total_quantity # Get the current quantity of the contract in the portfolio. It can be negative or positive. current_quantity = self.algo.Portfolio[contract.Symbol].Quantity self.algo.Debug(f"Current quantity {contract.Symbol} {current_quantity}") # Calculate the quantity needed to reach the target. If the target or current is negative, # this calculation will account for it and return the correct adjustment amount. quantity_needed = target_quantity - current_quantity # Return the calculated quantity needed to reach the target. return quantity_needed def complete_trade(self, layer, condor, quantity, key): for key_ in layer: condor.active_layers.append(key_) condor.trading_entries += 1 condor.entry_premiums_trading[condor.trading_entries] = [condor.Premium, quantity, True] self.re_entry_manager.allowed_condor = key self.re_entry_manager.previous_premium = condor.Premium self.re_entry_manager.entered_today = True self.avg_down_manager.entered_condor = condor self.avg_down_manager.entered_key = key self.avg_down_manager.avg_down_counter += 1 # condor.entry_premium = condor.Premium # condor.calculate_avg_entry() if condor.first_entry_time is None: condor.first_entry_time = int(self.algo.Time.strftime("%H%M").replace(":", "")) condor.entry_time = int(self.algo.Time.strftime("%H%M").replace(":", "")) condor.is_re_entry = False if self.avg_down_manager.first_entry is None: self.avg_down_manager.first_entry = condor.Premium if condor.first_entry is None: condor.first_entry = condor.Premium # self.ago.Debug("ENTRY") return condor, None def check_avg_down(self, condors, keys, min_range, max_range, premium_threshold): price = self.algo.Securities[self.symbol].Price if self.algo.Portfolio.Invested > 0: invested = True else: invested = False if invested or self.use_trading_quantity: for key in keys: if key != self.avg_down_manager.entered_key and not self.use_trading_quantity: continue condor = condors[key[0]] avg_down_sig, quantity, layer = self.avg_down_manager.check_avg_down(condor) if avg_down_sig: self.algo.Debug(f"{self.algo.Time} AVERAGED DOWN") # self.algo.MarketOrder(condor.Put_Buy.Symbol, quantity, tag =f"AVG DOWN {condor.open_put_range} Strike {condor.Put_Buy.Strike} pm {condor.Premium} Price {price}") # self.algo.MarketOrder(condor.Put_Sell.Symbol, -quantity, tag =f"AVG DOWN {condor.open_put_range} Strike {condor.Put_Sell.Strike} pm {condor.Premium} Price {price}") # self.algo.MarketOrder(condor.Call_Buy.Symbol, quantity, tag =f"AVG DOWN {condor.open_call_range} Strike {condor.Call_Buy.Strike} pm {condor.Premium} Price {price}") # self.algo.MarketOrder(condor.Call_Sell.Symbol, -quantity, tag =f"AVG DOWN {condor.open_call_range} Strike {condor.Call_Sell.Strike} pm {condor.Premium} Price {price}") legs = [] # legs.append(Leg.Create(condor.Put_Buy.Symbol, 1)) # legs.append(Leg.Create(condor.Put_Sell.Symbol, -1)) # legs.append(Leg.Create(condor.Call_Buy.Symbol, 1)) # legs.append(Leg.Create(condor.Call_Sell.Symbol, -1)) # self.algo.ComboMarketOrder(legs, quantity) weekly_canonical_symbol = Symbol.CreateCanonicalOption(self.symbol, "SPXW", Market.USA, "?SPXW") self.algo.Transactions.CancelOpenOrders() call_buy = condor.Call_Buy call_sell = condor.Call_Sell put_sell = condor.Put_Sell put_buy = condor.Put_Buy call_buy_quantity = self.get_target_quantity(call_buy, quantity) call_sell_quantity = self.get_target_quantity(call_sell, -quantity) put_sell_quantity = self.get_target_quantity(put_sell, -quantity) put_buy_quantity = self.get_target_quantity(put_buy, quantity) self.algo.Debug(f"{quantity} {call_buy_quantity} {call_sell_quantity} {put_sell_quantity} {put_buy_quantity}") if call_buy_quantity == quantity and call_sell_quantity == -quantity and put_sell_quantity == -quantity and put_buy_quantity == quantity: condor.partial = False legs.append(Leg.Create(condor.Call_Buy.Symbol, 1)) legs.append(Leg.Create(condor.Call_Sell.Symbol, -1)) legs.append(Leg.Create(condor.Put_Sell.Symbol, -1)) legs.append(Leg.Create(condor.Put_Buy.Symbol, 1)) self.algo.ComboMarketOrder(legs, quantity) return self.complete_trade(layer, condor, quantity, key) elif call_sell_quantity == -quantity and put_sell_quantity == -quantity and call_buy_quantity == 0 and put_buy_quantity == 0: condor.partial = False legs.append(Leg.Create(condor.Call_Sell.Symbol, -1)) legs.append(Leg.Create(condor.Put_Sell.Symbol, -1)) self.algo.ComboMarketOrder(legs, quantity) return self.complete_trade(layer, condor, quantity, key) else: condor.partial = True if call_buy_quantity != quantity: condor.partial_orders.append(self.algo.MarketOrder(call_buy.Symbol, call_buy_quantity)) if call_sell_quantity != quantity: condor.partial_orders.append(self.algo.MarketOrder(call_sell.Symbol, call_sell_quantity)) if put_sell_quantity != quantity: condor.partial_orders.append(self.algo.MarketOrder(put_sell.Symbol, put_sell_quantity)) if put_buy_quantity != quantity: condor.partial_orders.append(self.algo.MarketOrder(put_buy.Symbol, put_buy_quantity)) # iron_condor = OptionStrategies.IronCondor( # weekly_canonical_symbol, # condor.Put_Buy.StrikePrice, # condor.Put_Sell.StrikePrice, # condor.Call_Sell.StrikePrice, # condor.Call_Buy.StrikePrice, # condor.Put_Sell.Expiry) # self.algo.Buy(iron_condor, quantity) # for key_ in layer: # condor.active_layers.append(key_) # condor.trading_entries += 1 # condor.entry_premiums_trading[condor.trading_entries] = [condor.Premium, quantity, True] # self.re_entry_manager.allowed_condor = key # self.re_entry_manager.previous_premium = condor.Premium # self.re_entry_manager.entered_today = True # self.avg_down_manager.entered_condor = condor # self.avg_down_manager.entered_key = key # self.avg_down_manager.avg_down_counter += 1 # # condor.entry_premium = condor.Premium # # condor.calculate_avg_entry() # if condor.first_entry_time is None: # condor.first_entry_time = int(self.algo.Time.strftime("%H%M").replace(":", "")) # condor.entry_time = int(self.algo.Time.strftime("%H%M").replace(":", "")) # condor.is_re_entry = False # if self.avg_down_manager.first_entry is None: # self.avg_down_manager.first_entry = condor.Premium # if condor.first_entry is None: # condor.first_entry = condor.Premium # # self.ago.Debug("ENTRY") # return condor, None ##### # self.re_entry_manager.allowed_condor = key # self.re_entry_manager.previous_premium = condor.Premium # self.re_entry_manager.entered_today = True # self.avg_down_manager.entered_condor = condor # self.avg_down_manager.entered_key = key # self.avg_down_manager.avg_down_counter += 1 # condor.entry_premium = condor.Premium # condor.calculate_avg_entry() # condor.entry_time = self.algorithm.Time # if self.avg_down_manager.first_entry is None: # self.avg_down_manager.first_entry = condor.Premium # if condor.first_entry is None: # condor.first_entry = condor.Premium # return condor return None, None def check_regular(self, condors, keys, min_range, max_range, premium_threshold, open_price): price = self.algo.Securities[self.symbol].Price if self.algo.Portfolio.Invested > 0: invested = True else: invested = False if not invested and not self.re_entry_manager.entered_today: for key in keys: condor = condors[key[0]] #self.algorithm.Debug(f"{condor.Calculate_Premium()} {premium_threshold} {condor.check_range(min_range, max_range)}") if condor.calculate_premium() >= premium_threshold and condor.check_range(min_range, max_range): #self.algorithm.Debug(f" HERE {self.algorithm.Time} {open_price}") self.algo.MarketOrder(condor.Put_Buy.Symbol, config.QUANTITY, tag =f"REGULAR ENTRY {condor.open_put_range} Strike {condor.Put_Buy.Strike} pm {condor.Premium} Price {price} {open_price} {condor.Expiry}") self.algo.MarketOrder(condor.Put_Sell.Symbol, -config.QUANTITY, tag =f"REGULAR ENTRY {condor.open_put_range} Strike {condor.Put_Sell.Strike} pm {condor.Premium} Price {price} {open_price} {condor.Expiry}") self.algo.MarketOrder(condor.Call_Buy.Symbol, config.QUANTITY, tag =f"REGULAR ENTRY {condor.open_call_range} Strike {condor.Call_Buy.Strike} pm {condor.Premium} Price {price} {open_price} {condor.Expiry}") self.algo.MarketOrder(condor.Call_Sell.Symbol, -config.QUANTITY, tag =f"REGULAR ENTRY {condor.open_call_range} Strike {condor.Call_Sell.Strike} pm {condor.Premium} Price {price} {open_price} {condor.Expiry}") self.re_entry_manager.allowed_condor = key self.re_entry_manager.previous_premium = condor.Premium self.re_entry_manager.entered_today = True self.avg_down_manager.entered_condor = condor self.avg_down_manager.entered_key = key condor.entry_premium = condor.Premium condor.calculate_avg_entry() condor.entry_time = self.algo.Time if self.avg_down_manager.first_entry is None: self.avg_down_manager.first_entry = condor.Premium if condor.first_entry is None: condor.first_entry = condor.Premium return condor
from AlgorithmImports import * import config class ExitManager(): def __init__(self, algorithm, symbol, close_trading_window): self.algo = algorithm self.symbol = symbol self.avg_down_manager = None self.use_stop_loss = config.USE_STOP_LOSS self.stop_loss_mode = config.STOP_LOSS_MODE self.stop_loss_multiplier = config.STOP_LOSS_MULTIPLIER self.use_absolute_stop_loss = config.USE_ABSOLUTE_STOP_LOSS self.absolute_stop_loss = config.ABSOLUTE_STOP_LOSS self.use_regular_profit_take = config.USE_REGULAR_PROFIT_TAKE self.profit_taking_mode = config.PROFIT_TAKING_MODE self.regular_profit_percentage = 1 - (config.REGULAR_PROFIT_PERCENTAGE/100) self.use_timed_profit_exit = config.USE_TIMED_PROFIT_EXIT self.minutes_after_entry = config.MINUTES_AFTER_ENTRY self.timed_profit_percentage = 1 - (config.TIMED_PROFIT_PERCENTAGE/100) self.use_timed_exit = config.USE_TIMED_EXIT self.timed_exit_mode = config.TIMED_EXIT_MODE self.timed_Exit_minutes = config.TIMED_EXIT_MINUTES self.timed_exit_fixed = config.TIMED_EXIT_FIXED ################################################################################################### self.use_trading_quantity = config.TRADING_QUANTITY_ACTIVE self.trading_profit_taking_mode = config.TRADING_PROFIT_TAKING_MODE self.trading_quantity_fixed_profit = config.TRADING_QUANTITY_FIXED_PROFIT self.trading_profit_percentage = config.TRADING_PROFIT_PERCENTAGE/100 #self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.BeforeMarketClose(self.symbol, 1), close_trading_window) def check_stop_loss(self, condor): if self.stop_loss_mode == "FIRST ENTRY": if condor.Calculate_Premium >= condor.first_entry * self.stop_loss_multiplier: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) elif self.stop_loss_mode == "MOST RECENT ENTRY": if condor.Calculate_Premium >= condor.entry_premium * self.stop_loss_multiplier: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) elif self.stop_loss_mode == "AVG ENTRY": if condor.Calculate_Premium >= condor.avg_entry * self.stop_loss_multiplier: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) else: raise Exception(f"Please input a correct STOP LOSS MODE in the config file. {config.STOP_LOSS_MODE} is incorrect") def check_absolute_stop_loss(self, condor): if self.stop_loss_mode == "FIRST ENTRY": if condor.Calculate_Premium() >= condor.first_entry + self.absolute_stop_loss: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) elif self.stop_loss_mode == "MOST RECENT ENTRY": if condor.Calculate_Premium() >= condor.entry_premium + self.absolute_stop_loss: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) elif self.stop_loss_mode == "AVG ENTRY": if condor.Calculate_Premium() >= condor.avg_entry + self.absolute_stop_loss: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) def check_regular_profit_take(self, condor): if not self.use_trading_quantity: if self.profit_taking_mode == "FIRST ENTRY": if condor.Calculate_Premium() <= condor.first_entry * self.regular_profit_percentage: self.algo.Liquidate(condor.Call_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from FIRST ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Call_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from FIRST ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from FIRST ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from FIRST ENTRY Premium {condor.Premium}") elif self.profit_taking_mode == "MOST RECENT ENTRY": if condor.Calculate_Premium() <= condor.entry_premium * self.regular_profit_percentage: self.algo.Liquidate(condor.Call_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from MOST RECENT ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Call_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from MOST RECENT ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from MOST RECENT ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from MOST RECENT ENTRY Premium {condor.Premium}") elif self.profit_taking_mode == "AVG ENTRY": if condor.Calculate_Premium() <= condor.avg_entry * self.regular_profit_percentage: self.algo.Liquidate(condor.Call_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Call_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") ############################################################################################################# if self.use_trading_quantity and condor: premium = condor.calculate_premium() condor.calculate_trading_entry_avg_premium() if condor.avg_trading_premium != 0: current_profit = (condor.avg_trading_premium - premium) self.algo.Debug(current_profit) if self.trading_profit_taking_mode == "FIXED" and current_profit >= self.trading_quantity_fixed_profit: for layer in condor.active_layers: self.avg_down_manager.avg_down_layers[layer][1] = False condor.active_layers.clear() condor.current_trading_quantity = 0 self.algo.Liquidate(condor.Call_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Call_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") profit_percentage = self.trading_profit_percentage # if self.use_adjusted_profit_take: # start_day_con = True if int( # self.spx_info.time.replace(":", "")) >= self.profit_adjust_time else False # profit_percentage = self.adjusted_profit if self.trading_profit_taking_mode == "PERCENTAGE" and current_profit >= (condor.avg_trading_premium * profit_percentage): for layer in condor.active_layers: self.avg_down_manager.avg_down_layers[layer][1] = False condor.active_layers.clear() condor.current_trading_quantity = 0 self.algo.Liquidate(condor.Call_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Call_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Sell.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") self.algo.Liquidate(condor.Put_Buy.Symbol, tag=f"REGULAR PROFIT TAKE at {config.REGULAR_PROFIT_PERCENTAGE}% from AVG ENTRY Premium {condor.Premium}") def check_timed_profit_exit(self, condor): if self.algo.Time <= condor.entry_time + self.minutes_after_entry: if self.profit_taking_mode == "FIRST ENTRY": if condor.Calculate_Premium() <= condor.first_entry * self.timed_profit_percentage: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) elif self.profit_taking_mode == "MOST RECENT ENTRY": if condor.Calculate_Premium() <= condor.entry_premium * self.timed_profit_percentage: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) elif self.profit_taking_mode == "AVG ENTRY": if condor.Calculate_Premium() <= condor.avg_entry * self.timed_profit_percentage: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) def check_timed_exit(self, condor): if self.timed_exit_mode == "SIMPLE": if condor.entry_time + self.timed_Exit_minutes >= self.algo.Time: self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol) elif self.timed_exit_mode == "FIXED TIME": if self.timed_exit_fixed.strftime("%H%M") >= self.algo.Time.strftime("%H%M"): self.algo.Liquidate(condor.Call_Sell.Symbol) self.algo.Liquidate(condor.Call_Buy.Symbol) self.algo.Liquidate(condor.Put_Sell.Symbol) self.algo.Liquidate(condor.Put_Buy.Symbol)
#region imports from AlgorithmImports import * from collections import deque #endregion import config import statistics as stats class IronCondor(): def __init__(self, algorithm, put_buy, put_sell, call_buy, call_sell, open_call_range, open_put_range, expiry): self.algo = algorithm self.Put_Buy = put_buy self.Put_Sell = put_sell self.Call_Buy = call_buy self.Call_Sell = call_sell self.Sent_Already = False self.Premium = None self.entry_premium = None self.Entry_Fees = None self.partial = False self.partial_orders = [] self.first_entry = None self.entry_premiums = [] self.avg_entry = None self.Expiry = expiry self.Lowest_Premium = None self.Scanned_Already = False self.entry_time = None self.Reached_Threshold = False self.Profit = None self.Stopped_Out = False self.Profit_Taken = False self.Current_Profit = None self.Margin_Required = None self.open_call_range = open_call_range self.open_put_range = open_put_range self.Sent_Open_Range = False self.Highest_Premium = -1000000 self.Weight = 0 self.Entered_Increments = [] #self.Avg_Down_Type = config.AVG_DOWN_TYPE #self.Underlying_Increment = config.UNDERLYING_PERCENT_MOVE_INCREMENT/100 self.Pivot_Queue = deque(maxlen=3) ########################################################################################## self.active_layers = [] self.first_entry_time = None self.entry_premiums_trading = {} self.avg_trading_premium = None self.trading_entries = 0 self.max_trading_quantity = config.AVG_DOWN_QUANTITY self.current_trading_quantity = 0 def check_range(self, min_range, max_range): if self.open_call_range >= min_range and self.open_put_range >= min_range and self.open_call_range <= max_range and self.open_put_range <= max_range: return True else: return False def calculate_trading_entry_avg_premium(self): length = 0 total_quantity = 0 total_value = 0 for entry, info in self.entry_premiums_trading.items(): premium, quantity, is_open = info if is_open: length += 1 total_quantity += quantity total_value += (premium * quantity) if length > 0: self.avg_trading_premium = total_value / total_quantity else: self.avg_trading_premium = 0 self.current_trading_quantity = total_quantity # self.algo.Debug(self.entry_premiums_trading) return self.avg_trading_premium def calculate_avg_entry(self): self.entry_premiums.append(self.entry_premium) self.avg_entry = stats.mean(self.entry_premiums) def calculate_premium(self): cs_premium = self.algo.Securities[self.Call_Sell.Symbol].BidPrice cb_premium = self.algo.Securities[self.Call_Buy.Symbol].AskPrice ps_premium = self.algo.Securities[self.Put_Sell.Symbol].BidPrice pb_premium = self.algo.Securities[self.Put_Buy.Symbol].AskPrice call_premium = cs_premium - cb_premium put_premium = ps_premium - pb_premium list_of_ba = [-pb_premium, ps_premium, -cb_premium, cs_premium] self.Premium = sum(list_of_ba) #self.algo.Debug(f"pb ask {pb_premium} ps bid {ps_premium} cs bid {cs_premium} cb ask {cb_premium}") #self.algo.Debug(f"pb ask {self.Call_Sell.AskPrice} ps bid {self.Put_Sell.BidPrice} cs bid {self.Call_Sell.BidPrice} cb ask {self.Call_Buy.AskPrice}") return self.Premium #def Calculate_Underlying_Re_Entry(self): #if
# region imports from AlgorithmImports import * from symboldata import SymbolData from create_condors import CreateCondors from select_range import SelectRange from adjust_premium import PremiumThresholdAdjuster from select_premium import PremiumSelecter from re_entry import ReEntry from entry import EntryManager from avg_down import AvgDown from exits import ExitManager from check_calendar import CheckCalendar import config import yfinance as yf class AlertBlackBull(QCAlgorithm): def Initialize(self): self.SetStartDate(2023, 1, 1) # Set Start Date self.SetEndDate(2024, 3, 20) self.SetCash(1000000) # Set Strategy Cash #self.symbol = self.AddIndex("SPX", Resolution.Minute).Symbol self.symbol = self.AddIndex("SPX", Resolution.Minute).Symbol self.condor_creator = CreateCondors(self) self.range_selector = SelectRange(self, self.symbol) self.premium_adjuster = PremiumThresholdAdjuster(self, self.symbol) self.premium_selector = PremiumSelecter(self) self.re_entry_manager = ReEntry(self, self.symbol) self.avg_down_manager = AvgDown(self, self.symbol) self.entry_manager = EntryManager(self, self.symbol, self.re_entry_manager, self.avg_down_manager) self.exit_manager = ExitManager(self, self.symbol, self.close_if_at_loss) self.calendar_checker = CheckCalendar(self, self.close_trading_window, self.open_window, self.close_window) self.exit_manager.avg_down_manager = self.avg_down_manager self.symbol_dictionary = {} self.symbol_dictionary[self.symbol] = SymbolData(self, self.symbol) self.created_combinations_today = False self.trading_window = False self.open_price = None self.today_condors = None self.today_keys = None self.todays_premium = None self.todays_min_range = None self.todays_max_range = None self.invested_condor = None ################################################################### self.use_regular_entry = config.REGULAR_ENTRY_ACTIVE self.key = config.TRADING_ENTRY_THRESHOLD self.threshold = config.PREMIUM_THRESHOLD_REDUCE self.org_layer = [config.TRADING_ENTRY_QUANTITY, False] self.new_premium = config.NEW_PREMIUM self.gradual_premium = float(config.TRADING_ENTRY_THRESHOLD) self.key_2 = config.TRADING_ENTRY_THRESHOLD_2 self.key_3 = config.TRADING_ENTRY_THRESHOLD_3 self.max_count = config.DAYS_BELOW_THRESHOLD self.drop_by = config.DROP_PREMIUM_BY self.current_key = self.key self.today_below = True self.latest_time = config.NO_ENTRY_AFTER self.first_data_point = True def open_window(self): self.Debug(self.Time) self.open_price = self.Securities[self.symbol].Open self.get_open_yfinance() self.trading_window = True if self.calendar_checker.check_calendar(): self.trading_window = False self.Debug(f"{self.Time} {self.open_price}") def close_window(self): #self.close_if_at_loss() self.created_combinations_today = False self.trading_window = False self.today_condors = None self.today_keys = None self.todays_premium = None self.todays_min_range = None self.todays_max_range = None self.invested_condor = None self.open_price = None self.premium_adjuster.run_append() self.premium_adjuster.reset_premium_adjuster() self.re_entry_manager.reset() self.avg_down_manager.reset() def close_trading_window(self): self.Liquidate() self.created_combinations_today = False self.trading_window = False self.today_condors = None self.today_keys = None self.todays_premium = None self.todays_min_range = None self.todays_max_range = None self.invested_condor = None self.re_entry_manager.reset() self.avg_down_manager.reset() def OnOrderEvent(self, orderEvent: OrderEvent) -> None: order = self.Transactions.GetOrderById(orderEvent.OrderId) if orderEvent.Status == OrderStatus.Filled: if self.invested_condor is not None and orderEvent.OrderId in self.invested_condor.partial_orders: self.invested_condor.partial_orders.remove(orderEvent.OrderId) if self.invested_condor is not None and len(self.invested_condor.partial_orders) == 0 and self.invested_condor.partial: self.invested_condor.partial = False self.entry_manager.check_avg_down(self.today_condors, self.today_keys, self.todays_min_range, self.todays_max_range, self.todays_premium) def close_if_at_loss(self): if self.invested_condor is not None: #self.Debug(f"{self.Securities[self.symbol].High+0.2} {self.Securities[self.symbol].Low-0.2}") if self.Securities[self.symbol].High+0.2 >= self.invested_condor.Call_Sell.Strike: #self.Debug(f"{self.Time} {self.invested_condor}") self.Liquidate(tag="At loss") elif self.Securities[self.symbol].Low-0.2 <= self.invested_condor.Put_Sell.Strike: #self.Debug(f"{self.Time} {self.invested_condor}") self.Liquidate(tag="At loss") def get_open_yfinance(self): try: spx = yf.Ticker('^GSPC') # Get historical data for the SPX historical_data = spx.history(period='1d') # Get the most recent date and open price latest_open_price = historical_data['Open'].iloc[-1] # Get the most recent date and open price latest_date = historical_data.index[-1].strftime('%Y-%m-%d') if latest_date == self.Time.strftime("%Y-%m-%d"): if latest_open_price is not None and latest_open_price != 0 and latest_open_price < 100000: self.open_price = latest_open_price except: self.Debug(f"No yahoo data at {self.Time}") def OnData(self, slice): if self.first_data_point: self.open_window() self.first_data_point = False self.Debug(f"IN ON DATA {self.Time}") if self.trading_window: for symbol, symbolData in self.symbol_dictionary.items(): #chain = slice.OptionChains.GetValue(symbolData.option_symbol) #self.Debug(f"chain {chain}") self.Debug(f"SPX PRICE {self.Securities[self.symbol].Open}") if not self.created_combinations_today: min_range, max_range = self.range_selector.set_range_today() self.todays_min_range = min_range self.todays_max_range = max_range if self.open_price is None: self.open_price = self.Securities[self.symbol].Open self.Debug(f"{self.Time} WTF {self.open_price}") #if chain is None: # self.Debug(f"WHY ARE WE NOT RETURNING {chain}") #return condors, keys, appended_1, appended_1_5, appended_2, appended_2_5, appended_3 = self.condor_creator.populate_lists(self.symbol, symbolData, self.open_price, min_range, max_range) self.today_condors = condors keys.sort(key=lambda tup: (tup[1], tup[2], -tup[3]), reverse=False) self.today_keys = keys #self.Debug(f"{appended_1} {appended_1_5} {appended_2} {appended_2_5} {appended_3}") self.premium_adjuster.receive_condors(appended_1, appended_1_5, appended_2, appended_2_5, appended_3) #adjustable_premium_today = self.premium_adjuster.return_premium_today(min_range) self.todays_premium = self.premium_selector.select_premium(min_range, 1) self.created_combinations_today = True self.Debug(f"LEN {len(keys)}") if self.invested_condor is not None: if self.exit_manager.use_stop_loss: self.exit_manager.check_stop_loss(self.invested_condor) if self.exit_manager.use_absolute_stop_loss: self.exit_manager.check_absolute_stop_loss(self.invested_condor) if self.exit_manager.use_regular_profit_take: self.exit_manager.check_regular_profit_take(self.invested_condor) if self.exit_manager.use_timed_exit: self.exit_manager.check_timed_exit(self.invested_condor) if self.exit_manager.use_timed_profit_exit: self.exit_manager.check_timed_profit_exit(self.invested_condor) if self.avg_down_manager.use_avg_down: self.avg_down_manager.append_pivot() if len(self.today_keys) > 0: x = self.today_condors[self.today_keys[0][0]].calculate_premium() if self.use_regular_entry: if self.invested_condor is None and self.today_condors[self.today_keys[0][0]].Calculate_Premium() >= self.todays_premium: self.invested_condor = self.entry_manager.check_regular(self.today_condors, self.today_keys, self.todays_min_range, self.todays_max_range, self.todays_premium, self.open_price) if self.invested_condor is not None: if self.re_entry_manager.use_re_entry: condor = self.entry_manager.check_re_entry(self.today_condors, self.today_keys, self.todays_min_range, self.todays_max_range, self.todays_premium) if condor is not None: self.invested_condor = condor time = int(self.Time.strftime("%H%M").replace(":", "")) self.Debug(f'{int(self.Time.strftime("%H%M").replace(":", ""))} {x} {self.today_keys[0][0]}') if time <= self.latest_time and x >= 1 and ( (self.invested_condor is not None and (not self.avg_down_manager.avg_down_layers[self.current_key][-1] or not self.avg_down_manager.avg_down_layers[self.key_2][-1] or not self.avg_down_manager.avg_down_layers[self.key_3][-1])) or (self.avg_down_manager.use_trading_quantity and (not self.avg_down_manager.avg_down_layers[self.current_key][-1] or not self.avg_down_manager.avg_down_layers[self.key_2][-1] or not self.avg_down_manager.avg_down_layers[self.key_3][-1])) ): if self.avg_down_manager.use_avg_down and (self.invested_condor is None or not self.invested_condor.partial): condor, strgl = self.entry_manager.check_avg_down(self.today_condors, self.today_keys, self.todays_min_range, self.todays_max_range, self.todays_premium) if condor is not None: self.invested_condor = condor
from AlgorithmImports import * from collections import deque import statistics as stats import config class ReEntry(): def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol self.use_re_entry = config.USE_RE_ENTRY self.re_entry_mode = config.RE_ENTRY_MODE self.re_entry_threshold_mode = config.RE_ENTRY_THRESHOLD_MODE self.re_entry_multiplier = config.RE_ENTRY_MULTIPLIER self.re_entry_static = config.RE_ENTRY_STATIC_PREMIUM self.re_entry_times_x = config.RE_ENTRY_X_TIMES self.entered_today = False self.entry_count_today = 0 self.previous_premium = None self.allowed_condor = "ANY CONDOR" def check_permission(self, invested): if not self.use_re_entry and self.entered_today: return False elif self.use_re_entry and not invested and self.entered_today and self.entry_count_today < self.re_entry_times_x: return True else: return False def get_new_threshold(self): if self.re_entry_threshold_mode == "STATIC": return self.re_entry_static elif self.re_entry_threshold_mode == "ENTRY MULTIPLIER": return self.previous_premium * self.re_entry_multiplier def reset(self): self.use_re_entry = config.USE_RE_ENTRY self.re_entry_mode = config.RE_ENTRY_MODE self.re_entry_threshold_mode = config.RE_ENTRY_THRESHOLD_MODE self.re_entry_multiplier = config.RE_ENTRY_MULTIPLIER self.re_entry_static = config.RE_ENTRY_STATIC_PREMIUM self.re_entry_times_x = config.RE_ENTRY_X_TIMES self.entered_today = False self.entry_count_today = 0 self.previous_premium = None self.allowed_condor = "ANY CONDOR"
from AlgorithmImports import * from collections import deque import statistics as stats import config class PremiumSelecter(): def __init__(self, algorithm): self.algorithm = algorithm self.premium_threshold_mode = config.PREMIUM_THRESHOLD_MODE self.fixed_premium = config.FIXED_PREMIUM self.fixed_premium_1 = config.FIXED_PREMIUM_1 self.fixed_premium_1_5 = config.FIXED_PREMIUM_1_5 self.fixed_premium_2 = config.FIXED_PREMIUM_2 self.fixed_premium_2_5 = config.FIXED_PREMIUM_2_5 self.fixed_premium_3 = config.FIXED_PREMIUM_3 def select_premium(self, range_today, adjustable_premium_today): if self.premium_threshold_mode == "FIXED": self.algorithm.Plot("Premium Used", "Premium", self.fixed_premium) return self.fixed_premium elif self.premium_threshold_mode == "FIXED PER RANGE": if range_today == 0.01 or range_today != 0.01: self.algorithm.Plot("Premium Used", "Premium", self.fixed_premium_1) premium_today = self.fixed_premium_1 elif range_today == 0.015: self.algorithm.Plot("Premium Used", "Premium", self.fixed_premium_1_5) premium_today = self.fixed_premium_1_5 elif range_today == 0.02: self.algorithm.Plot("Premium Used", "Premium", self.fixed_premium_2_5) premium_today = self.fixed_premium_2_5 elif range_today == 0.025: self.algorithm.Plot("Premium Used", "Premium", self.fixed_premium_2_5) premium_today = self.fixed_premium_2_5 elif range_today == 0.03: self.algorithm.Plot("Premium Used", "Premium", self.fixed_premium_3) premium_today = self.fixed_premium_3 return premium_today elif self.premium_threshold_mode == "ADJUSTED PREMIUM": self.algorithm.Plot("Premium Used", "Premium", adjustable_premium_today) return adjustable_premium_today else: raise Exception(f"Premium Threshold Mode '{config.PREMIUM_THRESHOLD_MODE}' is incorrect, please pick between 'FIXED' or 'FIXED PER RANGE' or 'ADJUSTED PREMIUM'")
from AlgorithmImports import * import config import yfinance as yf class SelectRange(): def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol self.range_mode = config.RANGE_MODE #self.VIX = self.algorithm.AddIndex("VIX", Resolution.Minute).Symbol self.range_max_today = None self.range_min_today = None self.automatic_range_percentages = config.AUTOMATIC_RANGE_PERCENTAGES self.automatic_range_max_add = config.AUTOMATIC_RANGE_MAX_ADD/100 self.vix_threshold_1 = config.VIX_THRESHOLD_1 self.vix_threshold_2 = config.VIX_THRESHOLD_2 self.vix_threshold_3 = config.VIX_THRESHOLD_3 self.atr_threshold_1 = config.ATR_THRESHOLD_1 self.atr_threshold_2 = config.ATR_THRESHOLD_2 self.atr_21_indie = NormalizedAverageTrueRange(21) self.atr_21 = None self.vix = None self.use_1 = False self.use_1_5 = False self.use_2 = False self.use_2_5 = False self.use_3 = False self.bar_consolidator = TradeBarConsolidator(timedelta(days=1)) self.algorithm.SubscriptionManager.AddConsolidator(self.symbol, self.bar_consolidator) self.bar_consolidator.DataConsolidated += self.temporary_receive_bar history = self.algorithm.History[TradeBar](self.symbol, 100, Resolution.Daily) for bar in history: self.bar_consolidator.Update(bar) self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.AfterMarketOpen(self.symbol, 1), self.temporary_get_vix) if self.range_mode == "FIXED": self.range_max_today = config.MAXIMUM_DISTANCE/100 self.range_min_today = config.MINIMUM_DISTANCE/100 elif self.range_mode == "AUTOMATIC": #config.data_dictionary["select_range_callable"] = [(self.select_range_callable, "atr_21", NormalizedAverageTrueRange(21), 21, "1 day", Resolution.Daily, timedelta(days=1))] if 1 in self.automatic_range_percentages: self.use_1 = True if 1.5 in self.automatic_range_percentages: self.use_1_5 = True if 2 in self.automatic_range_percentages: self.use_2 = True if 2.5 in self.automatic_range_percentages: self.use_2_5 = True if 3 in self.automatic_range_percentages: self.use_3 = True else: raise Exception(f"Selected RANGE MODE {self.range_mode} is incorrect, please check the input and either choose 'AUTOMATIC' or 'FIXED'") def temporary_get_vix(self): vix = yf.Ticker("^VIX") self.vix = vix.history(period="1d")['Close'].iloc[0] self.algorithm.Debug(f"VIX {self.vix}") def temporary_receive_bar(self, sender, bar): self.atr_21_indie.Update(bar) if self.atr_21_indie.IsReady: self.atr_21 = self.atr_21_indie.Current.Value/100 def select_range_callable(self, atr_21, vix): self.atr_21 = atr_21/100 self.vix = vix def set_range_today(self): self.atr_21 = 0.008 self.vix = 14 #self.algorithm.Debug(f"{self.vix} {self.atr_21}") if self.range_mode == "AUTOMATIC": if self.use_1_5 and self.atr_21 <= self.atr_threshold_1 and self.vix <= self.vix_threshold_2: self.range_max_today = 0.015 + self.automatic_range_max_add self.range_min_today = 0.015 elif self.use_2 and self.atr_21 <= self.atr_threshold_1: self.range_max_today = 0.02 + self.automatic_range_max_add self.range_min_today = 0.02 elif self.use_2 and self.vix <= self.vix_threshold_2: self.range_max_today = 0.02 + self.automatic_range_max_add self.range_min_today = 0.02 elif self.use_2_5: self.range_max_today = 0.025 + self.automatic_range_max_add self.range_min_today = 0.025 if self.use_3 and self.vix >= self.vix_threshold_1: self.range_max_today = 0.03 + self.automatic_range_max_add self.range_min_today = 0.03 if self.use_1 and self.atr_21 < self.atr_threshold_2 and self.vix < self.vix_threshold_3: self.range_max_today = 0.005 + self.automatic_range_max_add self.range_min_today = 0.005 elif self.range_mode == "FIXED": pass else: raise Exception(f"Selected RANGE MODE {self.range_mode} is incorrect, please check the input and either choose 'AUTOMATIC' or 'FIXED'") self.algorithm.Plot("Range Used", "Range", self.range_min_today) #self.range_max_today = 0.01 + self.automatic_range_max_add #self.range_min_today = 0.01 return self.range_min_today , self.range_max_today
from AlgorithmImports import * from QuantConnect.Securities.Option import OptionPriceModels class SymbolData(): def __init__(self, algorithm, symbol): self.algorithm = algorithm self.symbol = symbol