Overall Statistics
Total Trades
208
Average Win
0.02%
Average Loss
0.00%
Compounding Annual Return
0.519%
Drawdown
0.100%
Expectancy
1.565
Net Profit
0.517%
Sharpe Ratio
4.061
Probabilistic Sharpe Ratio
100.000%
Loss Rate
58%
Win Rate
42%
Profit-Loss Ratio
5.06
Alpha
0.004
Beta
-0
Annual Standard Deviation
0.001
Annual Variance
0
Information Ratio
0.574
Tracking Error
0.202
Treynor Ratio
-18.491
Total Fees
$510.00
Estimated Strategy Capacity
$1000.00
Lowest Capacity Asset
SPY 323AA3RM5H3VQ|SPY R735QTJ8XC9X
from AlgorithmImports import *
from collections import deque
import statistics as stats
import config



class PremiumThresholdAdjuster():



    def __init__(self, algorithm):
        self.algorithm = algorithm


        self.Avg_Premium_Length = config.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_15 = None
        self.Avg_Premium_20 = None
        self.Avg_Premium_25 = None
        self.Avg_Premium_30 = None


    def Append_15(self, premium):
        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.Debug(f"{self.algorithm.Time} 1.5% Avg Premium {self.Avg_Premium_15}")

    def Append_20(self, premium):
        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)

    def Append_25(self, premium):
        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)

    def Append_30(self, premium):
        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)


from AlgorithmImports import *
from collections import deque
import statistics as stats
import config



class AtrEma():



    def __init__(self, algorithm, symbol):
        self.algorithm = algorithm
        self.symbol = symbol

        self.Atr_Period = config.ATR_PERIOD
        self.Ema_Period = config.EMA_PERIOD

        self.Atr = NormalizedAverageTrueRange(self.Atr_Period)
        self.Ema = ExponentialMovingAverage(self.Ema_Period)


        self.Bar_Consolidator = TradeBarConsolidator(timedelta(days=1))
        self.algorithm.SubscriptionManager.AddConsolidator(self.symbol, self.Bar_Consolidator)
        self.Bar_Consolidator.DataConsolidated += self.Update_Indicators


        self.Increased_Volatility = False


        history_period = (self.Atr_Period + self.Ema_Period) * 2

        history = self.algorithm.History[TradeBar](self.symbol, history_period, Resolution.Minute)

        for bar in history:
            self.Bar_Consolidator.Update(bar)
    

    def Update_Indicators(self, sender, bar):
        self.Atr.Update(bar)

        if self.Atr.IsReady:
            self.Ema.Update(IndicatorDataPoint(bar.EndTime, self.Atr.Current.Value))
        else:
            self.Increased_Volatility = False
    
        if self.Atr.IsReady and self.Ema.IsReady:
            self.Check_Condition()
        else:
            self.Increased_Volatility = False

    def Check_Condition(self):
        if self.Atr.Current.Value >= self.Ema.Current.Value:
            self.Increased_Volatility = True
        else:
            self.Increased_Volatility = False
from AlgorithmImports import *
from collections import deque
import statistics as stats



class BarChange():



    def __init__(self, algorithm, symbol):
        self.algorithm = algorithm
        self.symbol = symbol

        self.Intraday_Bar_Consolidator = TradeBarConsolidator(timedelta(minutes=5))
        self.algorithm.SubscriptionManager.AddConsolidator(self.symbol, self.Intraday_Bar_Consolidator)
        self.Intraday_Bar_Consolidator.DataConsolidated += self.Calculate_Bar_Change
        self.len = 42
        self.List_Bar_Changes_OC = []
        self.List_Bar_Changes_HL = []

        self.Current_Cumulative_OC = None
        self.Current_Cumulative_HL = None

        self.Daily_Sums_OC = []
        self.Daily_Sums_HL = []

        self.Daily_Sum_Mean_OC = None
        self.Daily_Sum_Mean_HL = None

        self.Relative_OC = {"10":deque(maxlen=self.len), "11":deque(maxlen=self.len), "12":deque(maxlen=self.len), "13":deque(maxlen=self.len), "14":deque(maxlen=self.len), "15":deque(maxlen=self.len)}
        self.Relative_HL = {"10":deque(maxlen=self.len), "11":deque(maxlen=self.len), "12":deque(maxlen=self.len), "13":deque(maxlen=self.len), "14":deque(maxlen=self.len), "15":deque(maxlen=self.len)}



        self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.At(10,0), self.Append_10)
        self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.At(11,0), self.Append_11)
        self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.At(12,0), self.Append_12)
        self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.At(13,0), self.Append_13)
        self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.At(14,0), self.Append_14)
        self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.At(15,0), self.Append_15)


        self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.At(23,0), self.Reset_Lists)
    

    def Append_10(self):
        sum_oc = sum(self.List_Bar_Changes_OC)
        sum_hl = sum(self.List_Bar_Changes_HL)
        self.Relative_OC["10"].appendleft(sum_oc)
        self.Relative_HL["10"].appendleft(sum_hl)
    

    def Append_11(self):
        sum_oc = sum(self.List_Bar_Changes_OC)
        sum_hl = sum(self.List_Bar_Changes_HL)
        self.Relative_OC["11"].appendleft(sum_oc)
        self.Relative_HL["11"].appendleft(sum_hl)

    
    def Append_12(self):
        sum_oc = sum(self.List_Bar_Changes_OC)
        sum_hl = sum(self.List_Bar_Changes_HL)
        self.Relative_OC["12"].appendleft(sum_oc)
        self.Relative_HL["12"].appendleft(sum_hl)

    
    def Append_13(self):
        sum_oc = sum(self.List_Bar_Changes_OC)
        sum_hl = sum(self.List_Bar_Changes_HL)
        self.Relative_OC["13"].appendleft(sum_oc)
        self.Relative_HL["13"].appendleft(sum_hl)


    def Append_14(self):
        sum_oc = sum(self.List_Bar_Changes_OC)
        sum_hl = sum(self.List_Bar_Changes_HL)
        self.Relative_OC["14"].appendleft(sum_oc)
        self.Relative_HL["14"].appendleft(sum_hl)


    def Append_15(self):
        sum_oc = sum(self.List_Bar_Changes_OC)
        sum_hl = sum(self.List_Bar_Changes_HL)
        self.Relative_OC["15"].appendleft(sum_oc)
        self.Relative_HL["15"].appendleft(sum_hl)





    def Reset_Lists(self):
        sum_oc = sum(self.List_Bar_Changes_OC)
        sum_hl = sum(self.List_Bar_Changes_HL)
        self.Daily_Sums_OC.append(sum_oc)
        self.Daily_Sums_HL.append(sum_hl)
        self.Daily_Sum_Mean_OC = stats.mean(self.Daily_Sums_OC)
        self.Daily_Sum_Mean_HL = stats.mean(self.Daily_Sums_HL)
        self.List_Bar_Changes_OC.clear()
        self.List_Bar_Changes_HL.clear()


    def Get_Relative_Change(self, list_sums_oc, list_sums_hl):
        sum_oc = sum(self.List_Bar_Changes_OC)
        sum_hl = sum(self.List_Bar_Changes_HL)

        relative_oc = stats.mean(list_sums_oc)
        relative_hl = stats.mean(list_sums_hl)

        ratio_oc = sum_oc / relative_oc
        ratio_hl = sum_hl / relative_hl


        return round(sum_oc, 3), round(relative_oc, 3), round(ratio_oc, 3), round(sum_hl, 3), round(relative_hl, 3), round(ratio_hl, 3)


    def Calculate_Bar_Change(self, sender, bar):
        change_OC = abs((bar.Close - bar.Open) / bar.Open)
        change_HL = abs((bar.High - bar.Low) / bar.Close)

        self.List_Bar_Changes_OC.append(change_OC)
        self.List_Bar_Changes_HL.append(change_HL)

        if len(self.List_Bar_Changes_OC) >= 1:
            self.Current_Cumulative_OC = sum(self.List_Bar_Changes_OC)
        if len(self.List_Bar_Changes_HL) >= 1:
            self.Current_Cumulative_HL = sum(self.List_Bar_Changes_HL)
#region imports
from AlgorithmImports import *
#endregion
import time





