Overall Statistics
Total Trades
304
Average Win
0.02%
Average Loss
0.00%
Compounding Annual Return
0.340%
Drawdown
0.100%
Expectancy
1.124
Net Profit
0.679%
Sharpe Ratio
3.389
Probabilistic Sharpe Ratio
100.000%
Loss Rate
58%
Win Rate
42%
Profit-Loss Ratio
4.04
Alpha
0.002
Beta
-0
Annual Standard Deviation
0.001
Annual Variance
0
Information Ratio
-0.18
Tracking Error
0.162
Treynor Ratio
-7.118
Total Fees
$720.00
Estimated Strategy Capacity
$3000.00
Lowest Capacity Asset
SPY 323AA3RM5H3VQ|SPY R735QTJ8XC9X
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_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 = 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"),

                ]

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]






PREMIUM_MULTIPLIER = 1.5



STOP_LOSS_MULTIPLIER = 10
USE_STOP_LOSS = True





#########################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
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 *
#endregion
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.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
    
    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)
        return self.Premium
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

class SmoothFluorescentYellowCaribou(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2021, 1, 1)  # Set Start Date
        self.SetEndDate(2022, 12, 31)
        self.SetCash(1000000)  # Set Strategy Cash
        #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.HH_LL = HighestHighLowestLow(self, self.Spy)
      

        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_Friday_Window)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Friday), self.TimeRules.At(15, 59), self.Close_Friday_Window)


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

        self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.At(9, 30), self.Open_Wednesday_Window)
        self.Schedule.On(self.DateRules.Every(DayOfWeek.Wednesday), self.TimeRules.At(15, 59), self.Close_Wednesday_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()
        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.Time.month == 3:
                #self.Debug(f"{self.Securities[self.Spy].High} {self.Securities[self.Spy].Low} {self.Invested_Condor.Call_Sell.Strike} {self.Invested_Condor.Put_Sell.Strike}")
            if self.Securities[self.Spy].High+0.1 >= self.Invested_Condor.Call_Sell.Strike:
                self.Liquidate()
            elif self.Securities[self.Spy].Low-0.1 <= self.Invested_Condor.Put_Sell.Strike:
                self.Liquidate()



    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
        #self.Debug(f"Open {self.Open_Price}")
        #self.VIX_Open = self.Securities[self.VIX].Open
        #self.Debug(self.Time)
    

    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_Monday_Window(self):
        #self.Debug(f"{self.Time} VIX {self.Securities[self.VIX].Open}")
        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 Open_Wednesday_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.Wednesday_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 Open_Friday_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.Friday_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 OnEndOfAlgorithm(self):
        end_time = time.perf_counter()
      


  
   
        self.Debug(self.List_Of_Losses)
        wins = self.Trade_Counter - len(self.List_Of_Losses)
        winrate = wins / self.Trade_Counter
        losses = len(self.List_Of_Losses)
        self.Debug(f"Winrate {winrate*100}%  Total Trades {self.Trade_Counter} Total Losses {losses}")
    

    def Close_Monday_Window(self):
        if self.One_Five_Premium is None:
            one_five = None
        else:
            one_five = self.One_Five_Premium.Highest_Premium
        if self.Two_Premium is None:
            two = None
        else:
            two = self.Two_Premium.Highest_Premium
        if self.Two_Five_Premium is None:
            two_five = None
        else:
            two_five = self.Two_Five_Premium.Highest_Premium
        if self.Three_Premium is None:
            three = None
        else:
            three = self.Three_Premium.Highest_Premium

        #self.Debug(f"Range Today {self.Minimum_Distance*100}% // 1.5% Premium {one_five} // 2% Premium {two} // 2.5% Premium {two_five} // 3% Premium {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

        # full_range =  ((self.HOD - self.LOD) / close_price)
        

        # string_debug = f"Date {time} Trade Result {pnl} Range OC {range_today} Range HL {full_range} Premium 2% {self.Premium_At_Open_2} Premium 2.5% {self.Premium_At_Open} IV {self.all_iv} ATR 5 {atr_5} ATR 14 {atr_14} ATR 21 {atr_21} ATR 42 {atr_42} ATR 63 {atr_63}"
        #self.Debug(string_debug)
        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 Close_Wednesday_Window(self):
        if self.One_Five_Premium is None:
            one_five = None
        else:
            one_five = self.One_Five_Premium.Highest_Premium
        if self.Two_Premium is None:
            two = None
        else:
            two = self.Two_Premium.Highest_Premium
        if self.Two_Five_Premium is None:
            two_five = None
        else:
            two_five = self.Two_Five_Premium.Highest_Premium
        if self.Three_Premium is None:
            three = None
        else:
            three = self.Three_Premium.Highest_Premium

        #self.Debug(f"Range Today {self.Minimum_Distance*100}% // 1.5% Premium {one_five} // 2% Premium {two} // 2.5% Premium {two_five} // 3% Premium {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.Wednesday_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 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 Close_Friday_Window(self):
        if self.One_Five_Premium is None:
            one_five = None
        else:
            one_five = self.One_Five_Premium.Highest_Premium
        if self.Two_Premium is None:
            two = None
        else:
            two = self.Two_Premium.Highest_Premium
        if self.Two_Five_Premium is None:
            two_five = None
        else:
            two_five = self.Two_Five_Premium.Highest_Premium
        if self.Three_Premium is None:
            three = None
        else:
            three = self.Three_Premium.Highest_Premium

        #self.Debug(f"Range Today {self.Minimum_Distance*100}% // 1.5% Premium {one_five} // 2% Premium {two} // 2.5% Premium {two_five} // 3% Premium {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.Friday_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
        if self.Open_Price is None:
            start_time = self.Time - timedelta(minutes=390)
            history = self.History[TradeBar](self.Spy, start_time, start_time, Resolution.Minute)
            for bar in history:
                self.Open_Price = bar.Open

        close_price = self.Securities[self.Spy].Close
        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
        # full_range = ((self.HOD - self.LOD) / close_price)


        # string_debug = f"Date {time} Trade Result {pnl} Range OC {range_today} Range HL {full_range} Premium 2% {self.Premium_At_Open_2} Premium 2.5% {self.Premium_At_Open} IV {self.all_iv} ATR 5 {atr_5} ATR 14 {atr_14} ATR 21 {atr_21} ATR 42 {atr_42} ATR 63 {atr_63}"
        #self.Debug(string_debug)
        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.Debug(f"{self.Time} Entry {self.Invested_Condor.Entry_Premium} PROFIT TAKEN {self.Invested_Condor.Current_Profit}")
                self.Entered_With_PT = False
                self.Invested_Condor.Profit_Taken = True
               
                self.Invested_Condor.Sent_Already = False
                self.Invested_Condor.Premium = None
                self.Invested_Condor.Entry_Premium = None
                self.Invested_Condor.Entry_Fees = None

                self.Invested_Condor.Lowest_Premium = None
                self.Invested_Condor.Scanned_Already = False

                self.Invested_Condor.Profit = None
                self.Invested_Condor.Stopped_Out = False
                self.Invested_Condor.Profit_Taken = False
                
                self.Invested_Condor.Current_Profit = None
                self.Invested_Condor.Margin_Required = None
                self.Invested_Condor = None
                
                
        

    
    def Stop_Loss(self):
        if self.Invested_Condor is not None:
            self.Debug("HERE")
            pnl = self.Portfolio.TotalUnrealizedProfit
            max_loss = -(self.Invested_Condor.Profit * 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

       
      

        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

        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 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
            #self.Debug(f"{percent_range*100}% Premium {x} {self.Time}")
        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()
            return
        vix = self.Securities[self.VIX].Price
  
        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.Debug(f"None {self.Time}")
                    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 >= 1 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 >= 1 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
                   
                        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
                   
                    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
           
                    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_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 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)


                    #if self.One_Five_Premium is None:
                        #self.Debug(f"{self.Open_Price} // {self.Iron_Condors.keys()}")

                    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:
                                          
                                                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.Entered = True
                                           
                                                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 Generate_Key_To_Look_Up(self):
        open_price = self.Open_Price
        start= config.START
        increment = config.INCREMENT
        end = config.END
        current = start
        max_percent = config.MAX_PERCENT
        min_percent = config.MINIMUM_DISTANCE

        put_sell = (1 - min_percent) * open_price
        put_buy = (1 - min_percent) * open_price
        call_sell = (1 + min_percent) * open_price
        call_buy = (1 + min_percent) * open_price


        for i in count(0):
            put_buy += increment
            call_buy += increment
            current += increment
            string_add = f"{put_buy} {put_sell} {call_sell} {call_buy}"
            self.List_To_Look_Up.append(string_add)
            if current == end:
                put_sell += increment
                call_sell += increment
                put_buy = put_sell
                call_buy = call_sell
                current = start






                            

    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))