Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //@version=5
- indicator("DCA Standard / Weighted", overlay=true)
- ////// 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 = -16.493
- b = 5.688
- e = a + b * math.log10(d)
- y = math.pow(10, e)
- price_power_law = y
- // Calculate +350% of the power law result with adjustable increments
- y_plus_350_percent_increment = input.int(100, title=" Weighted Scale Adjustment (10% steps)", minval=10, step=10)
- y_plus_350_percent = y * (1 + y_plus_350_percent_increment / 100)
- // 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
- // Reverse percentages for plots
- step_10_percent = (y_plus_350_percent - y_minus_30_percent) / 10
- // Input to toggle visibility of blue plots
- showBluePlots = input(true, title="Show Percentage Deviations")
- // Calculate reversed levels
- level_100 = y_minus_30_percent
- level_90 = y_minus_30_percent + step_10_percent
- level_80 = y_minus_30_percent + step_10_percent * 2
- level_70 = y_minus_30_percent + step_10_percent * 3
- level_60 = y_minus_30_percent + step_10_percent * 4
- level_50 = y_minus_30_percent + step_10_percent * 5
- level_40 = y_minus_30_percent + step_10_percent * 6
- level_30 = y_minus_30_percent + step_10_percent * 7
- level_20 = y_minus_30_percent + step_10_percent * 8
- level_10 = y_minus_30_percent + step_10_percent * 9
- level_0 = y_plus_350_percent
- // Plot reversed levels if showBluePlots is enabled
- //pl1 = plot(showBluePlots ? level_0 : na, color=#ffebba7f, title='Level 0%')
- pl2 = plot(showBluePlots ? level_10 : na, color=#00ff087e, title='BTC 0% - USD 100%')
- pl3 = plot(showBluePlots ? level_20 : na, color=#ffebba7f, title='BTC 10% - USD 90%')
- pl4 = plot(showBluePlots ? level_30 : na, color=#ffebba7f, title='BTC 20% - USD 80%')
- pl5 = plot(showBluePlots ? level_40 : na, color=#ffebba7f, title='BTC 30% - USD 70%')
- pl6 = plot(showBluePlots ? level_50 : na, color=#ffebba7f, title='BTC 40% - USD 60%')
- pl7 = plot(showBluePlots ? level_60 : na, color=#ffebba7f, title='BTC 50% - USD 50%')
- pl8 = plot(showBluePlots ? level_70 : na, color=#ffebba7f, title='BTC 60% - USD 40%')
- pl9 = plot(showBluePlots ? level_80 : na, color=#ffebba7f, title='BTC 70% - USD 30%')
- pl10 = plot(showBluePlots ? level_90 : na, color=#ffebba7f, title='BTC 80% - USD 20%')
- pl11 = plot(showBluePlots ? level_100 : na, color=#ff590080, title='BTC/USD = 90%-10% ⬆ - 100% ⬇')
- p4 = plot(y_minus_60_percent, color=#ffebba, title='Support')
- // Fill between levels
- fill = input(true, 'Fill?')
- fill(pl11, p4, color=fill ? color.rgb(93, 96, 107, 80) : na)
- /////// Projection Logic
- projection_days = 50 // Number of days to project
- future_indexes = array.new_int(projection_days)
- future_prices = array.new_float(projection_days)
- // Calculate projections dynamically
- for i = 1 to projection_days
- future_d = d + i
- future_y = math.pow(10, a + b * math.log10(future_d))
- array.set(future_prices, i - 1, future_y)
- array.set(future_indexes, i - 1, bar_index + i)
- // Calculate future levels based on future_y
- future_y_plus_350_percent = future_y * (1 + y_plus_350_percent_increment / 100)
- future_y_minus_30_percent = future_y * 0.7
- future_y_minus_60_percent = future_y * 0.4 // Added future calculation for -60%
- future_step_10_percent = (future_y_plus_350_percent - future_y_minus_30_percent) / 10
- future_level_100 = future_y_minus_30_percent
- future_level_90 = future_y_minus_30_percent + future_step_10_percent
- future_level_80 = future_y_minus_30_percent + future_step_10_percent * 2
- future_level_70 = future_y_minus_30_percent + future_step_10_percent * 3
- future_level_60 = future_y_minus_30_percent + future_step_10_percent * 4
- future_level_50 = future_y_minus_30_percent + future_step_10_percent * 5
- future_level_40 = future_y_minus_30_percent + future_step_10_percent * 6
- future_level_30 = future_y_minus_30_percent + future_step_10_percent * 7
- future_level_20 = future_y_minus_30_percent + future_step_10_percent * 8
- future_level_10 = future_y_minus_30_percent + future_step_10_percent * 9
- future_level_0 = future_y_plus_350_percent
- // Variables to store labels
- var label[] projectionLabels = array.new<label>()
- // Function to delete existing labels
- if array.size(projectionLabels) > 0
- for i = 0 to array.size(projectionLabels) - 1
- label.delete(array.get(projectionLabels, i))
- array.clear(projectionLabels)
- //line.new(bar_index, y_minus_60_percent, bar_index + projection_days, future_y_minus_60_percent, color=color.new(#ffebba, 80), width=2)
- //array.push(projectionLabels, label.new(bar_index + projection_days, future_y_minus_60_percent, text="Level -60%", style=label.style_label_down, color=color.new(#ffebba, 50), textcolor=color.black))
- line.new(bar_index, level_100, bar_index + projection_days, future_level_100, color=color.new(#ff5900, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_100, text="BTC/USD = 90%-10% ⬆ - 100% ⬇", style=label.style_label_left, color=color.new(#ff5900, 50), textcolor=#ffebba80))
- line.new(bar_index, level_90, bar_index + projection_days, future_level_90, color=color.new(#ffebba, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_90, text="BTC 80% - USD 20% ⬆", style=label.style_label_left, color=color.new(#ffebba, 50), textcolor=color.black))
- line.new(bar_index, level_80, bar_index + projection_days, future_level_80, color=color.new(#ffebba, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_80, text="BTC 70% - USD 30% ⬆", style=label.style_label_left, color=color.new(#ffebba, 50), textcolor=color.black))
- line.new(bar_index, level_70, bar_index + projection_days, future_level_70, color=color.new(#ffebba, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_70, text="BTC 60% - USD 40% ⬆", style=label.style_label_left, color=color.new(#ffebba, 50), textcolor=color.black))
- line.new(bar_index, level_60, bar_index + projection_days, future_level_60, color=color.new(#ffebba, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_60, text="BTC 50% - USD 50% ⬆", style=label.style_label_left, color=color.new(#ffebba, 50), textcolor=color.black))
- line.new(bar_index, level_50, bar_index + projection_days, future_level_50, color=color.new(#ffebba, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_50, text="BTC 40% - USD 60% ⬆", style=label.style_label_left, color=color.new(#ffebba, 50), textcolor=color.black))
- line.new(bar_index, level_40, bar_index + projection_days, future_level_40, color=color.new(#ffebba, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_40, text="BTC 30% - USD 70% ⬆", style=label.style_label_left, color=color.new(#ffebba, 50), textcolor=color.black))
- line.new(bar_index, level_30, bar_index + projection_days, future_level_30, color=color.new(#ffebba, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_30, text="BTC 20% - USD 80% ⬆", style=label.style_label_left, color=color.new(#ffebba, 50), textcolor=color.black))
- line.new(bar_index, level_20, bar_index + projection_days, future_level_20, color=color.new(#ffebba, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_20, text="BTC 10% - USD 90% ⬆", style=label.style_label_left, color=color.new(#ffebba, 50), textcolor=color.black))
- line.new(bar_index, level_10, bar_index + projection_days, future_level_10, color=color.new(#00ff0a, 70), width=2)
- array.push(projectionLabels, label.new(bar_index + projection_days, future_level_10, text="BTC 0% - USD 100% ⬆", style=label.style_label_left, color=color.new(#00ff0a,50), textcolor=color.black))
- /////////////////////////
- /////////////////////////
- // DCA Table Logic
- // Input for selecting start and end years
- startYear = input.int(2020, title="Starting Year", minval=2000, maxval=2025)
- endYear = input.int(2024, title="Ending Year", minval=2000, maxval=2040)
- // Input to select DCA frequency: daily, weekly, or monthly
- dcaFrequency = input.string("Once a Month", title="DCA Frequency", options=["Once a Day", "Once a Week", "Once a Month"])
- // Input to choose table position: top, middle, or bottom
- tablePosition = input.string("Top", title="Table Position", options=["Top", "Middle", "Bottom"])
- // Input to toggle between Standard and Weighted DCA
- dcaMode = input.string("Standard", title="DCA Mode", options=["Standard", "Weighted"])
- // Get the current year from the timestamp
- currentYear = year
- // Define the amount to invest per period
- investmentAmount = input.float(100, title="Investment Amount")
- // Check if the current year is within the selected range
- isWithinYearRange = currentYear >= startYear and currentYear <= endYear
- // Define DCA period based on the selected frequency
- var bool shouldInvest = false
- if dcaFrequency == "Once a Day"
- shouldInvest := ta.change(time("D"))
- else if dcaFrequency == "Once a Week"
- shouldInvest := ta.change(time("W"))
- else if dcaFrequency == "Once a Month"
- shouldInvest := ta.change(time("M"))
- // Accumulate investments over time
- var float totalInvestedBTC = 0
- var float totalSharesBTC = 0
- var float totalInvestedStable = 0
- var float weightBTC = na
- var float weightStable = na
- // Update weights based on live price
- weightBTC := close > y_plus_350_percent ? 0 : close <= level_100 ? 100 : close <= level_90 ? 90 : close <= level_80 ? 80 : close <= level_70 ? 70 : close <= level_60 ? 60 : close <= level_50 ? 50 : close <= level_40 ? 40 : close <= level_30 ? 30 : close <= level_20 ? 20 : close <= level_10 ? 10 : 0
- weightStable := 100 - weightBTC
- // Perform DCA only within the specified year range
- if (isWithinYearRange)
- if shouldInvest
- if dcaMode == "Weighted"
- investedBTC = investmentAmount * (weightBTC / 100)
- investedStable = investmentAmount * (weightStable / 100)
- totalInvestedBTC += investedBTC
- totalInvestedStable += investedStable
- totalSharesBTC += investedBTC / close
- // Calculate SATs per investment for BTC
- satsPerInvestment = (investedBTC / close) * 100000000 // 1 Bitcoin = 100,000,000 SATs
- else
- totalInvestedBTC += investmentAmount
- totalSharesBTC += investmentAmount / close
- // Calculate SATs per investment for BTC
- satsPerInvestment = (investmentAmount / close) * 100000000
- // Stablecoin reserve logic
- stableReserveInvest = isWithinYearRange and shouldInvest and close < y_minus_30_percent and totalInvestedStable > 0
- reserveInvestment = stableReserveInvest ? math.min(totalInvestedStable, investmentAmount) : 0
- if (stableReserveInvest)
- totalInvestedBTC += reserveInvestment
- totalSharesBTC += reserveInvestment / close
- totalInvestedStable -= reserveInvestment
- // Calculate the average entry price for BTC
- averagePriceBTC = totalInvestedBTC / totalSharesBTC
- // Plot the average DCA price on the chart as a line
- plot(averagePriceBTC, color=#ff5a00, title="Average DCA Price")
- // Calculate the percentage difference from average entry to current price
- percentageDifferenceBTC = ((close - averagePriceBTC) / averagePriceBTC) * 100
- // Calculate P&L (Profit and Loss) for BTC
- P_L_BTC = (close - averagePriceBTC) * totalSharesBTC
- // Calculate Total Invested + P&L (Current Value for BTC)
- totalValueBTC = totalInvestedBTC + P_L_BTC
- totalInvested = totalInvestedBTC + totalInvestedStable
- // Calculate percentage ratio between stablecoins and BTC
- stableToBTCRatio = weightStable
- btcToStableRatio = weightBTC
- // Plot a tiny circle on the chart when DCA happens, only within the year range
- DCAcolor = close < level_10 ? #ff59007e : close > level_10 ? #00c50780 : na
- plotshape(series=shouldInvest and isWithinYearRange, location=location.belowbar, style=shape.circle, size=size.tiny, color=DCAcolor)
- // Plot a tiny circle on top of the bar to represent reserve purchases
- plotshape(series=stableReserveInvest, location=location.abovebar, style=shape.circle, size=size.tiny, color=#00c50780, title="Stablecoin Reserve Purchase")
- // Add a label at the latest bar that follows the plot of the average price, and delete previous label to prevent repetition
- var label avgEntryLabel = na
- if not na(avgEntryLabel)
- label.delete(avgEntryLabel)
- avgEntryLabel := label.new(bar_index, averagePriceBTC, text="Average Entry\n" + str.tostring(percentageDifferenceBTC, "#.##") + "%", style=label.style_label_left, color=#ff5a00, textcolor=color.black, size=size.small)
- //////////////////
- // Determine table position based on user input
- var table dcaTable = na
- if tablePosition == "Top"
- dcaTable := table.new(position.top_right, 10, 10, border_color=color.black, frame_color=color.black, bgcolor=color.gray)
- else if tablePosition == "Middle"
- dcaTable := table.new(position.middle_right, 10, 10, border_color=color.black, frame_color=color.black, bgcolor=color.gray)
- else
- dcaTable := table.new(position.bottom_right, 10, 10, border_color=color.black, frame_color=color.black, bgcolor=color.gray)
- // Clear and update the table with total invested, average entry, percentage difference, P&L, and total value (Invested + P&L)
- table.cell(dcaTable, 0, 0, "BTC/Stable Ratio", text_color=color.white, bgcolor=#363a45)
- table.cell(dcaTable, 1, 0, str.tostring(btcToStableRatio, "#.##") + "% / " + str.tostring(stableToBTCRatio, "#.##") + "%", text_color=#000000, bgcolor=#5a5a5a)
- table.cell(dcaTable, 0, 1, "BTC Reserve", text_color=#ff5a00, bgcolor=#5a5a5a)
- table.cell(dcaTable, 1, 1, "$" + str.tostring(totalValueBTC, "#.##"), text_color=#000000 ,bgcolor=color.rgb(255, 89, 0, 50))
- table.cell(dcaTable, 0, 2, "Stablecoin Reserve", text_color=#00c508, bgcolor=#5a5a5a)
- table.cell(dcaTable, 1, 2, "$" + str.tostring(totalInvestedStable, "#.##"), text_color=#000000, bgcolor=color.rgb(0, 197, 7, 50))
- table.cell(dcaTable, 0, 3, "Total Invested BTC", text_color=color.white, bgcolor=#5a5a5a)
- table.cell(dcaTable, 1, 3, "$" + str.tostring(totalInvestedBTC, "#.##"), text_color=#000000)
- table.cell(dcaTable, 0, 4, "Average Entry BTC", text_color=color.white, bgcolor=#5a5a5a)
- table.cell(dcaTable, 1, 4, "$" + str.tostring(averagePriceBTC, "#.##"), text_color=#000000)
- table.cell(dcaTable, 0, 5, "% Profitable", text_color=color.white, bgcolor=#5a5a5a)
- table.cell(dcaTable, 1, 5, str.tostring(percentageDifferenceBTC, "#.##") + "%", text_color=#000000)
- table.cell(dcaTable, 0, 6, "P&L BTC", text_color=color.white, bgcolor=#5a5a5a)
- table.cell(dcaTable, 1, 6, "$" + str.tostring(P_L_BTC, "#.##"), text_color=#000000)
- // Adding Total BTC Amount row
- totalBTCAmount = totalInvestedBTC / averagePriceBTC // Calculate total BTC amount
- table.cell(dcaTable, 0, 7, "Total BTC Amount", text_color=color.white, bgcolor=#5a5a5a)
- table.cell(dcaTable, 1, 7, str.tostring(totalBTCAmount, "#.####") + " BTC", text_color=#000000, bgcolor=color.rgb(0, 120, 255, 50))
- ////////////////////
- //ATH
- // Variables to track the all-time high
- var float all_time_high = na
- var line all_time_high_line = na
- var label all_time_high_label = na
- // Check if the current high exceeds the all-time high
- if na(all_time_high) or high > all_time_high
- all_time_high := high // Update the all-time high if a new high is made
- // Delete previous line and label
- if not na(all_time_high_line)
- line.delete(all_time_high_line)
- if not na(all_time_high_label)
- label.delete(all_time_high_label)
- // Create new line and label
- all_time_high_line := line.new(x1=bar_index, y1=all_time_high, x2=bar_index + 1, y2=all_time_high, color=#03ac0a, width=1, extend=extend.right)
- all_time_high_label := label.new(x=bar_index, y=all_time_high, text="ATH:" + str.tostring(all_time_high, format.mintick), style=label.style_label_down, color=#03ac0a, textcolor=#0d0d0d)
Advertisement
Add Comment
Please, Sign In to add comment