USE_FOMC_MEETINGS = True
FOMC_MEETINGS = [
                Time(2022, 1, 25).strftime("%Y%-m%-d"),
                Time(2022, 1, 26).strftime("%Y%-m%-d"),
                Time(2022, 3, 15).strftime("%Y%-m%-d"),
                Time(2022, 3, 16).strftime("%Y%-m%-d"),
                Time(2022, 5, 3).strftime("%Y%-m%-d"),
                Time(2022, 5, 4).strftime("%Y%-m%-d"),
                Time(2022, 6, 14).strftime("%Y%-m%-d"),
                time(2022, 6, 15).strftime("%Y%-m%-d"),
                time(2022, 7, 26).strftime("%Y%-m%-d"),
                time(2022, 7, 27).strftime("%Y%-m%-d"),
                time(2022, 9, 20).strftime("%Y%-m%-d"),
                time(2022, 9 ,21).strftime("%Y%-m%-d"),
                time(2022, 11, 1).strftime("%Y%-m%-d"),
                time(2022, 11, 2).strftime("%Y%-m%-d"),
                time(2022, 12, 13).strftime("%Y%-m%-d"),
                time(2022, 12, 14).strftime("%Y%-m%-d"),
                ]





USE_FOMC_MINUTES = True
FOMC_MINUTES = [
                time(2022, 2 ,16).strftime("%Y%-m%-d"),
                time(2022, 4, 6).strftime("%Y%-m%-d"),
                time(2022, 5, 25).strftime("%Y%-m%-d"),
                time(2022, 7, 6).strftime("%Y%-m%-d"),
                time(2022, 8, 17).strftime("%Y%-m%-d"),
                time(2022, 10, 12).strftime("%Y%-m%-d"),
                ]
                



USE_CPI = True
CPI =          [
                time(2022, 1, 12).strftime("%Y%-m%-d"),
                time(2022, 2, 10).strftime("%Y%-m%-d"),
                time(2022, 3, 10).strftime("%Y%-m%-d"),
                time(2022, 4, 12).strftime("%Y%-m%-d"),
                time(2022, 5, 11).strftime("%Y%-m%-d"),
                time(2022, 6, 10).strftime("%Y%-m%-d"),
                time(2022, 7, 13).strftime("%Y%-m%-d"),
                time(2022, 8, 10).strftime("%Y%-m%-d"),
                time(2022, 9, 13).strftime("%Y%-m%-d"),
                time(2022, 10, 13).strftime("%Y%-m%-d"),
                time(2022, 11, 13).strftime("%Y%-m%-d"),
                time(2022, 12, 13).strftime("%Y%-m%-d"),
                ]
#region imports
from AlgorithmImports import *
#endregion
from datetime import*





USE_PRINT_OUT = False
PRINT_OUT =     [
                datetime(2022, 9, 2).strftime("%Y%-m%-d")
                ]






USE_LOWER_THRESHOLD = False

MINIMUM_GAP = 1
MAXIMUM_GAP = 5

LIST_OF_PERCENTAGES = [0.01, 0.02, 0.03]
LIST_OF_GAPS = [4,5,6]


USE_TIMED_PROFIT_EXIT = False
PROFIT_EXIT_TIME = 60
TIMED_PROFIT_THRESHOLD = 50

PREMIUM_MULTIPLIER = 1.5



STOP_LOSS_MULTIPLIER = 10
USE_STOP_LOSS = True

USE_SL_AT_ENTRY = False
PROFIT_THRESHOLD = 50

USE_ABSOLUTE_STOP_LOSS = True
ABSOLUTE_STOP_LOSS = 3.00

USE_VIX_SL = False

USE_ATR_EMA = False
ATR_PERIOD = 5
EMA_PERIOD = 9

USE_ADJST_PREMIUM = False
AVG_PREMIUM_LENGTH = 10





PREMIUM_INCREASE = 40



#########################HENDRIK#########################

# Minimum Premium
PREMIUM_THRESHOLD = 0.1

# Maximum Premium
MAX_PREMIUM = 111

# Enable/Disable Profit take
USE_PROFIT = True

# Enable/Disable Timed exit
USE_TIMED_EXIT = False

# Exit Time
EXIT_TIME = time(12, 0).strftime("%-H%-M")


PROFIT_PERCENT = 90

AMOUNT_OF_CONTRACTS = 10

# Minimum range from open
MINIMUM_DISTANCE = 0.025

# Maximum range from open
RANGE_MAX = 0.027

# Use ATR to lower Threshold (If ATR value is below ATR Threshold reduce range to new ranges)

USE_SMA = True
SMA_LENGTH = 200
SMA_MINIMUM_DISTANCE = 0.02


USE_ATR = True
ATR_THRESHOLD = 0.02
NEW_MINIMUM_DISTANCE = 0.02
NEW_RANGE_MAX = 0.022

USE_VIX_ATR = True
VIX_ATR_MINIMUM_DISTANCE = 0.015
VIX_ATR_RANGE_MAX = 0.017



# Use Vix to decide to take a trade or not
USE_VIX = True
VIX_THRESHOLD = 25


USE_VIX_2 = True
VIX_THRESHOLD_2 = 30
VIX_MINIMUM_RANGE = 0.03
VIX_RANGE_MAX = 0.032


PREMIUM_1_5 = 0.25
PREMIUM_2 = 0.25
PREMIUM_2_5 = 0.25
PREMIUM_3 = 0.25

#########################HENDRIK#########################







PREMIUM_RANGE_RATIO = 10

AVG_DAYS = 14

USE_5_5 = False

NEW_THRESHOLD = 0.25


ALLOW_RE_ENTER = False

MINUTES_TO_LOWER_THRESHOLD = 180
LOWERED_THRESHOLD = 0.1


USE_AVG = False



STRIKE_MAX = 5
RANGE_WEIGHT = 0.05 
STRIKE_WEIGHT = 0.2 






# LOOK UP



START = 1
INCREMENT = 1
END = 5
MAX_PERCENT = 0.027




USE_POWELL = True

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 = True
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 = True
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 = True
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 = True
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"),
                ]
from AlgorithmImports import *



class HighestHighLowestLow():




    def __init__(self, algorithm, symbol):
        self.algorithm = algorithm
        self.symbol = symbol

        self.HH = None
        self.LL = None

        self.CB = None
        self.CS = None
        self.PS = None
        self.PB = None

        self.Check_Range = False

        self.Yesterday_High = None
        self.Yesterday_Low = None

        self.Weekly_High = None
        self.Weekly_Low = None


        self.Bar_Consolidator = TradeBarConsolidator(timedelta(minutes=1))
        self.algorithm.SubscriptionManager.AddConsolidator(self.symbol, self.Bar_Consolidator)
        self.Bar_Consolidator.DataConsolidated += self.Update_HH_LL

        self.Opening_Vix = None
        self.Opening_Atr = None



        self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.BeforeMarketClose(self.symbol, -10), self.Reset)
        self.algorithm.Schedule.On(self.algorithm.DateRules.WeekStart(), self.algorithm.TimeRules.BeforeMarketClose(self.symbol, -10), self.Reset_Weekly)

    def Reset_Weekly(self):
        self.Weekly_High = None
        self.Weekly_Low = None


    def Reset(self):

        if self.Check_Range:
            close = self.algorithm.Securities[self.symbol].Close
            outside = "Inside of Range"
            if self.HH > self.CS:
                outside = "Outside of Range"
            if self.LL < self.PS:
                outside = "Outside of Range"

            

            #self.algorithm.Debug(f"{self.algorithm.Time} Close {close} (High {self.HH}  {round(self.CS, 2)} CS) / (Low {self.LL}  {round(self.PS, 2)} PS) / VIX {round(self.Opening_Vix, 2)} ATR {round(self.Opening_Atr, 2)} {outside}")
            #self.algorithm.Debug(f"{self.algorithm.Time} Weekly High {self.Weekly_High} Weekly Low {self.Weekly_Low} Yesterday High {self.Yesterday_High} Yesterday Low {self.Yesterday_Low}")

        self.Yesterday_High = self.HH
        self.Yesterday_Low = self.LL
        if self.Weekly_High is None:
            self.Weekly_High = self.Yesterday_High
        if self.Yesterday_High > self.Weekly_High:
            self.Weekly_High = self.Yesterday_High
        if self.Weekly_Low is None:
            self.Weekly_Low = self.Yesterday_Low
        if self.Yesterday_Low < self.Weekly_Low:
            self.Weekly_Low = self.Yesterday_Low

        self.HH = None
        self.LL = None

        self.CB = None
        self.CS = None
        self.PS = None
        self.PB = None

        self.Check_Range = False
    

    def Update_HH_LL(self, sender, bar):
        high = bar.High
        low = bar.Low

        if self.HH is None:
            self.HH = high
        if self.LL is None:
            self.LL = low

        if high > self.HH:
            self.HH = high
        if low < self.LL:
            self.LL = low

        

