SavingFace

DCA Standard / BTC Weighted

Dec 16th, 2024 (edited)
501
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.26 KB | Cryptocurrency | 0 0
  1. //@version=5
  2. indicator("DCA Standard / Weighted", overlay=true)
  3.  
  4. ////// Power Law
  5. // Days X-Axis Value
  6. start = time == timestamp(2010, 7, 18, 0, 0) // First BLX Bitcoin Date
  7. days = request.security('BNC:BLX', 'D', ta.barssince(start))
  8. offset = 564 // days between 2009/1/1 and "start"
  9. d = days + offset
  10.  
  11. // Power Law
  12. a = -16.493
  13. b = 5.688
  14. e = a + b * math.log10(d)
  15. y = math.pow(10, e)
  16.  
  17. price_power_law = y
  18.  
  19. // Calculate +350% of the power law result with adjustable increments
  20. y_plus_350_percent_increment = input.int(100, title=" Weighted Scale Adjustment (10% steps)", minval=10, step=10)
  21. y_plus_350_percent = y * (1 + y_plus_350_percent_increment / 100)
  22.  
  23. // Calculate -30% of the power law result
  24. y_minus_30_percent = y * 0.7
  25.  
  26. // Calculate -60% of the power law result
  27. y_minus_60_percent = y * 0.4
  28.  
  29. // Reverse percentages for plots
  30. step_10_percent = (y_plus_350_percent - y_minus_30_percent) / 10
  31.  
  32. // Input to toggle visibility of blue plots
  33. showBluePlots = input(true, title="Show Percentage Deviations")
  34.  
  35. // Calculate reversed levels
  36. level_100 = y_minus_30_percent
  37. level_90 = y_minus_30_percent + step_10_percent
  38. level_80 = y_minus_30_percent + step_10_percent * 2
  39. level_70 = y_minus_30_percent + step_10_percent * 3
  40. level_60 = y_minus_30_percent + step_10_percent * 4
  41. level_50 = y_minus_30_percent + step_10_percent * 5
  42. level_40 = y_minus_30_percent + step_10_percent * 6
  43. level_30 = y_minus_30_percent + step_10_percent * 7
  44. level_20 = y_minus_30_percent + step_10_percent * 8
  45. level_10 = y_minus_30_percent + step_10_percent * 9
  46. level_0 = y_plus_350_percent
  47.  
  48. // Plot reversed levels if showBluePlots is enabled
  49. //pl1 = plot(showBluePlots ? level_0 : na, color=#ffebba7f, title='Level 0%')
  50. pl2 = plot(showBluePlots ? level_10 : na, color=#00ff087e, title='BTC 0% - USD 100%')
  51. pl3 = plot(showBluePlots ? level_20 : na, color=#ffebba7f, title='BTC 10% - USD 90%')
  52. pl4 = plot(showBluePlots ? level_30 : na, color=#ffebba7f, title='BTC 20% - USD 80%')
  53. pl5 = plot(showBluePlots ? level_40 : na, color=#ffebba7f, title='BTC 30% - USD 70%')
  54. pl6 = plot(showBluePlots ? level_50 : na, color=#ffebba7f, title='BTC 40% - USD 60%')
  55. pl7 = plot(showBluePlots ? level_60 : na, color=#ffebba7f, title='BTC 50% - USD 50%')
  56. pl8 = plot(showBluePlots ? level_70 : na, color=#ffebba7f, title='BTC 60% - USD 40%')
  57. pl9 = plot(showBluePlots ? level_80 : na, color=#ffebba7f, title='BTC 70% - USD 30%')
  58. pl10 = plot(showBluePlots ? level_90 : na, color=#ffebba7f, title='BTC 80% - USD 20%')
  59. pl11 = plot(showBluePlots ? level_100 : na, color=#ff590080, title='BTC/USD = 90%-10% ⬆ - 100% ⬇')
  60.  
  61. p4 = plot(y_minus_60_percent, color=#ffebba, title='Support')
  62. // Fill between levels
  63. fill = input(true, 'Fill?')
  64. fill(pl11, p4, color=fill ? color.rgb(93, 96, 107, 80) : na)
  65.  
  66.  
  67.  
  68. /////// Projection Logic
  69. projection_days = 50 // Number of days to project
  70. future_indexes = array.new_int(projection_days)
  71. future_prices = array.new_float(projection_days)
  72.  
  73. // Calculate projections dynamically
  74. for i = 1 to projection_days
  75. future_d = d + i
  76. future_y = math.pow(10, a + b * math.log10(future_d))
  77. array.set(future_prices, i - 1, future_y)
  78. array.set(future_indexes, i - 1, bar_index + i)
  79.  
  80. // Calculate future levels based on future_y
  81. future_y_plus_350_percent = future_y * (1 + y_plus_350_percent_increment / 100)
  82. future_y_minus_30_percent = future_y * 0.7
  83. future_y_minus_60_percent = future_y * 0.4 // Added future calculation for -60%
  84. future_step_10_percent = (future_y_plus_350_percent - future_y_minus_30_percent) / 10
  85.  
  86. future_level_100 = future_y_minus_30_percent
  87. future_level_90 = future_y_minus_30_percent + future_step_10_percent
  88. future_level_80 = future_y_minus_30_percent + future_step_10_percent * 2
  89. future_level_70 = future_y_minus_30_percent + future_step_10_percent * 3
  90. future_level_60 = future_y_minus_30_percent + future_step_10_percent * 4
  91. future_level_50 = future_y_minus_30_percent + future_step_10_percent * 5
  92. future_level_40 = future_y_minus_30_percent + future_step_10_percent * 6
  93. future_level_30 = future_y_minus_30_percent + future_step_10_percent * 7
  94. future_level_20 = future_y_minus_30_percent + future_step_10_percent * 8
  95. future_level_10 = future_y_minus_30_percent + future_step_10_percent * 9
  96. future_level_0 = future_y_plus_350_percent
  97.  
  98. // Variables to store labels
  99. var label[] projectionLabels = array.new<label>()
  100.  
  101. // Function to delete existing labels
  102. if array.size(projectionLabels) > 0
  103. for i = 0 to array.size(projectionLabels) - 1
  104. label.delete(array.get(projectionLabels, i))
  105. array.clear(projectionLabels)
  106.  
  107.  
  108.  
  109. //line.new(bar_index, y_minus_60_percent, bar_index + projection_days, future_y_minus_60_percent, color=color.new(#ffebba, 80), width=2)
  110. //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))
  111.  
  112. line.new(bar_index, level_100, bar_index + projection_days, future_level_100, color=color.new(#ff5900, 70), width=2)
  113. 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))
  114.  
  115. line.new(bar_index, level_90, bar_index + projection_days, future_level_90, color=color.new(#ffebba, 70), width=2)
  116. 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))
  117.  
  118. line.new(bar_index, level_80, bar_index + projection_days, future_level_80, color=color.new(#ffebba, 70), width=2)
  119. 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))
  120.  
  121. line.new(bar_index, level_70, bar_index + projection_days, future_level_70, color=color.new(#ffebba, 70), width=2)
  122. 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))
  123.  
  124. line.new(bar_index, level_60, bar_index + projection_days, future_level_60, color=color.new(#ffebba, 70), width=2)
  125. 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))
  126.  
  127. line.new(bar_index, level_50, bar_index + projection_days, future_level_50, color=color.new(#ffebba, 70), width=2)
  128. 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))
  129.  
  130. line.new(bar_index, level_40, bar_index + projection_days, future_level_40, color=color.new(#ffebba, 70), width=2)
  131. 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))
  132.  
  133. line.new(bar_index, level_30, bar_index + projection_days, future_level_30, color=color.new(#ffebba, 70), width=2)
  134. 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))
  135.  
  136. line.new(bar_index, level_20, bar_index + projection_days, future_level_20, color=color.new(#ffebba, 70), width=2)
  137. 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))
  138.  
  139. line.new(bar_index, level_10, bar_index + projection_days, future_level_10, color=color.new(#00ff0a, 70), width=2)
  140. 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))
  141.  
  142.  
  143.  
  144. /////////////////////////
  145.  
  146. /////////////////////////
  147. // DCA Table Logic
  148. // Input for selecting start and end years
  149. startYear = input.int(2020, title="Starting Year", minval=2000, maxval=2025)
  150. endYear = input.int(2024, title="Ending Year", minval=2000, maxval=2040)
  151.  
  152. // Input to select DCA frequency: daily, weekly, or monthly
  153. dcaFrequency = input.string("Once a Month", title="DCA Frequency", options=["Once a Day", "Once a Week", "Once a Month"])
  154.  
  155. // Input to choose table position: top, middle, or bottom
  156. tablePosition = input.string("Top", title="Table Position", options=["Top", "Middle", "Bottom"])
  157.  
  158. // Input to toggle between Standard and Weighted DCA
  159. dcaMode = input.string("Standard", title="DCA Mode", options=["Standard", "Weighted"])
  160.  
  161. // Get the current year from the timestamp
  162. currentYear = year
  163.  
  164. // Define the amount to invest per period
  165. investmentAmount = input.float(100, title="Investment Amount")
  166.  
  167. // Check if the current year is within the selected range
  168. isWithinYearRange = currentYear >= startYear and currentYear <= endYear
  169.  
  170. // Define DCA period based on the selected frequency
  171. var bool shouldInvest = false
  172. if dcaFrequency == "Once a Day"
  173. shouldInvest := ta.change(time("D"))
  174. else if dcaFrequency == "Once a Week"
  175. shouldInvest := ta.change(time("W"))
  176. else if dcaFrequency == "Once a Month"
  177. shouldInvest := ta.change(time("M"))
  178.  
  179. // Accumulate investments over time
  180. var float totalInvestedBTC = 0
  181. var float totalSharesBTC = 0
  182. var float totalInvestedStable = 0
  183.  
  184. var float weightBTC = na
  185. var float weightStable = na
  186.  
  187. // Update weights based on live price
  188. 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
  189. weightStable := 100 - weightBTC
  190.  
  191. // Perform DCA only within the specified year range
  192. if (isWithinYearRange)
  193. if shouldInvest
  194. if dcaMode == "Weighted"
  195. investedBTC = investmentAmount * (weightBTC / 100)
  196. investedStable = investmentAmount * (weightStable / 100)
  197.  
  198. totalInvestedBTC += investedBTC
  199. totalInvestedStable += investedStable
  200. totalSharesBTC += investedBTC / close
  201.  
  202. // Calculate SATs per investment for BTC
  203. satsPerInvestment = (investedBTC / close) * 100000000 // 1 Bitcoin = 100,000,000 SATs
  204.  
  205. else
  206. totalInvestedBTC += investmentAmount
  207. totalSharesBTC += investmentAmount / close
  208.  
  209. // Calculate SATs per investment for BTC
  210. satsPerInvestment = (investmentAmount / close) * 100000000
  211.  
  212. // Stablecoin reserve logic
  213. stableReserveInvest = isWithinYearRange and shouldInvest and close < y_minus_30_percent and totalInvestedStable > 0
  214. reserveInvestment = stableReserveInvest ? math.min(totalInvestedStable, investmentAmount) : 0
  215. if (stableReserveInvest)
  216. totalInvestedBTC += reserveInvestment
  217. totalSharesBTC += reserveInvestment / close
  218. totalInvestedStable -= reserveInvestment
  219.  
  220. // Calculate the average entry price for BTC
  221. averagePriceBTC = totalInvestedBTC / totalSharesBTC
  222.  
  223. // Plot the average DCA price on the chart as a line
  224. plot(averagePriceBTC, color=#ff5a00, title="Average DCA Price")
  225.  
  226. // Calculate the percentage difference from average entry to current price
  227. percentageDifferenceBTC = ((close - averagePriceBTC) / averagePriceBTC) * 100
  228.  
  229. // Calculate P&L (Profit and Loss) for BTC
  230. P_L_BTC = (close - averagePriceBTC) * totalSharesBTC
  231.  
  232. // Calculate Total Invested + P&L (Current Value for BTC)
  233. totalValueBTC = totalInvestedBTC + P_L_BTC
  234.  
  235. totalInvested = totalInvestedBTC + totalInvestedStable
  236.  
  237. // Calculate percentage ratio between stablecoins and BTC
  238. stableToBTCRatio = weightStable
  239. btcToStableRatio = weightBTC
  240.  
  241. // Plot a tiny circle on the chart when DCA happens, only within the year range
  242. DCAcolor = close < level_10 ? #ff59007e : close > level_10 ? #00c50780 : na
  243. plotshape(series=shouldInvest and isWithinYearRange, location=location.belowbar, style=shape.circle, size=size.tiny, color=DCAcolor)
  244.  
  245. // Plot a tiny circle on top of the bar to represent reserve purchases
  246. plotshape(series=stableReserveInvest, location=location.abovebar, style=shape.circle, size=size.tiny, color=#00c50780, title="Stablecoin Reserve Purchase")
  247.  
  248. // Add a label at the latest bar that follows the plot of the average price, and delete previous label to prevent repetition
  249. var label avgEntryLabel = na
  250. if not na(avgEntryLabel)
  251. label.delete(avgEntryLabel)
  252. 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)
  253.  
  254.  
  255. //////////////////
  256. // Determine table position based on user input
  257. var table dcaTable = na
  258. if tablePosition == "Top"
  259. dcaTable := table.new(position.top_right, 10, 10, border_color=color.black, frame_color=color.black, bgcolor=color.gray)
  260. else if tablePosition == "Middle"
  261. dcaTable := table.new(position.middle_right, 10, 10, border_color=color.black, frame_color=color.black, bgcolor=color.gray)
  262. else
  263. dcaTable := table.new(position.bottom_right, 10, 10, border_color=color.black, frame_color=color.black, bgcolor=color.gray)
  264.  
  265. // Clear and update the table with total invested, average entry, percentage difference, P&L, and total value (Invested + P&L)
  266. table.cell(dcaTable, 0, 0, "BTC/Stable Ratio", text_color=color.white, bgcolor=#363a45)
  267. table.cell(dcaTable, 1, 0, str.tostring(btcToStableRatio, "#.##") + "% / " + str.tostring(stableToBTCRatio, "#.##") + "%", text_color=#000000, bgcolor=#5a5a5a)
  268.  
  269. table.cell(dcaTable, 0, 1, "BTC Reserve", text_color=#ff5a00, bgcolor=#5a5a5a)
  270. table.cell(dcaTable, 1, 1, "$" + str.tostring(totalValueBTC, "#.##"), text_color=#000000 ,bgcolor=color.rgb(255, 89, 0, 50))
  271.  
  272. table.cell(dcaTable, 0, 2, "Stablecoin Reserve", text_color=#00c508, bgcolor=#5a5a5a)
  273. table.cell(dcaTable, 1, 2, "$" + str.tostring(totalInvestedStable, "#.##"), text_color=#000000, bgcolor=color.rgb(0, 197, 7, 50))
  274.  
  275. table.cell(dcaTable, 0, 3, "Total Invested BTC", text_color=color.white, bgcolor=#5a5a5a)
  276. table.cell(dcaTable, 1, 3, "$" + str.tostring(totalInvestedBTC, "#.##"), text_color=#000000)
  277.  
  278. table.cell(dcaTable, 0, 4, "Average Entry BTC", text_color=color.white, bgcolor=#5a5a5a)
  279. table.cell(dcaTable, 1, 4, "$" + str.tostring(averagePriceBTC, "#.##"), text_color=#000000)
  280.  
  281. table.cell(dcaTable, 0, 5, "% Profitable", text_color=color.white, bgcolor=#5a5a5a)
  282. table.cell(dcaTable, 1, 5, str.tostring(percentageDifferenceBTC, "#.##") + "%", text_color=#000000)
  283.  
  284. table.cell(dcaTable, 0, 6, "P&L BTC", text_color=color.white, bgcolor=#5a5a5a)
  285. table.cell(dcaTable, 1, 6, "$" + str.tostring(P_L_BTC, "#.##"), text_color=#000000)
  286.  
  287. // Adding Total BTC Amount row
  288. totalBTCAmount = totalInvestedBTC / averagePriceBTC // Calculate total BTC amount
  289. table.cell(dcaTable, 0, 7, "Total BTC Amount", text_color=color.white, bgcolor=#5a5a5a)
  290. table.cell(dcaTable, 1, 7, str.tostring(totalBTCAmount, "#.####") + " BTC", text_color=#000000, bgcolor=color.rgb(0, 120, 255, 50))
  291.  
  292. ////////////////////
  293.  
  294. //ATH
  295. // Variables to track the all-time high
  296. var float all_time_high = na
  297. var line all_time_high_line = na
  298. var label all_time_high_label = na
  299.  
  300. // Check if the current high exceeds the all-time high
  301. if na(all_time_high) or high > all_time_high
  302. all_time_high := high // Update the all-time high if a new high is made
  303. // Delete previous line and label
  304. if not na(all_time_high_line)
  305. line.delete(all_time_high_line)
  306. if not na(all_time_high_label)
  307. label.delete(all_time_high_label)
  308. // Create new line and label
  309. 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)
  310. 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)
  311.  
  312.  
Advertisement
Add Comment
Please, Sign In to add comment