Window Periods
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © rrturtles2

//@version=5
indicator(title="Window Periods", overlay=true)
printTable(txt) => var table t = table.new(position.top_right, 1, 1), table.cell(t, 0, 0, txt, bgcolor = color.yellow)

// Work in progress.. visualize event windows

// to do:
// - assign sector relevance (add opec events and weight more to commodity typed instruments, whereas revenue forecasts of walmart won't be as relevant to commodities)
// - create weighting onto macro probability valuators
// - create means to store window weight/values in an accessible way so that additional scripts can access this data (post hidden text in window?) or maybe just duplicate arrays elsewhere in additional code (terrible option)
// - correct colors to scale within like types of events (opex the same, rebalancing periods the same, political and financial meeting the same color etc..)
// - find a way to make transfer the timestamps or date strings as const variables usable within functions.  v5 sends as series and cannot be converted back making this an overly complicated case instead of a function/library
// - add dates back to 2017 for better referencing
// - convert a number of the variables to inputs so they can be controlled in-chart, such as transparancy, and color of each window period?

// Window periods
// Initialize array of window dates (size with pushes)
//  - make list of all windows to be initialized
//  - manually enter dates below
var string _drawnext = "vix opex" // first case select to cascade from
var _windowsVixOpex = array.new_int(1)
var _windowsOpex = array.new_int(1)
var _windowsMarketClosures = array.new_int(1)
var _windowsEOQ = array.new_int(1)
var _windowsERBlackout = array.new_int(1)
var _windowsRevForecasts = array.new_int(1)
var _windowsGlobalFinancialMeeting = array.new_int(1)
var _windowsPoliticalEvents = array.new_int(1)
var _windowsCPI = array.new_int(1)
var _windowsFOMC = array.new_int(1)
var _windowsFOMCminutes = array.new_int(1)
var _windowsMajorIPOs = array.new_int(1)


// Default variables
var _windowsRiskPeriod = array.new_int(1) // initialize generic loop array
var _windowText = "" // Displayed text within window
var bool _drawingloop = true // condution for when loop
var bool _drawwindows = true // condition for case to pass to when loop
var int _transparancy = 75 // strength of transparancy

// set window colors
var color _windowBorderColor = color.rgb(255, 255, 255, 100) // transparency = 100 so no borders
var color _windowBGcolor = color.new(color.white, 50) // assigned differently for each window type

// Set manually for each type of risk window
var int _windowFadeInDays = 1 // high risk trend/chop that diverges from macro trend
var int _windowFadeOutDays = 1 // duration of vanna/charm gamma event
  
// fetch vertical positions for the window to span
float _highest = ta.highest(high, 120) * 1.05
float _lowest = ta.lowest(low, 120)// * .75

// Set number of milliseconds in a day for future calculations
// convert # days to milliseconds for direct use with timestamps
var int _millisecondday = 86400000          
       