#region imports
from AlgorithmImports import *
from collections import deque
#endregion
import config
class Iron_Condor():


    def __init__(self, algorithm, put_buy, put_sell, call_buy, call_sell, open_call_range, open_put_range):
        self.algorithm = 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.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.Premium_Increase = 1 + (config.PREMIUM_INCREASE/100)


        self.Pivot_Queue = deque(maxlen=3)


    
    def Calculate_Premium(self, pb_premium, ps_premium, cb_premium, cs_premium):
        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.Pivot_Queue.appendleft(self.Premium)
        return self.Premium



    def Calculate_Pivot(self):
        if self.Entry_Premium is not None:
            if len(self.Pivot_Queue) == 3:
                if self.Premium > (self.Entry_Premium * self.Premium_Increase):
                    self.algorithm.Debug("PIVOT POINT")
                    return True
                else:
                    return False
            else:
                return False
        


    #def Calculate_Underlying_Re_Entry(self):
        #if
from AlgorithmImports import *
from itertools import count
from collections import deque
from QuantConnect.Securities.Option import OptionPriceModels
import config
import statistics as stats
import requests
import time
from bar_change import BarChange
from ironcondor import Iron_Condor
from hhll import HighestHighLowestLow
from adjust_premium import PremiumThresholdAdjuster
from sl_at_entry import SlAtEntry
from rolling_hhll import RollingHighestHighLowestLow
from atr_ema import AtrEma


