Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // © x77x
- //@version=5
- indicator("77-Power Law", overlay = true)
- /////////////////////////////////////////////////////////////////MVRV
- // Inputs
- timeframe = timeframe.isintraday ? "D" : timeframe.period
- MC = request.security("GLASSNODE:BTC_MARKETCAP", timeframe, close)
- MC_Realised = request.security("COINMETRICS:BTC_MARKETCAPREAL", timeframe, close)
- version = 'Z-Score'
- // Standard Deviation
- var MCap = array.new<float>()
- array.push(MCap, MC)
- Stdev = array.stdev(MCap)
- //MVRV and Range Values
- MVRV = version == 'Standard' ? MC/MC_Realised : (MC-MC_Realised)/Stdev
- lval_s = (1)
- hval_s = (3)
- lval_z = (0)
- hval_z = (5)
- lvl6 = input(5.5,title = 'MVRV TOP')
- lval = version == 'Standard' ? lval_s : lval_z
- hval = version == 'Standard' ? hval_s : hval_z
- //MVRV Glow
- glow = MVRV < lval ? color.rgb(255, 89, 0, 60) : MVRV > lvl6 ? color.rgb(255, 255, 255, 60) : na
- plot(close, color=glow, linewidth=10,title = 'MVRV Extreme Glow')
- ////// Power Law
- // Days X-Axis Value
- start = time == timestamp(2010, 7, 18, 0, 0) // First BLX Bitcoin Date
- days = request.security('BNC:BLX', 'D', ta.barssince(start))
- offset = 564 // days between 2009/1/1 and "start"
- d = days + offset
- // Power Law
- a = input(-16.493, 'Power Law Intercept',group = "Power Law Settings")
- b = input(5.688, 'Power Law Slope',group = "Power Law Settings")
- e = a + b * math.log10(d)
- y = math.pow(10, e)
- price_power_law = y
- // Calculate +350% of the power law result
- y_plus_350_percent = y * 4.5
- // Calculate +250% of the power law result
- y_plus_250_percent = y * 3.5
- // Calculate +150% of the power law result
- y_plus_150_percent = y * 2.5
- // Calculate +60% of the power law result
- y_plus_60_percent = y * 1.6
- // Calculate -30% of the power law result
- y_minus_30_percent = y * 0.7
- // Calculate -60% of the power law result
- y_minus_60_percent = y * 0.4
- // Extreme QE lol
- a2 = -13.36632341
- b2 = 5.03
- e2 = a2 + b2 * math.log10(d)
- y2 = math.pow(10, e2)
- EXQE_log = y * 8.5
- EXQE_price = EXQE_log
- //////////////////////////////////////////////////////
- var int futureBars = 650
- decay = 12000
- ext_BTC_trend = y * 1.709 + decay
- //ext_t = plot(ext_BTC_trend, color=color.rgb(255, 0, 0), title="PL Extension", linewidth = 1, offset = futureBars,
- //show_last = futureBars+1)
- // Label Deltas
- delta_powerL = math.round((y / close - 1.0) * 100)
- m2 = close < y ? '+' : ''
- // Plot
- //p3 = plot(EXQE_price, color=#ff5a00, title='Extreme QE')
- p7 = plot(y_plus_350_percent, color=#ff5a00, title='350%')
- p2 = plot(y_plus_250_percent, color=#ff5a00, title='250%')
- p5 = plot(y_plus_150_percent, color=#ff5a00, title = '150%')
- p6 = plot(y_plus_60_percent, color=#ff5a00, title = '60%')
- p1 = plot(y, color=#ff0000, title='Power Law',linewidth = 1)
- p9 = plot(y_minus_30_percent, color=color.rgb(54, 58, 69, 50), title='-30')
- p4 = plot(y_minus_60_percent, color=#ffebba, title='Support')
- fill = input(true, 'Plot Power Law Fill?',group = "Power Law Settings")
- fill(p5, p7, color=fill ? #b13e001a : na,title = 'Power Law Fill')
- fill(p5, p1, color=fill ? #b13e001a : na,title = 'Power Law Fill')
- fill(p1, p4, color=fill ? #5d606b33 : na,title = 'Power Law Fill')
- //Power Law Extension
- len5 = 1
- src5 = close
- PL_P_line = ta.ema(src5, len5)
- // Add a dropdown menu in the settings
- selectedOption = input.string(defval="Power Law % Line", title="Select Line/Bar", options=["Power Law % Line", "Clock Price Line", "Colored Bars"],group = "Power Law Settings")
- // PL Price Line
- show_PLprice_line = (selectedOption == "Power Law % Line")
- PLprice_line = PL_P_line < y_minus_30_percent ? #ff5a00 : PL_P_line < y ? #5d606b : PL_P_line < y_plus_60_percent? #b87333 : PL_P_line < y_plus_150_percent ? #90bff9 : PL_P_line < y_plus_250_percent ? #ffffff : PL_P_line < y_plus_350_percent ? #ffffff : PL_P_line < EXQE_price ? #da00ff : na
- plot(show_PLprice_line ? PL_P_line : na, title="Power Law Price Line", color=PLprice_line)
- // Input parameters
- startYear = 2010
- // Define colors and associate them with each segment (1 through 12)
- barColors = array.from(#5d606b, // ⏱ 1
- #5d606bf0, // ⏱ 2
- #ff5a00, // ⏱ 3
- #ff5900fc, // ⏱ 4
- #5d606bf2, // ⏱ 5
- #5d606bfc, // ⏱ 6
- #5d606bfa, // ⏱ 7
- #5d606bf7, // ⏱ 8
- #5d606bf5, // ⏱ 9
- #d7c089, // ⏱ 10
- #ffebba, // ⏱ 11
- #ffffff) // ⏱ 12
- // Calculate the current year and the number of months passed since the start year
- currentYear = year(time)
- yearsPassed = currentYear - startYear
- monthsPassed = (yearsPassed * 12) + (month(time) - 1)
- // Determine the current cycle segment (1 to 12)
- cycleSegment = monthsPassed % 48 // 4 years = 48 months
- currentSegment = math.floor(cycleSegment / 4)
- // Ensure the currentSegment is within bounds (0 to 11)
- currentSegment := math.max(0, math.min(currentSegment, 11))
- // Get the current color for the cycle segment
- currentColor = array.get(barColors, currentSegment)
- // Show Clock Price Line if selected
- show_ClockPrice_line = (selectedOption == "Clock Price Line")
- plot(show_ClockPrice_line ? close : na, title='Clock Price Line', color=currentColor, linewidth=1)
- // Show Colored Bars if selected
- show_ColoredBars = (selectedOption == "Colored Bars")
- barcolor(show_ColoredBars ? currentColor : na)
- // Track the previous segment to detect color changes (use int for typing, and assign to na initially)
- var int previousSegment = na
- colorChanged = (currentSegment != previousSegment)
- // Update previousSegment after processing the current bar
- previousSegment := currentSegment
- // Labels
- var label lbl1 = na
- var label lbl2 = na
- var label lbl3 = na
- var label lbl4 = na
- var label lbl5 = na
- var label lbl6 = na
- var label lbl7 = na
- label.delete(lbl1)
- label.delete(lbl2)
- label.delete(lbl3)
- label.delete(lbl4)
- label.delete(lbl5)
- label.delete(lbl6)
- label.delete(lbl7)
- //PL % Lables
- lbl1 := label.new(bar_index, y_plus_350_percent, style=label.style_label_left, text='350% = ' + str.tostring(y_plus_350_percent, '#.##'), textcolor=#ff5a00, color=#363a4503,size =size.small)
- lbl2 := label.new(bar_index, y_plus_250_percent, style=label.style_label_left, text='250% = ' + str.tostring(y_plus_250_percent, '#.##'), textcolor=#ff5a00, color=#363a4503,size =size.small)
- lbl3 := label.new(bar_index, y_plus_150_percent, style=label.style_label_left, text='150% = ' + str.tostring(y_plus_150_percent, '#.##'), textcolor=#ff5a00, color=#363a4503,size =size.small)
- lbl7 := label.new(bar_index, y_plus_60_percent, style=label.style_label_left, text='60% = ' + str.tostring(y_plus_60_percent, '#.##'), textcolor=#ff5a00, color=#363a4503,size =size.small)
- lbl4 := label.new(bar_index, y, style=label.style_label_left, text='Power Law = ' + str.tostring(y, '#.##'), textcolor=#ee2132, color=#363a4503,size =size.small)
- lbl5 := label.new(bar_index, y_minus_60_percent, style=label.style_label_left, text='Support -60% = ' + str.tostring(y_minus_60_percent, '#.##'), textcolor=#ffebba, color=#363a4503,size =size.small)
- //lbl6 := label.new(bar_index, EXQE_price, style=label.style_label_left, text='Extreme QE = ' + str.tostring(EXQE_price, '#.##'), textcolor=#ff5a00, color=#363a4503,size =size.small)
- /////////////////////////////////////
- ///////////////////////////////////////////////////////////////// Realized price
- // Get the timeframe to daily since all indicators are daily
- f_resInMinutes() =>
- _resInMinutes = timeframe.multiplier * (
- timeframe.isseconds ? 1. / 60 :
- timeframe.isminutes ? 1. :
- timeframe.isdaily ? 60. * 24 :
- timeframe.isweekly ? 60. * 24 * 7 :
- timeframe.ismonthly ? 60. * 24 * 30.4375 : na)
- f_resInDays() => f_resInMinutes() / 60 / 24
- timeframe_divisor = f_resInDays() // Use when doing moving averages
- // Inputs
- CVDD_extention_slope_factor = 100
- CVDD_extention_intercept_factor = 100
- CVDD_shift = 120
- // Query
- btc_high = request.security("BTCUSD", "D", high)
- btc_low = request.security("BTCUSD", "D", low)
- MCR = request.security("COINMETRICS:BTC_MARKETCAPREAL","D",close)
- TV = ta.sma(request.security("GLASSNODE:BTC_TOTALVOLUME","D",close), math.round(500 / timeframe_divisor)) //Total Volume of transfer
- //Calculate CVDD
- CVDD = (MCR-TV) / 22000000
- CVDD_bottom = CVDD * CVDD_shift/100
- top_factor_CVDD = -8.1775E-13 * CVDD_extention_slope_factor/100 * time + 1.965805965 * CVDD_extention_intercept_factor/100
- top_factor_CVDD := math.pow(10, top_factor_CVDD)
- // Plot
- plot(not na(CVDD) and time > timestamp(2011, 08, 06) ? CVDD_bottom : na, color = #b13e00, title = "Shifted CVDD",display=display.none, linewidth = 1)
- plot(not na(CVDD) and time > timestamp(2011, 08, 06) ? CVDD * top_factor_CVDD : na,display=display.none, color = color.rgb(255, 255, 255), title = "CVDD Extension", linewidth = 1)
- plot(not na(CVDD) and time > timestamp(2011, 08, 06) ? CVDD : na, color = #b13e00, title = "CVDD",display=display.none, linewidth = 1)
- bkg_color_above = color.rgb(255, 255, 255, 84)
- plotshape(btc_high >= CVDD * top_factor_CVDD, style=shape.diamond, color=color.rgb(255, 255, 255, 80), location=location.abovebar, size=size.tiny, title="CVDD High Highlight")
- ////150 day ema
- resolution = 'D'
- lowema_short = input.int(150, minval=1, title=' BMSB EMA',group = "BMSB EMA Settings")
- is_show_lowma2 = input(true, title='Show BMSB?',group = "BMSB EMA Settings")
- ema_short_low = request.security(syminfo.tickerid, resolution, ta.ema(close, lowema_short))
- BMSB=is_show_lowma2?ema_short_low:na
- PL_color = BMSB < y ? #5d606b : BMSB > y_plus_250_percent ? #da00ff : BMSB > y_plus_150_percent? #ffffff : BMSB > y_plus_60_percent ? #90bff9 : BMSB < y_plus_250_percent ? #b87333 : na
- plot(BMSB, color=PL_color, linewidth=2, title="BMSB")
- ///////////////////Halvings
- showLabels = input(defval=true, title="Show Halving labels",group = "Halving Settings")
- // New color inputs for lines and labels
- lineColor = input(defval=#b13e00, title="Line Color",group = "Halving Settings")
- labelBackgroundColor = input(defval=#b13e00, title="Label Background Color",group = "Halving Settings")
- labelTextColor = input(defval=color.rgb(0, 0, 0), title="Label Text Color",group = "Halving Settings")
- // Arrays for halving dates and descriptions
- var halvingDates = array.new_int(4)
- var halvingTexts = array.new_string(4)
- // Populate arrays with halving information
- array.set(halvingDates, 0, timestamp('GMT', 2012, 11, 28))
- array.set(halvingDates, 1, timestamp('GMT', 2016, 7, 9))
- array.set(halvingDates, 2, timestamp('GMT', 2020, 5, 11))
- array.set(halvingDates, 3, timestamp('GMT', 2024, 4, 19))
- array.set(halvingTexts, 0, "⛏ 1st Halving\n - Nov 28, 2012")
- array.set(halvingTexts, 1, "⛏ 2nd Halving\n - Jul 9, 2016")
- array.set(halvingTexts, 2, "⛏ 3rd Halving\n - May 11, 2020")
- array.set(halvingTexts, 3, "⛏ 4th Halving\n - Apr 19, 2024")
- // Adjusted drawHalvingEvent function to use the input colors
- drawHalvingEvent(date, labelText) =>
- if (time[1] < date and time >= date)
- line.new(x1=bar_index, y1=low, x2=bar_index, y2=high, xloc=xloc.bar_index, extend=extend.both, color=lineColor)
- if showLabels
- label.new(bar_index[1], y_minus_60_percent, text=labelText, style=label.style_label_upper_left, color=labelBackgroundColor, textcolor=labelTextColor, textalign=text.align_left,size =size.small)
- // Loop through each halving event and draw it
- for i = 0 to array.size(halvingDates) - 1
- drawHalvingEvent(array.get(halvingDates, i), array.get(halvingTexts, i))
- //////////////////////////////
- // NOTES
- // The "Spring" is the confirmed Miner capitulation period:
- // - The 1st "gray" circle is the start of Capitulation (1 month Hash Rate crosses UNDER 2 month Hash Rate)
- // - Last "green" circle is the end of Capitulation (1 month Hash Rate crosses OVER 2 month Hash Rate)
- // - The "greener" the spring gets (up until blue) represents Hash Rate recovery (it is increasing)
- // - The "blue" circle is the first instance of positive momentum following recovery of Hash Rate (1m HR > 2m HR). This is historically a rewarding place to buy with limited downside.
- // INPUTS
- type = 'Oscillator'
- len_s = 30
- len_l = 60
- signals = input(true, 'Plot Signals',group = "HASHRATE Signal")
- source = 'INTOTHEBLOCK:BTC_HASHRATE'
- ////////////////// HASH RATE MA
- // HR on TV only has "yesterday's" value --> use "lookahead_on" when running live (on current bar), to pull forward yesterdays data
- live_HR_raw = request.security(source, 'D', close, gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
- live_HR_short = request.security(source, 'D', ta.sma(close, len_s), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
- live_HR_long = request.security(source, 'D', ta.sma(close, len_l), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_on)
- hist_HR_raw = request.security(source, 'D', close, gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
- hist_HR_short = request.security(source, 'D', ta.sma(close, len_s), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
- hist_HR_long = request.security(source, 'D', ta.sma(close, len_l), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
- daily_s10 = request.security(syminfo.tickerid, 'D', ta.sma(close, 10), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
- daily_s20 = request.security(syminfo.tickerid, 'D', ta.sma(close, 20), gaps=barmerge.gaps_off, lookahead=barmerge.lookahead_off)
- // DAILY TIMEFRAME MGMT
- is_newbar(res) =>
- t = time(res) // res calculated below \/
- ta.change(t) != 0 ? true : false
- // Check how many bars are in our upper (otf) timeframe
- since_new_bar = ta.barssince(is_newbar('D')) //1-360 for minutes, D = Daily, W = Weekly, M = Monthly
- D_total_bars = int(na)
- D_total_bars := since_new_bar == 0 ? since_new_bar[1] : D_total_bars[1] // calculates the total number of current time frame bars in the OTF
- // Hash INDICATOR
- HR_short = float(na)
- HR_long = float(na)
- HR_raw = float(na)
- s10 = float(na)
- s20 = float(na)
- HR_short := barstate.isrealtime ? live_HR_short : hist_HR_short
- HR_long := barstate.isrealtime ? live_HR_long : hist_HR_long
- HR_raw := barstate.isrealtime ? live_HR_raw : hist_HR_raw
- s10 := barstate.isrealtime ? since_new_bar == D_total_bars ? daily_s10 : s10[1] : daily_s10
- s20 := barstate.isrealtime ? since_new_bar == D_total_bars ? daily_s20 : s20[1] : daily_s20
- capitulation = ta.crossunder(HR_short, HR_long)
- miner_capitulation = HR_short < HR_long
- recovering = HR_short > HR_short[1] and HR_short > HR_short[2] and HR_short > HR_short[3] and miner_capitulation
- recovering2 = ta.crossover(HR_short, HR_long)
- // HASH BOTTOM + PA SIGNAL
- buy = false
- buy := ta.crossover(s10, s20) and ta.barssince(recovering2) < ta.barssince(ta.crossunder(s10, s20)) and ta.barssince(recovering2) < ta.barssince(capitulation) or s10 > s20 and ta.crossover(HR_short, HR_long)
- buy_plot = buy
- // PLOT - SIGNALS
- // Clear previous labels to avoid overlap on the first bar
- if bar_index == 0
- var label[] all_labels = array.new_label()
- // Persistent flag: true if a capitulation label is currently active (has been shown)
- // and not yet reset by a hash buy signal.
- var bool capitulationShown = false
- if signals
- // Plot the hash buy signal label when its condition is met (label.new call is on one line)
- if buy_plot
- label.new(bar_index, EXQE_price, text="Hash Buy", style=label.style_circle, color=color.new(#ffebba7e, 90), textcolor=color.new(#ffebba7e, 90), size=size.tiny)
- capitulationShown := false
- // Plot the capitulation signal label only if it hasn't been shown since the last hash buy signal (label.new call is on one line)
- if capitulation and not capitulationShown
- label.new(bar_index, EXQE_price, text="Capitulation", style=label.style_circle, color=#ff59001b, textcolor=#ff59001b, size=size.tiny)
- capitulationShown := true
- //////////// Yearly returns
- // Inputs
- //{
- show_separator = input.bool (defval=false, title="New Year Line", group='New Year Settings')
- color_separator = input.color (defval=#ffffff, title="Line Color", group='New Year Settings')
- input_table_enable = input.bool (defval=true , title="Enable Table", group=" Yearly eturns Table Settings")
- input_table_size = input.string(defval="Small" , title="Size" , group="Yearly Returns Table Settings", options=["Auto", "Tiny", "Small", "Normal", "Large", "Huge"])
- input_table_position = input.string(defval="Bottom Right", title="Position" , group="Yearly Returns Table Settings", options=["Top Left", "Top Right", "Bottom Left", "Bottom Right"])
- input_table_direction = input.string(defval="Horizontal" , title="Direction" , group="Table Settings", options=["Vertical", "Horizontal"])
- input_sort_order = input.string(defval="Ascending", title="Sort By" , group="Yearly Returns Table Settings", options=["Ascending", "Descending"])
- //}
- table_size = switch input_table_size
- "Auto" => size.auto
- "Tiny" => size.tiny
- "Small" => size.small
- "Normal" => size.normal
- "Large" => size.large
- "Huge" => size.huge
- table_position = switch input_table_position
- "Top Left" => position.top_left
- "Top Right" => position.top_right
- "Bottom Left" => position.bottom_left
- "Bottom Right" => position.bottom_right
- GetLineStyle (line_style) =>
- switch line_style
- "Dashed" => hline.style_dashed
- "Dotted" => hline.style_dotted
- "Solid" => hline.style_solid
- GetOpen (timeframe) => request.security(syminfo.tickerid, timeframe, close[1], lookahead=barmerge.lookahead_on)
- var float[] yearly_returns = array.new_float(0)
- var int[] year_array = array.new_int(0)
- var float yearly_openPrice = 0.0
- var table returns_table = table(na)
- //////////////// Plot Yearly return
- //{
- // Check if it is a new year
- bool isNewYear = year(time) != year(time[1])
- // Get the Yearly Opening price
- yearly_openPrice := GetOpen('12M')
- // Calculate the yearly return
- float yearly_return = 100 * (close - yearly_openPrice) / yearly_openPrice
- color plot_color = yearly_return > 0 ? #ffebba : #b13e00
- // Show Background color
- color separator_col = show_separator and isNewYear ? color_separator : na
- bgcolor(separator_col, title="Year separator", editable=false)
- //}
- // Plot current and previous yearly return labels
- label past_return_label = na
- label current_return_label = na
- if (year(time) != year(time[1]))
- // Only push non-NaN values to array
- bool isNaN = na(yearly_return[1])
- if (not isNaN)
- // Concatenate yearly return with BTC clock segment
- string combinedLabelText = str.tostring(yearly_return[1], format.percent) + " ⏱: " + str.tostring(currentSegment) + ""
- past_return_label := label.new(bar_index[1], y_minus_60_percent, combinedLabelText, textcolor=#101010, color=plot_color[1], style=label.style_label_up, textalign=text.align_left, size=size.small)
- array.push(yearly_returns, yearly_return[1])
- array.push(year_array, year - 1)
- label.delete(past_return_label[1])
- // Plot current year returns
- if (barstate.islast)
- //current_return_label := label.new(bar_index, y4, str.tostring(yearly_return, format.percent), textcolor=#000000, color=plot_color, style=label.style_label_lower_left, textalign=text.align_left, size=size.small)
- array.push(yearly_returns, yearly_return)
- array.push(year_array , year )
- label.delete(current_return_label[1])
- //}
- // Function to insert cells into the table with black text color
- InsertCell(id, int col_index, int row_index, string _text, color _colour=#aaaaaa) =>
- table.cell(table_id=id, column=col_index, row=row_index, text=_text, text_size=table_size, bgcolor=_colour, text_color=#000000)
- // Set the minimum year for filtering
- minYear = 2011
- // Check if it's the last bar and the table should be shown
- if (barstate.islast and input_table_enable and array.size(yearly_returns) > 0)
- int _header_size = 2
- int _returns_size = array.size(yearly_returns) + 1 // +1 to add the BTC Time row
- _table = switch input_table_direction
- "Vertical" => array.from(_header_size , _returns_size + 1) // Add 1 to rows size for BTC Time row
- "Horizontal" => array.from(_returns_size + 1, _header_size) // Add 1 to columns size for BTC Time column
- int _column_size = array.get(_table, 0)
- int _rows_size = array.get(_table, 1)
- returns_table := table.new(table_position, columns=_column_size, rows=_rows_size, border_width=1)
- // Insert headers to table
- if input_table_direction == "Vertical"
- InsertCell(returns_table, 0, 0, "Year")
- InsertCell(returns_table, 1, 0, "% Returns")
- InsertCell(returns_table, 0, _rows_size - 1, "BTC Time") // Add BTC Time label
- else
- InsertCell(returns_table, 0, 0, "Year")
- InsertCell(returns_table, 0, 1, "% Returns")
- InsertCell(returns_table, _column_size - 1, 0, "BTC Time") // Add BTC Time label
- // Insert data to table for years 2014 and later
- for i=0 to array.size(yearly_returns) - 1
- year_value = array.get(year_array, i)
- // Only process if the year is 2014 or later
- if year_value >= minYear
- color col = array.get(yearly_returns, i) > 0 ? #ffebba : #b13e00
- string _year = str.tostring(year_value)
- string _returns = str.tostring(array.get(yearly_returns, i), format.percent)
- if input_table_direction == "Vertical"
- int _row_pos = input_sort_order == "Descending" ? _rows_size - i - 2 : i + 1 // Adjust to leave space for BTC Time row
- InsertCell(returns_table, 0 ,_row_pos, _year)
- InsertCell(returns_table, 1 ,_row_pos, _returns, _colour=col)
- else
- int _column_pos = input_sort_order == "Descending" ? _column_size - i - 2 : i + 1 // Adjust to leave space for BTC Time column
- InsertCell(returns_table, _column_pos, 0, _year)
- InsertCell(returns_table, _column_pos, 1, _returns, _colour=col)
- // Insert BTC Time into the table
- string btcTimeText = str.tostring(currentSegment) // BTC time info (cycle segment)
- if input_table_direction == "Vertical"
- InsertCell(returns_table, 1, _rows_size - 1, btcTimeText, _colour=#aaaaaa) // Insert in last row
- else
- InsertCell(returns_table, _column_size - 1, 1, btcTimeText, _colour=#aaaaaa) // Insert in last column
- ////////////////////
- var yearLabels = array.new_string(100)
- // Populate the year labels array
- array.set(yearLabels, 0, "Bull Year 1 In ")
- array.set(yearLabels, 1, "Bull Year 2 In ")
- array.set(yearLabels, 2, "Bull Year 3 IN ")
- array.set(yearLabels, 3, "Bear IN ")
- // Function to calculate and format the countdown to the next year
- getYearCountdown() =>
- var nextYear = year(timenow) + 1
- var nextYearLabel = array.get(yearLabels, nextYear - 2023)
- var nextYearTimestamp = timestamp(nextYear, 1, 1, 0, 0, 0)
- var secondsLeft = math.abs(nextYearTimestamp - timenow) / 1000
- var days = math.floor(secondsLeft / 86400)
- str.format(" {0}⏱:{1}d", nextYearLabel, days)
- // Display the label for the current year
- if barstate.islast
- var labelText = getYearCountdown()
- var label = label.new(bar_index, y_minus_60_percent, text=labelText, style=label.style_label_upper_left, color=color.rgb(0, 0, 0, 99), textcolor=#ffebba, textalign=text.align_left, size=size.small, xloc=xloc.bar_index)
- label.set_text(label, labelText)
- //////////////////////////////////////////////////////
- //ALERTS
- alertcondition(capitulation, title='Alert - Capitulation')
- alertcondition(buy and not buy[1], title='Alert - Hash Buy')
- //alertcondition(buy2, title='Alert - Call Spike')
- alertcondition(btc_high >= CVDD * top_factor_CVDD, title='Alert - CVDD Diamond')
- alertcondition(MVRV < lval?MVRV > lvl6:na, title='Alert - MVRV Extreme')
- ///////////////////////////////////////// Power Law Projection ////////////////////////////////////////////////////
- // Project into the future Power Law
- var int future_days = 500
- future_y = array.new_float(future_days)
- future_y_minus_60 = array.new_float(future_days)
- future_y_plus_60 = array.new_float(future_days)
- future_y_plus_150 = array.new_float(future_days) // New array for +150% deviation
- future_y_plus_250 = array.new_float(future_days) // New array for +250% deviation
- future_y_plus_350 = array.new_float(future_days) // New array for +350% deviation
- // Precompute future values for power law and deviations
- for i = 0 to future_days - 1
- future_d = d + i
- future_e = a + b * math.log10(future_d)
- power_law_value = math.pow(10, future_e)
- // Store original power law projection
- array.set(future_y, i, power_law_value)
- // Calculate -60% of the power law result
- power_law_value_minus_60 = power_law_value * 0.4
- array.set(future_y_minus_60, i, power_law_value_minus_60)
- // Calculate +60% of the power law result
- power_law_value_plus_60 = power_law_value * 1.6
- array.set(future_y_plus_60, i, power_law_value_plus_60)
- // Calculate +150% of the power law result
- power_law_value_plus_150 = power_law_value * 2.5
- array.set(future_y_plus_150, i, power_law_value_plus_150)
- // Calculate +250% of the power law result
- power_law_value_plus_250 = power_law_value * 3.5
- array.set(future_y_plus_250, i, power_law_value_plus_250)
- // Calculate +350% of the power law result
- power_law_value_plus_350 = power_law_value * 4.5
- array.set(future_y_plus_350, i, power_law_value_plus_350)
- // Plot future projection for power law
- var line future_line = na
- if bar_index == last_bar_index
- future_line := line.new(x1=bar_index, y1=y, x2=bar_index + future_days, y2=array.get(future_y, future_days - 1), color=#ff000033, width=2)
- // Plot future projection for -60% power law
- var line future_line_minus_60 = na
- if bar_index == last_bar_index
- future_line_minus_60 := line.new(x1=bar_index, y1=y * 0.4, x2=bar_index + future_days, y2=array.get(future_y_minus_60, future_days - 1), color=#ffebba78, width=2)
- // Plot future projection for +60% power law
- var line future_line_plus_60 = na
- if bar_index == last_bar_index
- future_line_plus_60 := line.new(x1=bar_index, y1=y * 1.6, x2=bar_index + future_days, y2=array.get(future_y_plus_60, future_days - 1), color=#ff590033, width=2)
- // Plot future projection for +150% power law
- var line future_line_plus_150 = na
- if bar_index == last_bar_index
- future_line_plus_150 := line.new(x1=bar_index, y1=y * 2.5, x2=bar_index + future_days, y2=array.get(future_y_plus_150, future_days - 1), color=#ff590033, width=2)
- // Plot future projection for +250% power law
- var line future_line_plus_250 = na
- if bar_index == last_bar_index
- future_line_plus_250 := line.new(x1=bar_index, y1=y * 3.5, x2=bar_index + future_days, y2=array.get(future_y_plus_250, future_days - 1), color=#ff590033, width=2)
- // Plot future projection for +350% power law
- var line future_line_plus_350 = na
- if bar_index == last_bar_index
- future_line_plus_350 := line.new(x1=bar_index, y1=y * 4.5, x2=bar_index + future_days, y2=array.get(future_y_plus_350, future_days - 1), color=#ff590033, width=2)
- //////////////////////////////
- // Variables to store labels so they can be deleted later
- var label power_law_label = na
- var label minus_60_label = na
- var label plus_60_label = na
- var label plus_150_label = na
- var label plus_250_label = na
- var label plus_350_label = na
- // Add labels at the end of the projections, deleting the previous label first
- if (bar_index == last_bar_index)
- // Delete previous labels if they exist
- if not na(power_law_label)
- label.delete(power_law_label)
- if not na(minus_60_label)
- label.delete(minus_60_label)
- if not na(plus_60_label)
- label.delete(plus_60_label)
- if not na(plus_150_label)
- label.delete(plus_150_label)
- if not na(plus_250_label)
- label.delete(plus_250_label)
- if not na(plus_350_label)
- label.delete(plus_350_label)
- // Create new labels and store them in variables
- power_law_label := label.new(bar_index + future_days, array.get(future_y, future_days - 1), text="Power Law = " + str.tostring(array.get(future_y, future_days - 1), format.mintick), color=#00897b00, style=label.style_label_left, textcolor=color.rgb(255, 0, 0, 50), yloc=yloc.price,size =size.small)
- minus_60_label := label.new(bar_index + future_days, array.get(future_y_minus_60, future_days - 1), text="-60% = " + str.tostring(array.get(future_y_minus_60, future_days - 1), format.mintick), color=#00897b00, style=label.style_label_left, textcolor=color.rgb(255, 235, 186, 50), yloc=yloc.price,size =size.small)
- plus_60_label := label.new(bar_index + future_days, array.get(future_y_plus_60, future_days - 1), text="+60% = " + str.tostring(array.get(future_y_plus_60, future_days - 1), format.mintick), color=#ff590000, style=label.style_label_left, textcolor=#ff590080, yloc=yloc.price,size =size.small)
- plus_150_label := label.new(bar_index + future_days, array.get(future_y_plus_150, future_days - 1), text="+150% = " + str.tostring(array.get(future_y_plus_150, future_days - 1), format.mintick), color=#ff590000, style=label.style_label_left, textcolor=#ff590080, yloc=yloc.price,size =size.small)
- plus_250_label := label.new(bar_index + future_days, array.get(future_y_plus_250, future_days - 1), text="+250% = " + str.tostring(array.get(future_y_plus_250, future_days - 1), format.mintick), color=#ff590000, style=label.style_label_left, textcolor=#ff590080, yloc=yloc.price,size =size.small)
- plus_350_label := label.new(bar_index + future_days, array.get(future_y_plus_350, future_days - 1), text="+350% = " + str.tostring(array.get(future_y_plus_350, future_days - 1), format.mintick), color=#ff590000, style=label.style_label_left, textcolor=#ff590080, yloc=yloc.price,size =size.small)
- //Target Price Line
- // Input for target price
- target_price = input.float(222308.0, title="Target Price", tooltip="Enter the price level for the horizontal line.")
- // Get current price (closing price of the latest bar)
- current_price = close
- // Calculate percentage difference (how far price needs to rise to reach the target)
- percent_diff = ((target_price - current_price) / current_price) * 100
- //Color
- LL_color = #ffebba
- // Plot horizontal line at target price
- line_price = hline(target_price, title="Target Price Line", color=LL_color, linewidth=1, linestyle=hline.style_solid)
- // Variable to store the label
- var label target_label = na
- // Delete the previous label if it exists
- if target_label != na
- label.delete(target_label)
- // Create a new label with customizable background color
- target_label := label.new(x=bar_index + 260, y=target_price, text="Target: " + str.tostring(target_price) + "\nTo Target: " + str.tostring(percent_diff, "#.##") + "%", style=label.style_label_down, size=size.small, color=LL_color, textcolor=#0b0b0b)
- // Alert condition: Trigger alert when price reaches or exceeds the target price
- price_reached = current_price >= target_price
- alertcondition(price_reached, "Price has reached the target")
- ///////////////////////TP Background
- // Define halving dates
- TPhalvingDates = array.new_int(0)
- array.push(TPhalvingDates, timestamp("2012-11-28 00:00"))
- array.push(TPhalvingDates, timestamp("2016-07-09 00:00"))
- array.push(TPhalvingDates, timestamp("2020-05-11 00:00"))
- array.push(TPhalvingDates, timestamp("2024-04-19 00:00"))
- array.push(TPhalvingDates, timestamp("2028-04-17 00:00"))
- // 40-week duration in milliseconds
- fortyWeeksMs = 40 * 7 * 24 * 60 * 60 * 1000
- // Determine the timeframe settings
- timeFrameMs = timeframe.isdaily ? 24 * 60 * 60 * 1000 :
- timeframe.isweekly ? 7 * 24 * 60 * 60 * 1000 :
- timeframe.ismonthly ? 30 * 24 * 60 * 60 * 1000 : na
- highlightColor = timeframe.isdaily ? #b13e0041 :
- timeframe.isweekly ? #b13e0041 :
- timeframe.ismonthly ? #b13e0041 : na
- offsetValue = timeframe.isdaily ? 280 :
- timeframe.isweekly ? 40 :
- timeframe.ismonthly ? 10 : na
- // Check if the current bar is within the 40-week window of any halving
- var bool inHighlightWindow = false
- inHighlightWindow := false // Reset for each bar
- if not na(timeFrameMs) // Only calculate if a valid timeframe is detected
- for i = 0 to array.size(halvingDates) - 1
- halvingStart = array.get(halvingDates, i)
- halvingEnd = halvingStart + fortyWeeksMs
- barStart = time
- barEnd = time + timeFrameMs
- if (barStart <= halvingEnd and barEnd >= halvingStart)
- inHighlightWindow := true
- break // Exit the loop once a matching window is found
- // Highlight the background only during the 40-week window for the current timeframe
- bgcolor(inHighlightWindow ? highlightColor : na, offset=offsetValue)
Advertisement
Add Comment
Please, Sign In to add comment