if barstate.islast
    while _drawingloop
        // Defaults to prevent infinite loop
        _windowsRiskPeriod := array.new_int(0)
        _drawingloop := false
        // Case select to compile data
        //  - used in place of function because v5 pinescript does not allow arrays to pass to functions
        //  - and it does not allow for a str.split() to create const strings that can be converted into timestamps
        //  - as of 2022/08/10, don't know any other way to import a list of dates into a function
        _drawwindows := switch _drawnext
            "vix opex" => 
                // VIX Opex, source: https://www.macroption.com/vix-expiration-calendar/
                _windowText := "VIX Opex"
                _windowBGcolor := color.new(color.red, _transparancy)  // set window colors
                _windowFadeInDays := 2 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 1 // duration of vanna/charm gamma event
                    // Reason: vix opex typically reverses dramatically (vix lower) 2 days prior and 1-2 days post
                    //  - as new hedges are applied, vix often experiences a surge 2-4 days after vix opex
                    //  - note: vix expires AM so a 17th expiry last trades on the 16th 
                array.set(_windowsVixOpex, 0, timestamp(2022, 08, 17))
                array.push(_windowsVixOpex, timestamp(2022, 09, 21))
                array.push(_windowsVixOpex, timestamp(2022, 10, 19))
                array.push(_windowsVixOpex, timestamp(2022, 11, 16))
                array.push(_windowsVixOpex, timestamp(2022, 12, 21))
                array.push(_windowsVixOpex, timestamp(2023, 01, 18))
                array.push(_windowsVixOpex, timestamp(2023, 02, 15))
                array.push(_windowsVixOpex, timestamp(2023, 03, 22))
                array.push(_windowsVixOpex, timestamp(2023, 04, 19))
                array.push(_windowsVixOpex, timestamp(2023, 05, 17))
                array.push(_windowsVixOpex, timestamp(2023, 06, 21))
                array.push(_windowsVixOpex, timestamp(2023, 07, 19))
                array.push(_windowsVixOpex, timestamp(2023, 08, 16))
                array.push(_windowsVixOpex, timestamp(2023, 09, 20))
                array.push(_windowsVixOpex, timestamp(2023, 10, 18))
                array.push(_windowsVixOpex, timestamp(2023, 11, 15))
                array.push(_windowsVixOpex, timestamp(2023, 12, 20))
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsVixOpex) // copy to generic loop array
                _drawnext := "opex" // set to next case
                true
            "opex" =>
               // Opex, source: https://www.marketwatch.com/tools/options-expiration-calendar
                _windowText := "Opex"
                _windowBGcolor := color.new(color.fuchsia, _transparancy)  // set window colors
                _windowFadeInDays := 1 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 2 // duration of vanna/charm gamma event
                    // Reason: SPX futures expiry AM, 
                array.set(_windowsOpex, 0, timestamp(2022, 08, 19))
                array.push(_windowsOpex, timestamp(2022, 09, 16))
                array.push(_windowsOpex, timestamp(2022, 10, 21))
                array.push(_windowsOpex, timestamp(2022, 11, 18))
                array.push(_windowsOpex, timestamp(2022, 12, 16))
                array.push(_windowsOpex, timestamp(2023, 01, 20))
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsOpex) // copy to generic loop array
                _drawnext := "market closures" // set to next case
                true
            "market closures" =>
               // Market Closures, source: https://www.nyse.com/markets/hours-calendars
                _windowText := "Market Closures"
                _windowBGcolor := color.new(color.gray, _transparancy)  // set window colors
                _windowFadeInDays := 3 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 3 // duration of vanna/charm gamma event
                    // Reason: Risk off of shorts or longs based on macro environment, **plus adjusting for option decay!** and vacations?
                array.set(_windowsMarketClosures, 0, timestamp(2022, 05, 30))
                array.push(_windowsMarketClosures, timestamp(2022, 07, 04))
                array.push(_windowsMarketClosures, timestamp(2022, 09, 05))
                array.push(_windowsMarketClosures, timestamp(2022, 09, 05))
                array.push(_windowsMarketClosures, timestamp(2022, 09, 05))
                array.push(_windowsMarketClosures, timestamp(2022, 10, 10))
                array.push(_windowsMarketClosures, timestamp(2022, 11, 24))
                array.push(_windowsMarketClosures, timestamp(2022, 12, 26))
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsMarketClosures) // copy to generic loop array
                _drawnext := "end of quarter" // set to next case
                true
            "end of quarter" =>    
               // Quarterly ER blackout periods, source: none
                _windowText := "EOQ"
                _windowBGcolor := color.new(color.purple, _transparancy)  // set window colors
                _windowFadeInDays := 0 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 3 // duration of vanna/charm gamma event
                    // Reason: Major rebalancing with in-flows prior to/at EOQ
                array.set(_windowsEOQ, 0, timestamp(2022, 03, 31))
                array.push(_windowsEOQ, timestamp(2022, 06, 30))
                array.push(_windowsEOQ, timestamp(2022, 09, 30))
                array.push(_windowsEOQ, timestamp(2022, 12, 30))
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsEOQ) // copy to generic loop array
                _drawnext := "er blackout" // set to next case
                true
            "er blackout" =>    
               // Quarterly ER blackout periods, source: none
                _windowText := "ER Blackout"
                _windowBGcolor := color.new(color.olive, _transparancy)  // set window colors
                _windowFadeInDays := 0 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 20 // duration of vanna/charm gamma event
                    // Reason: Majority of S&P companies in ER blackout from buybacks and news leads to increased opportunity to front-run expectations
                array.set(_windowsERBlackout, 0, timestamp(2022, 04, 15))
                array.push(_windowsERBlackout, timestamp(2022, 07, 15))
                array.push(_windowsERBlackout, timestamp(2022, 10, 15))
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsERBlackout) // copy to generic loop array
                _drawnext := "revenue forecasts" // set to next case
                true
            "revenue forecasts" =>
               // Mega Cap revenue forecast updates, source: none
                _windowText := "Rev forecast"
                _windowBGcolor := color.new(color.maroon, _transparancy)  // set window colors
                _windowFadeInDays := 1 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 1 // duration of vanna/charm gamma event
                    // Reason: front-running may occur, and if it does then vix / gamma can be chased as it reverts (vix collapse, gamma squeeze up)
                array.set(_windowsRevForecasts, 0, timestamp(2022, 07, 25)) // WMT Walmart (retail, tgt etc..)
                array.push(_windowsRevForecasts, timestamp(2022, 08, 09)) // MU Micron (semis)
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsRevForecasts) // copy to generic loop array
                _drawnext := "global financial meeting" // set to next case
                true
            "global financial meeting" =>  
               // Global Financial Meeting, source: none
                _windowText := "Global Financial Meeting"
                _windowBGcolor := color.new(color.orange, _transparancy)  // set window colors
                _windowFadeInDays := 3 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 1 // duration of vanna/charm gamma event
                    // Reason: no way the market melts down during billionaire / political gathering / WEF
                array.set(_windowsGlobalFinancialMeeting, 0, timestamp(2022, 08, 27)) // Jackson Hole
                //array.push(_windowsGlobalFinancialMeeting, timestamp(2022, 08, 27)) // name or details...
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsGlobalFinancialMeeting) // copy to generic loop array
                _drawnext := "political events" // set to next case
                true
            "political events" =>  
               // Political Events, source: none
                _windowText := "Political Event"
                _windowBGcolor := color.new(color.orange, _transparancy)  // set window colors
                _windowFadeInDays := 3 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 1 // duration of vanna/charm gamma event
                    // Reason: front-running may occur, and if it does then vix / gamma can be chased as it reverts (vix collapse, gamma squeeze up)
                array.set(_windowsPoliticalEvents, 0, timestamp(2022, 11, 08)) // US congress election
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsPoliticalEvents) // copy to generic loop array
                _drawnext := "cpi release" // set to next case
                true
            "cpi release" =>    
               // CPI release, source: https://www.bls.gov/schedule/news_release/cpi.htm
                _windowText := "CPI"
                _windowBGcolor := color.new(color.orange, _transparancy)  // set window colors
                _windowFadeInDays := 2 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 1 // duration of vanna/charm gamma event
                    // Reason: front-running may occur, and if it does then vix / gamma can be chased as it reverts (vix collapse, gamma squeeze up)
                array.set(_windowsCPI, 0, timestamp(2022, 09, 13))
                array.push(_windowsCPI, timestamp(2022, 10, 13))
                array.push(_windowsCPI, timestamp(2022, 11, 10))
                array.push(_windowsCPI, timestamp(2022, 12, 13))
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsCPI) // copy to generic loop array
                _drawnext := "fomc meeting" // set to next case
                true
            "fomc meeting" =>   
               // FOMC meeting, source: https://www.federalreserve.gov/monetarypolicy/fomccalendars.htm
                _windowText := "FOMC meeting"
                _windowBGcolor := color.new(color.aqua, _transparancy)  // set window colors
                _windowFadeInDays := 2 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 1 // duration of vanna/charm gamma event
                    // Reason: front-running may occur, and if it does then vix / gamma can be chased as it reverts (vix collapse, gamma squeeze up)
                array.set(_windowsFOMC, 0, timestamp(2022, 07, 26))
                array.push(_windowsFOMC, timestamp(2022, 09, 20))
                array.push(_windowsFOMC, timestamp(2022, 11, 01))
                array.push(_windowsFOMC, timestamp(2022, 12, 13))
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsFOMC) // copy to generic loop array
                _drawnext := "fomc minutes" // set to next case
                true
            "fomc minutes" => 
               // FOMC minutes, source: https://www.federalreserve.gov/newsevents/calendar.htm
                _windowText := "FOMC minutes"
                _windowBGcolor := color.new(color.aqua, _transparancy)  // set window colors
                _windowFadeInDays := 1 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 1 // duration of vanna/charm gamma event
                    // Reason: front-running may occur, and if it does then vix / gamma can be chased as it reverts (vix collapse, gamma squeeze up)
                array.set(_windowsFOMCminutes, 0, timestamp(2022, 07, 06))
                array.push(_windowsFOMCminutes, timestamp(2022, 08, 17))
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsFOMCminutes) // copy to generic loop array
                _drawnext := "major ipos" // set to next case
                true
            "major ipos" =>   
               // Major IPOs, source: https://www.nasdaq.com/market-activity/ipos
                _windowText := "Major IPOs"
                _windowBGcolor := color.new(color.green, _transparancy)  // set window colors
                _windowFadeInDays := 1 // high risk trend/chop that diverges from macro trend
                _windowFadeOutDays := 1 // duration of vanna/charm gamma event
                    // Reason: When notable IPOs enter the market, these can withdraw liqudity and trader activity just before
                    //  - and just after IPO.  The broad market can suffer a dullness as algos place effort on the option free single trade
                // array.set(_windowsMajorIPOs, 0, timestamp(2021, 09, 03)) //DWACU Digital World Acquisition Corp.
                // array.push(_windowsMajorIPOs, timestamp(2022, 07, 15)) // HKD AMTD Digital Inc.
                // REQURED at end of case
                _windowsRiskPeriod := array.copy(_windowsMajorIPOs) // copy to generic loop array
                _drawnext := "" // set to next case
                true
            "" => 
                _windowsRiskPeriod := array.new_int(0)
                false 
       
        for i = 0 to (array.size(_windowsRiskPeriod) == 0 ? na : array.size(_windowsRiskPeriod) -1)
            box.new(text=_windowText, text_color=color.white, left=array.get(_windowsRiskPeriod, i) - (_millisecondday * _windowFadeInDays), top=_highest, right=array.get(_windowsRiskPeriod, i) + (_millisecondday * _windowFadeOutDays), bottom=_lowest, border_color=_windowBorderColor, border_width=1, border_style=line.style_solid, extend=extend.none, xloc=xloc.bar_time, bgcolor=_windowBGcolor)
                
        _drawingloop := _drawwindows   