class SmoothFluorescentYellowCaribou(QCAlgorithm):



    def Initialize(self):
        self.SetStartDate(2022, 1, 1) 
        self.SetEndDate(2022, 12, 31)
        self.SetCash(1000000)  
        #self.Settings.DataSubscriptionLimit = 300
        self.Spy = self.AddEquity("SPY", Resolution.Minute, extendedMarketHours=False).Symbol
        self.VIX = self.AddIndex("VIX", Resolution.Minute).Symbol
        self.option = self.AddOption(self.Spy, Resolution.Minute)
        self.option.SetLeverage(1.0)

        self.Atr_Ema = AtrEma(self, self.Spy)
        self.HH_LL = HighestHighLowestLow(self, self.Spy)
        self.Premium_Adjuster = PremiumThresholdAdjuster(self)
        self.SL_At_Entry = SlAtEntry(self)

        self.Rolling_hl = RollingHighestHighLowestLow(self, self.VIX)

        self.Bar_Change = BarChange(self, self.Spy)

        self.Premium_Multiplier = config.PREMIUM_MULTIPLIER

        self.List_Of_Perentages = config.LIST_OF_PERCENTAGES
        self.List_Of_Gaps = config.LIST_OF_GAPS

        self.option_symbol = self.option.Symbol
        self.option.PriceModel = OptionPriceModels.CrankNicolsonFD()
        self.atr_5 = NormalizedAverageTrueRange(5)
        self.atr_14 = NormalizedAverageTrueRange(14)
        self.atr_21 = NormalizedAverageTrueRange(21)
        self.atr_42 = NormalizedAverageTrueRange(42)
        self.atr_63 = NormalizedAverageTrueRange(63)


        self.Bar_Consolidator = TradeBarConsolidator(timedelta(days=1))
        self.SubscriptionManager.AddConsolidator(self.Spy, self.Bar_Consolidator)
        self.Bar_Consolidator.DataConsolidated += self.Update_ATRs

        

        self.HOD = 0
        self.LOD = 0

        history = self.History[TradeBar](self.Spy, 200, Resolution.Daily)


        for bar in history:
            self.Bar_Consolidator.Update(bar)

        self.Start_Time = time.perf_counter()


        self.option.SetFilter(self.UniverseFunc)
        self.Iron_Condor_Counter = 0
        self.Friday_Window = False
        self.Wednesday_Window = True
        self.Monday_Window = False

        self.Indicator_Average_Call_Deque = deque(maxlen=10)
        self.Indicator_Average_Put_Deque = deque(maxlen=10)

        self.Indicator_Average_Call = 0
        self.Indicator_Average_Put = 0

        self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.At(9, 30), self.Open_Window)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.At(15, 59), self.Close_Window)


        self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday), self.TimeRules.At(9, 30), self.Open_Window)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday), self.TimeRules.At(15, 59), self.Close_Window)

        self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.At(9, 30), self.Open_Window)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.At(15, 59), self.Close_Window)


        self.Schedule.On(self.DateRules.On(2022, 2, 23), self.TimeRules.AfterMarketOpen("SPY", 1), self.Close_It)


        # POWELL

        self.Schedule.On(self.DateRules.On(2021, 1, 14), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 2, 10), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 3, 4), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 5, 3), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 6, 22), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 8, 17), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 11, 29), self.TimeRules.At(12,0), self.Close_Trading_Window)

        self.Schedule.On(self.DateRules.On(2022, 5, 17), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 9, 23), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 11, 30), self.TimeRules.At(12,0), self.Close_Trading_Window)


        # FED INTEREST RATE


        self.Schedule.On(self.DateRules.On(2021, 1, 27), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 3, 17), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 4, 28), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 6, 16), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 7, 28), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 9, 22), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 11, 3), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 12, 15), self.TimeRules.At(12,0), self.Close_Trading_Window)

        self.Schedule.On(self.DateRules.On(2022, 1, 26), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 3, 16), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 5, 4), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 6, 15), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 7, 27), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 9, 21), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 11, 2), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 12, 4), self.TimeRules.At(12,0), self.Close_Trading_Window)
        


        # FOMC MINUTES

        self.Schedule.On(self.DateRules.On(2021, 1, 6), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 2, 17), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 4, 7), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 5, 19), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 7, 7), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 8, 18), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 10, 13), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2021, 11, 24), self.TimeRules.At(12,0), self.Close_Trading_Window)

        self.Schedule.On(self.DateRules.On(2022, 1, 5), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 2, 16), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 4, 6), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 5, 25), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 7, 6), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 8, 17), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 10, 12), self.TimeRules.At(12,0), self.Close_Trading_Window)
        self.Schedule.On(self.DateRules.On(2022, 11, 23), self.TimeRules.At(12,0), self.Close_Trading_Window)
        



       

      



        self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday), self.TimeRules.AfterMarketOpen("SPY", 1), self.Get_Open_Price)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Tuesday), self.TimeRules.AfterMarketOpen("SPY", 1), self.Get_Open_Price)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.AfterMarketOpen("SPY", 1), self.Get_Open_Price)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Thursday), self.TimeRules.AfterMarketOpen("SPY", 1), self.Get_Open_Price)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.AfterMarketOpen("SPY", 1), self.Get_Open_Price)



        self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday), self.TimeRules.AfterMarketOpen("SPY", 2), self.Get_Open_Price_2)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.AfterMarketOpen("SPY", 2), self.Get_Open_Price_2)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.AfterMarketOpen("SPY", 2), self.Get_Open_Price_2)



        self.Schedule.On(self.DateRules.Every(DayOfWeek.Monday), self.TimeRules.BeforeMarketClose("SPY", 1), self.Check_At_Loss)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.BeforeMarketClose("SPY", 1), self.Check_At_Loss)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.BeforeMarketClose("SPY", 1), self.Check_At_Loss)


        self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 5), self.Get_Average)


        self.Traded_Today = False
        
        self.Minimum_Gap = config.MINIMUM_GAP
        self.Maximum_Gap = config.MAXIMUM_GAP
        self.Premium_Threshold = config.PREMIUM_THRESHOLD

        self.Range_Dictionary = {}

        self.Iron_Condors = {}

        self.Counter = 0


        self.Put_Buy_Strike = None
        self.Put_Sell_Strike = None
        self.Call_Buy_Strike = None
        self.Call_Sell_Strike = None


        self.Schedule.On(self.DateRules.EveryDay(), 
                self.TimeRules.Every(timedelta(minutes=31)),
                self.Reset_Counter)

        self.List_Of_Len = []
        self.Previous_Len = 0

        self.Stop_Loss_Multiplier = config.STOP_LOSS_MULTIPLIER
        self.Profit_Percent = 1 - (config.PROFIT_PERCENT/100)
        self.Amount_Of_Contracts = config.AMOUNT_OF_CONTRACTS


        self.Invested_Condor = None
        self.Previous_Fees = None
        self.Max_Unrealized_Loss = 0
        self.Max_Loss_Dollar = 0
        self.Unrealized_Losses = {}
        self.List_Of_Max_Unrealized = []
        self.List_Of_Losses = []
        self.Max_Loss = 0
        self.Avg_Loss = 0
        self.One_Five_Premium = None
        self.Two_Premium = None
        self.Two_Five_Premium = None
        self.Three_Premium = None

        self.Entered = False


        self.Launched_After_Open = False
        self.Open_Price = None

        self.Allow_Getting_Average = False
        self.Populated_List = False
        self.Len_List = None
        self.Average_Premium = None
        self.Premium_At_Open = None

        self.Premium_List = deque(maxlen=config.AVG_DAYS)
        self.Current_Average = None
        self.Appended_Today = False
        self.Ran_Universe_Func_Today = False
        self.Put_Combinations = {}
        self.Call_Combinations = {}
        self.Created_Combinations_Today = False
        self.Previous_Average = None
        self.Monday_Premium_Queue = deque(maxlen=5)
        self.Wednesday_Premium_Queue = deque(maxlen=5)
        self.Friday_Premium_Queue = deque(maxlen=5)
        self.Dont_Enter = False
        self.all_iv = 0
        self.Premium_At_Open_2 = None
        self.Appended_Today_2 = False


        self.List_To_Look_Up = []

        self.Allow_Re_enter = config.ALLOW_RE_ENTER
        self.Entered_With_PT = False
       

        self.Condor_List = []
        self.Sorted_Today = False
        self.Averaged_Down = False
        self.Avg_Down_Time = None
        self.VIX_Open = None
        self.Trade_Counter = 0
        self.Print_Out = False

        self.Minimum_Distance = config.MINIMUM_DISTANCE
        self.Range_Max = config.RANGE_MAX
    

    def Close_Trading_Window(self):
        if self.Portfolio.Invested:
            self.Liquidate(tag="Close_Trading_Window")
        self.Monday_Window = False
        self.Wednesday_Window = False
        self.Friday_Window = False

    def Update_ATRs(self, sender, bar):
        self.atr_5.Update(bar)
        self.atr_14.Update(bar)
        self.atr_21.Update(bar)
        self.atr_42.Update(bar)
        self.atr_63.Update(bar)


    def Get_Average(self):
        self.Allow_Getting_Average = True


    def Check_At_Loss(self):
        if self.Invested_Condor is not None:
      
            if self.Securities[self.Spy].High+0.1 >= self.Invested_Condor.Call_Sell.Strike:
                self.Liquidate(tag="Check at Loss")
            elif self.Securities[self.Spy].Low-0.1 <= self.Invested_Condor.Put_Sell.Strike:
                self.Liquidate(tag="Check at Loss")



    def Get_Open_Price(self):
     
        if config.USE_PRINT_OUT and self.Time.strftime("%Y%-m%-d") in config.PRINT_OUT:
            self.Print_Out = True
        self.Open_Price = self.Securities[self.Spy].Open

        self.HH_LL.Opening_Atr = self.atr_21.Current.Value
        self.HH_LL.Opening_Vix = self.Securities[self.VIX].Open
    
    

    def Get_Open_Price_2(self):
        if self.Open_Price is None:
            self.Open_Price = self.Securities[self.Spy].Open

    def Close_It(self):
        self.Monday_Window = False
        self.Wednesday_Window = False
        self.Friday_Window = False

    

    def Record_Premium_At_Open(self, premium):
        if self.Time.weekday() == 0:
            self.Monday_Premium_Queue.appendleft(premium)
        elif self.Time.weekday() == 2:
            self.Wednesday_Premium_Queue.appendleft(premium)
        elif self.Time.weekday() == 4:
            self.Friday_Premium_Queue.appendleft(premium)




    def Reset_Counter(self):
        for x in self.Iron_Condors.keys():
            condor = self.Iron_Condors[x]
            condor.Sent_Already = False
            condor.Scanned_Already = False
        self.Counter = 0


    def Open_Window(self):

        self.Appended_Today = False
        self.Put_Buy_Strike = None
        self.Put_Sell_Strike = None
        self.Call_Buy_Strike = None
        self.Call_Sell_Strike = None
        self.Call_Strike = None
        self.Put_Strike = None
        self.Monday_Window = True
        self.Previous_Fees = self.Portfolio.TotalFees
        self.Invested_Condor = None
        self.Traded_Today = False
        self.Previous_AccountValue = self.Portfolio.TotalPortfolioValue
        if config.USE_FOMC_MINUTES:
            if self.Time.strftime("%Y%-m%-d") in config.FOMC_MINUTES:
                self.Dont_Enter = True
        if config.USE_FOMC_MEETINGS:
            if self.Time.strftime("%Y%-m%-d") in config.FOMC_MEETINGS:
                self.Dont_Enter = True
        if config.USE_CPI:
            if self.Time.strftime("%Y%-m%-d") in config.CPI:
                self.Dont_Enter = True
        if config.USE_CPI_NEXTDAY:
            if self.Time.strftime("%Y%-m%-d") in config.CPI_NEXTDAY:
                self.Dont_Enter = True
        if config.USE_POWELL:
            if self.Time.strftime("%Y%-m%-d") in config.POWELL:
                self.Dont_Enter = True
        if config.USE_POWELL_NEXTDAY:
            if self.Time.strftime("%Y%-m%-d") in config.POWELL_NEXTDAY:
                self.Dont_Enter = True
        if config.USE_FED_INTEREST_RATE_DECISION:
            if self.Time.strftime("%Y%-m%-d") in config.FED_INTEREST_RATE_DECISION:
                self.Dont_Enter = True
        if config.USE_FED_INTEREST_RATE_DECISION_NEXTDAY:
            if self.Time.strftime("%Y%-m%-d") in config.FED_INTEREST_RATE_DECISION_NEXTDAY:
                self.Dont_Enter = True     
        if config.USE_FOMC_MEETINGS_FIRSTDAY:
            if self.Time.strftime("%Y%-m%-d") in config.FOMC_MEETINGS_FIRSTDAY:
                self.Dont_Enter = True                            



    

    
    

    def Close_Window(self):
        if self.One_Five_Premium is None:
            one_five = None
        else:
          
            one_five = self.One_Five_Premium.Highest_Premium
            self.Premium_Adjuster.Append_15(one_five)
        if self.Two_Premium is None:
            two = None
        else:
            two = self.Two_Premium.Highest_Premium
            self.Premium_Adjuster.Append_20(two)
        if self.Two_Five_Premium is None:
            two_five = None
        else:
            two_five = self.Two_Five_Premium.Highest_Premium
            self.Premium_Adjuster.Append_25(two_five)
        if self.Three_Premium is None:
            three = None
        else:
            three = self.Three_Premium.Highest_Premium
            self.Premium_Adjuster.Append_30(three)

        #self.Debug(f"{self.Time} 1.5% {one_five} 2% {two} 2.5% {two_five} 3% {three}")
    
        self.One_Five_Premium = None
        self.Two_Premium = None
        self.Two_Five_Premium = None
        self.Three_Premium = None
        self.Print_Out = False
        self.Entered = False
        self.Averaged_Down = False
        time = self.Time.strftime("%y %b %d %a")
        string_1 = str(self.Max_Unrealized_Loss)
        string_2 = str(self.Max_Loss_Dollar)
        string_3 = string_1 + "/" + string_2
        
        self.Unrealized_Losses[time] = string_3
        self.Monday_Window = False
        self.Sent_Already = []
        self.Iron_Condors.clear()
        self.List_Of_Max_Unrealized.append(self.Max_Loss_Dollar)
        self.Max_Unrealized_Loss = 0
        self.Max_Loss_Dollar = 0
        account_value = self.Portfolio.TotalPortfolioValue
        pnl = account_value - self.Previous_AccountValue
        close_price = self.Securities[self.Spy].Close
        if self.Open_Price is None:
           
            start_time = self.Time - timedelta(minutes=350)
            end_time = self.Time - timedelta(minutes=330)
            history = self.History[TradeBar](self.Spy, start_time, end_time, Resolution.Minute)
          
            for bar in history:
                self.Debug(f" wtf {bar.Open}")
                self.Open_Price = bar.Open
        if self.Open_Price is not None:
            range_today = (self.Open_Price - close_price) / self.Open_Price
            range_today = round(range_today, 3)
        else:
            range_today = 0
        atr_5 = self.atr_5.Current.Value
        atr_14 = self.atr_14.Current.Value
        atr_21 = self.atr_21.Current.Value
        atr_42 = self.atr_42.Current.Value
        atr_63 = self.atr_63.Current.Value

       
        self.all_iv = 0
        self.Premium_At_Open_2 = None
        self.Appended_Today_2 = False
        self.Len_List = None
        self.Average_Premium = None
        self.Populated_List = False
        self.Open_Price = None
        self.Premium_At_Open = None
        self.Ran_Universe_Func_Today = False
        self.Put_Combinations.clear()
        self.Call_Combinations.clear()
        self.Created_Combinations_Today = False
        self.Dont_Enter = False
        self.Entered_With_PT = False
        self.Sorted_Today = False
        self.Condor_List.clear()
        self.List_To_Look_Up.clear()
        self.HOD = 0
        self.LOD = 0
        
     
        if pnl < 0:
            self.List_Of_Losses.append((pnl, time))
        
     

    

    
   

    def Get_Max_Unrealized_Loss(self, current_profit):
        if self.Max_Unrealized_Loss == 0:
            
            if self.Invested_Condor.Profit == 0:
                return

            if current_profit > self.Invested_Condor.Profit:
                self.Max_Unrealized_Loss = abs(current_profit)/self.Invested_Condor.Profit
        
        if self.Max_Unrealized_Loss != 0:
         
            x = abs(current_profit)/self.Invested_Condor.Profit
            if x > self.Max_Unrealized_Loss:
                self.Max_Unrealized_Loss = x
                self.Max_Loss_Dollar = abs(current_profit) - self.Invested_Condor.Profit



    def Profit_Taker(self):
        
     

        


        if self.Invested_Condor.Current_Profit <= self.Profit_Percent * self.Invested_Condor.Entry_Premium:
            if self.Portfolio.Invested:
                self.Liquidate(tag="PROFIT TAKER")
             
                self.Entered_With_PT = False
                self.Invested_Condor.Profit_Taken = True
               
             
                
                
        

    
    def Stop_Loss(self):
        if self.Invested_Condor is not None:
           
            pnl = self.Invested_Condor.Current_Profit
            max_loss = (self.Invested_Condor.Entry_Premium * self.Stop_Loss_Multiplier)



            if pnl >= max_loss:
                if self.Portfolio.Invested:
                    self.Liquidate(tag=f"STOP LOSS {pnl} {max_loss} {self.Invested_Condor.Profit} {self.Invested_Condor.Entry_Premium} {self.Invested_Condor.Current_Profit}")
                    self.Invested_Condor.Stopped_Out = True


    def Update_Highest_Premiums(self):
        if self.Two_Premium is not None:
            premium = self.Two_Premium.Calculate_Premium(self.Securities[self.Two_Premium.Put_Buy.Symbol].AskPrice, self.Securities[self.Two_Premium.Put_Sell.Symbol].BidPrice, self.Securities[self.Two_Premium.Call_Buy.Symbol].AskPrice, self.Securities[self.Two_Premium.Call_Sell.Symbol].BidPrice)

            if premium > self.Two_Premium.Highest_Premium:
                self.Two_Premium.Highest_Premium = premium
        
        if self.Two_Five_Premium is not None:
            premium = self.Two_Five_Premium.Calculate_Premium(self.Securities[self.Two_Five_Premium.Put_Buy.Symbol].AskPrice, self.Securities[self.Two_Five_Premium.Put_Sell.Symbol].BidPrice, self.Securities[self.Two_Five_Premium.Call_Buy.Symbol].AskPrice, self.Securities[self.Two_Five_Premium.Call_Sell.Symbol].BidPrice)

            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(self.Securities[self.One_Five_Premium.Put_Buy.Symbol].AskPrice, self.Securities[self.One_Five_Premium.Put_Sell.Symbol].BidPrice, self.Securities[self.One_Five_Premium.Call_Buy.Symbol].AskPrice, self.Securities[self.One_Five_Premium.Call_Sell.Symbol].BidPrice)

            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(self.Securities[self.Three_Premium.Put_Buy.Symbol].AskPrice, self.Securities[self.Three_Premium.Put_Sell.Symbol].BidPrice, self.Securities[self.Three_Premium.Call_Buy.Symbol].AskPrice, self.Securities[self.Three_Premium.Call_Sell.Symbol].BidPrice)

            if premium > self.Three_Premium.Highest_Premium:
                self.Three_Premium.Highest_Premium = premium



    def OnData(self, data: Slice):
    
        Price = self.Securities[self.Spy].Price

        if self.Time.month == 9 and self.Time.day == 2 and self.Time.year == 2022:
            if self.Invested_Condor is not None:
                p = self.Invested_Condor.Calculate_Premium(self.Securities[self.Invested_Condor.Put_Buy.Symbol].AskPrice, self.Securities[self.Invested_Condor.Put_Sell.Symbol].BidPrice, self.Securities[self.Invested_Condor.Call_Buy.Symbol].AskPrice, self.Securities[self.Invested_Condor.Call_Sell.Symbol].BidPrice)
                #self.Debug(f"{self.Time} Premium {p}")

        self.Update_Highest_Premiums()
        if Price > self.HOD:
            self.HOD = Price

        if self.LOD == 0:
            self.LOD = Price

        if Price < self.LOD:
            self.LOD = Price
        vix = self.Securities[self.VIX].Price
        if self.Portfolio.Invested:
            if self.Invested_Condor.Profit is None:
                fees = self.Portfolio.TotalFees - self.Previous_Fees
                initial_profit = (self.Invested_Condor.Entry_Premium * 100) * self.Amount_Of_Contracts
                self.Invested_Condor.Profit = initial_profit - fees
            fees = self.Portfolio.TotalFees - self.Previous_Fees
            current_premium = self.Invested_Condor.Calculate_Premium(self.Securities[self.Invested_Condor.Put_Buy.Symbol].AskPrice, self.Securities[self.Invested_Condor.Put_Sell.Symbol].BidPrice, self.Securities[self.Invested_Condor.Call_Buy.Symbol].AskPrice, self.Securities[self.Invested_Condor.Call_Sell.Symbol].BidPrice)
            current_premium = current_premium 

            self.Invested_Condor.Current_Profit = current_premium 
            if self.Invested_Condor.Entry_Fees is None:
                self.Invested_Condor.Entry_Fees = fees
            self.Get_Max_Unrealized_Loss(self.Invested_Condor.Current_Profit)
            
            if config.USE_PROFIT:
                self.Profit_Taker()
            if config.USE_STOP_LOSS:
                self.Stop_Loss()
            if config.USE_SL_AT_ENTRY:
                if self.Invested_Condor is not None and not self.Invested_Condor.Stopped_Out:
                    if self.SL_At_Entry.Calculate_Exit(self.Invested_Condor):
                        self.Liquidate(tag=f"STOP LOSS AT ENTRY")
                        self.Debug(f"{self.Time} SL AT ENTRY")
                        self.Invested_Condor.Stopped_Out = True
            if config.USE_ABSOLUTE_STOP_LOSS:
                if self.Invested_Condor is not None and not self.Invested_Condor.Stopped_Out:
                    if self.SL_At_Entry.Calculate_Absolute_Stop_Loss(self.Invested_Condor):
                        self.Liquidate(tag=f"ABSOLUTE STOP LOSS")
                        self.Debug(f"{self.Time} ABSOLUTE STOP LOSS")
                        self.Invested_Condor.Stopped_Out = True
            if config.USE_TIMED_PROFIT_EXIT:
                if self.Invested_Condor is not None and not self.Invested_Condor.Stopped_Out:
                    if self.SL_At_Entry.Calculate_Timed_Profit_Exit(self.Invested_Condor):
                        self.Liquidate(tag=f"TIMED PROFIT EXIT")
                        self.Debug(f"{self.Time} TIMED PROFIT EXIT")
                        self.Invested_Condor.Stopped_Out = True
            if config.USE_VIX_SL:
                if self.Invested_Condor is not None and not self.Invested_Condor.Stopped_Out:
                    if self.Rolling_hl.Weekly_High is not None:
                        if vix >= self.Rolling_hl.Weekly_High:
                            self.Liquidate(tag=f"VIX SL")
                            self.Debug(f"{self.Time} VIX SL")
                            self.Invested_Condor.Stopped_Out = True
                    

        if self.Portfolio.Invested and self.Print_Out:
            x = self.Invested_Condor.Calculate_Premium(self.Securities[self.Invested_Condor.Put_Buy.Symbol].AskPrice, self.Securities[self.Invested_Condor.Put_Sell.Symbol].BidPrice, self.Securities[self.Invested_Condor.Call_Buy.Symbol].AskPrice, self.Securities[self.Invested_Condor.Call_Sell.Symbol].BidPrice)
            percent_range = self.Invested_Condor.open_put_range

        if self.Portfolio["SPY"].Invested:
            self.Liquidate("SPY")
        

        if config.USE_TIMED_EXIT and self.Time.strftime("%-H%-M") >= config.EXIT_TIME:
            if self.Portfolio.Invested:
                self.Liquidate(tag="USE TIMED EXIT")
            return
        
  
        if (self.Portfolio.Invested and not self.Allow_Re_enter) or (self.Dont_Enter): return

        for i in data.OptionChains:
            
            
           

            if i.Key != self.option_symbol: continue
            optionchain = i.Value
      
            
            
            if (data.OptionChains.Count == 0):
                return 

        

            Price = self.Securities[self.Spy].Price
            Price = math.floor(Price)


            if self.Friday_Window or self.Wednesday_Window or self.Monday_Window:
              


                if self.Open_Price is None:
                 
                    self.Open_Price = self.Securities[self.Spy].Open
           


         



                
                expiry_date = "TODAY"
                if not self.Created_Combinations_Today:

                    List_Of_Distances = []

     
                    put_3_expiry = [x for x in optionchain if x.Right == OptionRight.Put and ((x.Expiry - self.Time).days) == -1 and (x.Strike - Price) < 1]
                    call_3_expiry =  [x for x in optionchain if x.Right == OptionRight.Call and ((x.Expiry - self.Time).days) == -1 and (Price - x.Strike) < 1]
                  


                    put_3_min_distance = Price*1
                    put_3_min_distance = math.floor(put_3_min_distance)

             
                    put_3_min_distances_sell = [x for x in put_3_expiry]
                    put_3_min_distances_buy = [x for x in put_3_expiry]


                 
                    call_3_min_distance = Price*1
                    call_3_min_distance = math.ceil(call_3_min_distance)

              
                    call_3_min_distances_sell = [x for x in call_3_expiry]
                    call_3_min_distances_buy = [x for x in call_3_expiry]


                    put_3_min_distances_sorted_sell = sorted(put_3_min_distances_sell, key=lambda x: x.Strike, reverse=True)
                    call_3_min_distances_sorted_sell = sorted(call_3_min_distances_sell, key=lambda x: x.Strike, reverse=False)

                    put_3_min_distances_sorted_buy = sorted(put_3_min_distances_buy, key=lambda x: x.Strike, reverse=True)
                    call_3_min_distances_sorted_buy = sorted(call_3_min_distances_buy, key=lambda x: x.Strike, reverse=False)
                    
                  
       
             

                    put_list = []
                    call_list = []

                    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 >= 5 and strike_diff <= 5:
                                combo = (x, y)
                                put_list.append(combo)
                               
                     
             
                    for x in call_3_min_distances_sorted_sell:
                        for y in call_3_min_distances_sorted_buy:
                            strike_diff = y.Strike - x.Strike
                            if y.Strike > x.Strike and strike_diff >= 5 and strike_diff <= 5: 
                                combo = (x, y)
                                call_list.append(combo)
              
           

                    if config.USE_VIX_ATR and self.atr_21.Current.Value/100 <= config.ATR_THRESHOLD and vix <= config.VIX_THRESHOLD:
                        self.Minimum_Distance = config.VIX_ATR_MINIMUM_DISTANCE
                        self.Range_Max = config.VIX_ATR_RANGE_MAX
                        self.Premium_Threshold = config.PREMIUM_1_5
                        if config.USE_ADJST_PREMIUM and self.Premium_Adjuster.Avg_Premium_15 is not None and self.Premium_Adjuster.Avg_Premium_15 >= 0.05:
                            self.Premium_Threshold = self.Premium_Adjuster.Avg_Premium_15

                        #self.Plot("Range Used", "Range", config.VIX_ATR_MINIMUM_DISTANCE)
                    elif config.USE_ATR and self.atr_21.Current.Value/100 <= config.ATR_THRESHOLD:
                        self.Minimum_Distance = config.NEW_MINIMUM_DISTANCE
                        self.Range_Max = config.NEW_RANGE_MAX
                        #self.Plot("Range Used", "Range", config.NEW_MINIMUM_DISTANCE)
                        self.Premium_Threshold = config.PREMIUM_2
                        if config.USE_ADJST_PREMIUM and self.Premium_Adjuster.Avg_Premium_20 is not None and self.Premium_Adjuster.Avg_Premium_20 >= 0.05:
                            self.Premium_Threshold = self.Premium_Adjuster.Avg_Premium_20

                    elif config.USE_VIX and vix <= config.VIX_THRESHOLD:
                        self.Minimum_Distance = config.NEW_MINIMUM_DISTANCE
                        self.Range_Max = config.NEW_RANGE_MAX
                        #self.Plot("Range Used", "Range", config.NEW_MINIMUM_DISTANCE)
                        self.Premium_Threshold = config.PREMIUM_2
                        if config.USE_ADJST_PREMIUM and self.Premium_Adjuster.Avg_Premium_20 is not None and self.Premium_Adjuster.Avg_Premium_20 >= 0.05:
                            self.Premium_Threshold = self.Premium_Adjuster.Avg_Premium_20

                    else:
                        self.Minimum_Distance = config.MINIMUM_DISTANCE
                        self.Range_Max = config.RANGE_MAX
                        #self.Plot("Range Used", "Range", config.MINIMUM_DISTANCE)
                        self.Premium_Threshold = config.PREMIUM_2_5
                        if config.USE_ADJST_PREMIUM and self.Premium_Adjuster.Avg_Premium_25 is not None and self.Premium_Adjuster.Avg_Premium_25 >= 0.05:
                            self.Premium_Threshold = self.Premium_Adjuster.Avg_Premium_25


                    if config.USE_VIX_2 and vix >= config.VIX_THRESHOLD_2:
                        self.Minimum_Distance = config.VIX_MINIMUM_RANGE
                        self.Range_Max = config.VIX_RANGE_MAX
                        #self.Plot("Range Used", "Range", config.VIX_MINIMUM_RANGE)
                        self.Premium_Threshold = config.PREMIUM_3
                        if config.USE_ADJST_PREMIUM and self.Premium_Adjuster.Avg_Premium_30 is not None and self.Premium_Adjuster.Avg_Premium_30 >= 0.05:
                            self.Premium_Threshold = self.Premium_Adjuster.Avg_Premium_30



                    if config.USE_ATR_EMA and self.Atr_Ema.Increased_Volatility:
                        self.Minimum_Distance += 0.005
                        self.Range_Max += 0.005

                    self.Plot("Range Used", "Range", self.Minimum_Distance)

                    if self.Minimum_Distance == 0.015:
                        self.HH_LL.Check_Range = True
                        self.HH_LL.CS = self.Open_Price * (1.015)
                        self.HH_LL.PS = self.Open_Price * (0.985)


                    self.Plot("Premium Used", "Premium", self.Premium_Threshold)
          
                    for ps, pb in put_list:
                     
                    
                        for cs, cb in call_list:
                      
                            p_diff = ps.Strike - pb.Strike
                            c_diff = cb.Strike - cs.Strike
                     
                            if cs.Strike > ps.Strike and p_diff == c_diff:
                                Strikes = f"{pb.Strike} {ps.Strike} {cs.Strike} {cb.Strike}"
                                if Strikes not in self.Iron_Condors and self.Open_Price is not None:
                                    open_call_range = ((cs.Strike - self.Open_Price) / self.Open_Price)
                                    open_put_range = abs((ps.Strike - self.Open_Price) / self.Open_Price)
                                    self.Iron_Condors[Strikes] = Iron_Condor(self, pb, ps, cb, cs, open_call_range, open_put_range)

                                    

                                    if self.Minimum_Distance <= open_call_range <= self.Range_Max and self.Minimum_Distance <= open_put_range <= self.Range_Max:
                                        self.List_To_Look_Up.append(Strikes)
                                        if not self.Appended_Today_2:
                                            

                                            condor = self.Iron_Condors[Strikes]
                                            premium = self.Iron_Condors[Strikes].Calculate_Premium(self.Securities[condor.Put_Buy.Symbol].AskPrice, self.Securities[condor.Put_Sell.Symbol].BidPrice, self.Securities[condor.Call_Buy.Symbol].AskPrice, self.Securities[condor.Call_Sell.Symbol].BidPrice)
                                      
                                            self.Premium_At_Open_2 = premium
                                            self.Appended_Today_2 = True
                       
                                    weight = self.Assign_Weighting(open_call_range, open_put_range, p_diff)


                                    self.Iron_Condors[Strikes].Weight = weight


                                    if open_call_range >= 0.024 and open_call_range <= 0.027 and open_put_range >= 0.024 and open_put_range <= 0.027:
                               
                                        condor = self.Iron_Condors[Strikes]
                                        premium = self.Iron_Condors[Strikes].Calculate_Premium(self.Securities[condor.Put_Buy.Symbol].AskPrice, self.Securities[condor.Put_Sell.Symbol].BidPrice, self.Securities[condor.Call_Buy.Symbol].AskPrice, self.Securities[condor.Call_Sell.Symbol].BidPrice)
                                        if self.Two_Five_Premium is None:
                                         
                                            self.Two_Five_Premium = condor
                                        
                                        if not self.Appended_Today:
                                            self.Premium_At_Open = premium
                             
                                            self.Premium_List.appendleft(premium)
                                            self.Appended_Today = True
                                            self.Record_Premium_At_Open(premium)
                                            iv_cs = cs.ImpliedVolatility
                                            iv_cb = cb.ImpliedVolatility
                                            iv_ps = ps.ImpliedVolatility
                                            iv_pb = pb.ImpliedVolatility
                                            iv_list = [iv_cs, iv_cb, iv_ps, iv_pb]
                                            self.all_iv = stats.mean(iv_list)
                        


                                    if open_call_range >= 0.02 and open_call_range <= 0.022 and open_put_range >= 0.02 and open_put_range <= 0.022:
                                   
                                        condor = self.Iron_Condors[Strikes]
                                        premium = self.Iron_Condors[Strikes].Calculate_Premium(self.Securities[condor.Put_Buy.Symbol].AskPrice, self.Securities[condor.Put_Sell.Symbol].BidPrice, self.Securities[condor.Call_Buy.Symbol].AskPrice, self.Securities[condor.Call_Sell.Symbol].BidPrice)
                                        if self.Two_Premium is None:
                                           
                                            self.Two_Premium = condor
                                    
                                    if open_call_range >= 0.03 and open_call_range <= 0.032 and open_put_range >= 0.03 and open_put_range <= 0.032:
                    
                                        condor = self.Iron_Condors[Strikes]
                                        premium = self.Iron_Condors[Strikes].Calculate_Premium(self.Securities[condor.Put_Buy.Symbol].AskPrice, self.Securities[condor.Put_Sell.Symbol].BidPrice, self.Securities[condor.Call_Buy.Symbol].AskPrice, self.Securities[condor.Call_Sell.Symbol].BidPrice)
                                        if self.Three_Premium is None:
                                      
                                            self.Three_Premium = condor
                                    
                                    if open_call_range >= 0.015 and open_call_range <= 0.017 and open_put_range >= 0.015 and open_put_range <= 0.017:
                                
                                        condor = self.Iron_Condors[Strikes]
                                        premium = self.Iron_Condors[Strikes].Calculate_Premium(self.Securities[condor.Put_Buy.Symbol].AskPrice, self.Securities[condor.Put_Sell.Symbol].BidPrice, self.Securities[condor.Call_Buy.Symbol].AskPrice, self.Securities[condor.Call_Sell.Symbol].BidPrice)
                                        if self.One_Five_Premium is None:
                                            
                                            self.One_Five_Premium = condor
             
                    for x in self.Iron_Condors.keys():
                        condor = self.Iron_Condors[x]
                        self.Condor_List.append((condor.Weight, condor))

                    self.Condor_List.sort(key=lambda x: x[0], reverse = True)



                    for x in self.Condor_List:
                        condor = x[1]
                        if condor.Calculate_Premium(self.Securities[condor.Put_Buy.Symbol].AskPrice, self.Securities[condor.Put_Sell.Symbol].BidPrice, self.Securities[condor.Call_Buy.Symbol].AskPrice, self.Securities[condor.Call_Sell.Symbol].BidPrice) >= 0.07:
                            self.Indicator_Average_Call_Deque.appendleft(condor.open_call_range)
                            self.Indicator_Average_Put_Deque.appendleft(condor.open_put_range)

                            if len(self.Indicator_Average_Call_Deque) == 10 and len(self.Indicator_Average_Put_Deque) == 10:
                                self.Indicator_Average_Call = sum(self.Indicator_Average_Call_Deque) / len(self.Indicator_Average_Call_Deque)
                                self.Indicator_Average_Put = sum(self.Indicator_Average_Put_Deque) / len(self.Indicator_Average_Put_Deque)
                            break




                    self.Created_Combinations_Today = True
                    put_list.clear()
                    call_list.clear()
                    put_3_expiry.clear()
                    call_3_expiry.clear()
                    put_3_min_distances_buy.clear()
                    put_3_min_distances_sell.clear()
                    put_3_min_distances_sorted_buy.clear()
                    put_3_min_distances_sorted_sell.clear()
                    call_3_min_distances_buy.clear()
                    call_3_min_distances_sell.clear()
                    call_3_min_distances_sorted_buy.clear()
                    call_3_min_distances_sorted_sell.clear()

           
                premium_list = []
              

              


                if len(self.Premium_List) == config.AVG_DAYS:
                    self.Current_Average = stats.mean(self.Premium_List)

                if not self.Portfolio.Invested or (self.Portfolio.Invested and self.Allow_Re_enter and not self.Averaged_Down):
                    if not self.Entered_With_PT and not self.Portfolio.Invested or (self.Portfolio.Invested and self.Allow_Re_enter and not self.Averaged_Down):
                        for x in self.List_To_Look_Up:

                            condor = self.Iron_Condors[x]
                            if not condor.Sent_Already:
                            
                                condor_distance_put = self.Securities[self.Spy].Price - condor.Put_Sell.Strike
                                condor_distance_call = condor.Call_Sell.Strike - self.Securities[self.Spy].Price
                                put_call_distance = abs(condor_distance_put - condor_distance_call)
                                strike_Gap = condor.Call_Buy.Strike - condor.Call_Buy.Strike
                                percentage_call = ((condor.Call_Sell.Strike - self.Securities[self.Spy].Price) / self.Securities[self.Spy].Price)

                                percentage_put = ((self.Securities[self.Spy].Price - condor.Put_Sell.Strike) / condor.Put_Sell.Strike)
                     
                                
                                percentage = ((abs(self.Securities[self.Spy].Price - condor.Put_Sell.Strike) / self.Securities[self.Spy].Price) + (abs(self.Securities[self.Spy].Price - condor.Call_Sell.Strike) / self.Securities[self.Spy].Price)) / 2

                            

                                
                             
                            
                            if config.USE_5_5:
                                if self.Time.weekday() == 0 and len(self.Monday_Premium_Queue) == 5:
                                    premiums = self.Premium_List + self.Monday_Premium_Queue
                                    self.Current_Average = stats.mean(premiums)
                                elif self.Time.weekday() == 2 and len(self.Wednesday_Premium_Queue) == 5:
                                    premiums = self.Premium_List + self.Wednesday_Premium_Queue
                                    self.Current_Average = stats.mean(premiums)
                                elif self.Time.weekday() == 4 and len(self.Friday_Premium_Queue) == 5:
                                    premiums = self.Premium_List + self.Friday_Premium_Queue
                                    self.Current_Average = stats.mean(premiums)
                            

                            if self.Current_Average != 0 and self.Current_Average is not None:
                                self.Previous_Average = self.Current_Average

                            if config.USE_AVG:
                                if self.Current_Average is not None and self.Premium_At_Open is not None:
                                    if self.Premium_At_Open > self.Current_Average:
                                        if self.Current_Average != 0 and self.Premium_At_Open != 0:
                                            premium_higher_by = (abs(self.Premium_At_Open-self.Current_Average)) / self.Current_Average
                                        elif self.Current_Average == 0 and self.Premium_At_Open != 0:
                                            premium_higher_by = (abs(self.Premium_At_Open-self.Previous_Average)) / self.Previous_Average
                                        elif self.Premium_At_Open == 0:
                                            premium_higher_by = 0.0000001



                                        distance_increase_factor = 1 + (abs(premium_higher_by) / config.PREMIUM_RANGE_RATIO)
                                        self.Minimum_Distance = min((self.Minimum_Distance * distance_increase_factor),0.034)
                                        
                                    else:
                                        self.Minimum_Distance = config.MINIMUM_DISTANCE


                            
                            
                            if self.Avg_Down_Time is not None and (self.Avg_Down_Time + timedelta(minutes=config.MINUTES_TO_LOWER_THRESHOLD)) >= self.Time:
                                self.Premium_Threshold = config.LOWERED_THRESHOLD
                            
                           
                            strike_Gap = condor.Call_Buy.Strike - condor.Call_Sell.Strike 
                        
                            ssss = condor.Calculate_Premium(self.Securities[condor.Put_Buy.Symbol].AskPrice, self.Securities[condor.Put_Sell.Symbol].BidPrice, self.Securities[condor.Call_Buy.Symbol].AskPrice, self.Securities[condor.Call_Sell.Symbol].BidPrice)  
                            if strike_Gap <= 5 and config.MAX_PREMIUM >= condor.Calculate_Premium(self.Securities[condor.Put_Buy.Symbol].AskPrice, self.Securities[condor.Put_Sell.Symbol].BidPrice, self.Securities[condor.Call_Buy.Symbol].AskPrice, self.Securities[condor.Call_Sell.Symbol].BidPrice) >= self.Premium_Threshold and condor.open_call_range >= self.Minimum_Distance and condor.open_put_range >= self.Minimum_Distance and not self.Dont_Enter:
                                percentage_call_ = ((condor.Call_Sell.Strike - self.Securities[self.Spy].Price) / self.Securities[self.Spy].Price)

                                percentage_put_ = ((self.Securities[self.Spy].Price - condor.Put_Sell.Strike) / condor.Put_Sell.Strike)

                           
                            
                                percentage_call_ = round(percentage_call_, 3)
                                percentage_put_ = round(percentage_put_, 3)


                            
                                Breakeven_Price_Call = condor.Call_Sell.Strike + condor.Premium
                                Breakeven_Price_Put = condor.Put_Sell.Strike - condor.Premium

                                id_ = "-723291833"
                                message__ = f" THIS IS AN ALERT USING RANGE FROM OPEN \n PUT RANGE %{condor.open_put_range} FROM OPEN \n CALL RANGE %{condor.open_call_range} FROM OPEN \n Action   Expiry   Strike   Type \n Sell {(condor.Put_Sell.Expiry).strftime('%b%d%-y')}   ${condor.Put_Sell.Strike}   Put \n Buy {(condor.Put_Buy.Expiry).strftime('%b%d%-y')}   ${condor.Put_Buy.Strike}   Put \n Buy {(condor.Call_Buy.Expiry).strftime('%b%d%-y') }   ${condor.Call_Buy.Strike}   Call \n Sell {(condor.Call_Sell.Expiry).strftime('%b%d%-y')}   ${condor.Call_Sell.Strike}   Call \n \n \n \n Price ${self.Securities[self.Spy].Price} \n  Premium {condor.Premium} \n Strike diff ${abs(condor.Put_Sell.Strike - condor.Put_Buy.Strike)} \n Breakeven Price Call {Breakeven_Price_Call} \n Breakeven Price Put {Breakeven_Price_Put} \n Current Call %{percentage_call_} \n Current Put %{percentage_put_}  \n expiry {expiry_date}"
                                token_ = "5616527268:AAGkUitVosgYOntpLb_JU5HK_SSXm86GsVs"
                             
                
                                if not condor.Stopped_Out:
                                    if not condor.Profit_Taken or self.Allow_Re_enter:
                                        if not self.Traded_Today or self.Allow_Re_enter:
                                            if not self.Entered_With_PT and not self.Portfolio.Invested or (self.Allow_Re_enter and condor.Calculate_Pivot()):
                                          
                                                if self.Portfolio.Invested:
                                                    
                                                    if condor != self.Invested_Condor:
                                                        continue
                                                    else:
                                                        self.Averaged_Down = True
                                                self.Trade_Counter += 1
                                                self.MarketOrder(condor.Put_Buy.Symbol, self.Amount_Of_Contracts, tag =f"{percentage_put_} Strike {condor.Put_Buy.Strike} pm {condor.Premium} Price {Price}")
                                                self.MarketOrder(condor.Put_Sell.Symbol, -self.Amount_Of_Contracts, tag =f"{percentage_put_} Strike {condor.Put_Sell.Strike} pm {condor.Premium} Price {Price}")
                                                self.MarketOrder(condor.Call_Buy.Symbol, self.Amount_Of_Contracts, tag =f"{percentage_call_} Strike {condor.Call_Buy.Strike} pm {condor.Premium} Price {Price}")
                                                self.MarketOrder(condor.Call_Sell.Symbol, -self.Amount_Of_Contracts, tag =f"{percentage_call_} Strike {condor.Call_Sell.Strike} pm {condor.Premium} Price {Price}")
                                                self.Avg_Down_Time = self.Time
                                                self.Put_Buy_Strike = condor.Put_Buy.Strike
                                                self.Put_Sell_Strike = condor.Put_Sell.Strike
                                                self.Call_Buy_Strike = condor.Call_Buy.Strike
                                                self.Call_Sell_Strike = condor.Call_Sell.Strike
                                                self.Invested_Condor = condor
                                                condor.Entry_Premium = condor.Premium
                                                condor.Margin_Required = ((condor.Put_Buy.Strike - condor.Put_Sell.Strike) * 100) * self.Amount_Of_Contracts
                                                self.Traded_Today = True
                                                self.Counter = self.Counter + 1
                                                self.Iron_Condor_Counter = self.Iron_Condor_Counter + 1
                                                self.Invested_Condor.Entry_Time = self.Time
                                                self.Entered = True
                                                if self.Averaged_Down:
                                                    break
                                                if self.Allow_Re_enter:
                                                    self.Entered_With_PT = True
                                          
                    

                


    def Assign_Weighting(self, open_call_range, open_put_range, strike_diff):
        call_range_diff = open_call_range - config.RANGE_MAX
        put_range_diff = open_put_range - config.RANGE_MAX
        
        call_put_diff = abs(open_call_range - open_put_range)
        call_put_diff = math.ceil(call_put_diff)
        call_range_diff = round(call_range_diff, 3)
        put_range_diff = round(put_range_diff, 3)


        call_range_diff = (call_range_diff * 10) 
        put_range_diff = (put_range_diff * 10) 
        if call_put_diff != 0:
            range_weight = ((call_range_diff * config.RANGE_WEIGHT) + (put_range_diff * config.RANGE_WEIGHT)) / call_put_diff
        else:
            range_weight = ((call_range_diff * config.RANGE_WEIGHT) + (put_range_diff * config.RANGE_WEIGHT))
    

        weight = range_weight 
        return weight
                       
    








                            

    def UniverseFunc(self, universe):
    
        Price = self.Securities[self.Spy].Price
        ATM = self.Securities[self.Spy].Price * 0.06
    
        return universe.IncludeWeeklys().Strikes(-ATM, ATM).Expiration(TimeSpan.FromDays(0),TimeSpan.FromDays(0))
        



    

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.Avg_Down_Type = config.AVG_DOWN_TYPE
        self.Underlying_Increment = config.UNDERLYING_PERCENT_MOVE_INCREMENT/100
        self.Premium_Increase = config.PREMIUM_INCREASE/100


    

    def Check_Conditions(self, invested_condor, open_price, range_today):
        increment_count = range_today / self.Underlying_Increment
        
        

from AlgorithmImports import *
from collections import deque


class RollingHighestHighLowestLow():




    def __init__(self, algorithm, symbol):
        self.algorithm = algorithm
        self.symbol = symbol

        self.HH = None
        self.LL = None

        self.CB = None
        self.CS = None
        self.PS = None
        self.PB = None

        self.Check_Range = False

        self.Yesterday_High = None
        self.Yesterday_Low = None


        self.Weekly_High_Queue = deque(maxlen=5)
        self.Weekly_Low_Queue = deque(maxlen=5)

        self.Weekly_High = None
        self.Weekly_Low = None


        self.Bar_Consolidator = TradeBarConsolidator(timedelta(minutes=1))
        self.algorithm.SubscriptionManager.AddConsolidator(self.symbol, self.Bar_Consolidator)
        self.Bar_Consolidator.DataConsolidated += self.Update_HH_LL

        self.Opening_Vix = None
        self.Opening_Atr = None



        


   
      
    

    def Update_HH_LL(self, sender, bar):
        high = bar.High
        low = bar.Low

        self.Weekly_High_Queue.appendleft(high)
        self.Weekly_Low_Queue.appendleft(low)

        if len(self.Weekly_High_Queue) == 5:
            self.Weekly_High = max(self.Weekly_High_Queue)
            self.Weekly_Low = min(self.Weekly_Low_Queue)
            

from AlgorithmImports import *
from collections import deque
import statistics as stats
import config




class SlAtEntry():



    def __init__(self, algorithm):
        self.algorithm = algorithm


        self.Profit_Threshold = 1 - (config.PROFIT_THRESHOLD/100)
        self.Reached = False
        self.Absolute_Stop_Loss = config.ABSOLUTE_STOP_LOSS

        self.algorithm.Schedule.On(self.algorithm.DateRules.EveryDay(), self.algorithm.TimeRules.At(9,0), self.Reset)

        self.Profit_Exit_Time = config.PROFIT_EXIT_TIME

        self.Timed_Profit_Threshold = 1 - (config.TIMED_PROFIT_THRESHOLD/100)


    def Reset(self):
        self.Reached = False

    def Calculate_Exit(self, invested_condor):
        if invested_condor.Current_Profit <= self.Profit_Threshold * invested_condor.Entry_Premium:
            self.Reached = True
        else:
            return False
        if invested_condor.Reached_Threshold or self.Reached:
            if invested_condor.Current_Profit >= invested_condor.Entry_Premium:
                return True
            else:
                return False
        else:
            return False





    def Calculate_Timed_Profit_Exit(self, invested_condor):
        if self.algorithm.Time <= invested_condor.Entry_Time + timedelta(minutes=self.Profit_Exit_Time):
            if invested_condor.Current_Profit <= self.Timed_Profit_Threshold * invested_condor.Entry_Premium:
                return True
            else:
                return False
        else:
            return False
        






    def Calculate_Absolute_Stop_Loss(self, invested_condor):
        if invested_condor.Current_Profit - invested_condor.Entry_Premium >= self.Absolute_Stop_Loss:
            return True
        else:
            return False