यह मासिक रिटर्न प्रदर्शित करने पर आधारित एक मात्रात्मक ट्रेडिंग रणनीति है। यह विश्लेषण के लिए चार्ट पर एक तालिका में रणनीति के मासिक और वार्षिक रिटर्न की गणना और प्रस्तुत करने के लिए पाइन स्क्रिप्ट का उपयोग करता है।
इस रणनीति का मूल तर्क मासिक और वार्षिक प्रदर्शन को ट्रैक और गणना करना और इसे तालिका प्रारूप में प्रदर्शित करना है।
इक्विटी में परिवर्तन के आधार पर मासिक और वार्षिक रिटर्न की गणना करें।
मूल्य परिवर्तन के आधार पर बेंचमार्क मासिक और वार्षिक रिटर्न की गणना करें।
मासिक और वार्षिक रिटर्न को सरणी में संग्रहीत करें।
जब बार की पुष्टि की जाती है, तो मासिक पर्फ प्रस्तुत करने के लिए संग्रहीत रिटर्न सरणियों का उपयोग करके तालिका को भरें.
तालिका की दूसरी पंक्ति में बेंचमार्क प्रदर्शित करें. तीसरी पंक्ति में अल्फा प्रदर्शित करें.
ऐसा करने से यह स्क्रिप्ट एक संगठित तालिका में मासिक रिटर्न को स्पष्ट रूप से प्रस्तुत कर सकती है, बेंचमार्क तुलना के साथ। यह प्रदर्शन का विश्लेषण करने में मदद करता है।
इस मासिक प्रतिफल रणनीति के मुख्य लाभ इस प्रकार हैंः
मासिक रिटर्न का सहज प्रदर्शन। तालिका प्रारूप प्रदर्शन का विश्लेषण करना आसान बनाता है।
स्पष्ट बेंचमार्क तुलना। एक अलग बेंचमार्क पंक्ति प्रदर्शित करने से रणनीति बनाम बाजार प्रदर्शन विश्लेषण की अनुमति मिलती है।
अल्फा गणनाः अल्फा पंक्ति में दिखाया गया है कि क्या रणनीति बेंचमार्क से बेहतर/अधिकांश प्रदर्शन कर रही है।
लचीलेपन के लिए अनुकूलन योग्य मापदंड। उपयोगकर्ता आवश्यकतानुसार रंग, दिनांक सीमा, बेंचमार्क प्रतीक आदि सेट कर सकता है।
इस रणनीति के साथ ध्यान देने योग्य कुछ जोखिम हैंः
कोई ट्रेडिंग लॉजिक नहीं. यह केवल रिटर्न प्रदर्शित करता है, वास्तविक ट्रेडों को शामिल नहीं करता है.
ऐतिहासिक प्रदर्शन जारी नहीं रह सकता है। किसी भी बैकटेस्ट के साथ, पिछले रिटर्न भविष्य के प्रदर्शन की गारंटी नहीं देते हैं।
रिटर्न की गणना में संभावित त्रुटियां। बग गलत मासिक रिटर्न के आंकड़ों का कारण बन सकते हैं।
कुल मिलाकर यह स्क्रिप्ट मुख्य रूप से प्रदर्शन विज़ुअलाइज़ेशन उपकरण के रूप में कार्य करती है। रिटर्न गणना की सटीकता सुनिश्चित करके जोखिम को कम किया जा सकता है और केवल बैकटेस्ट पर भरोसा नहीं किया जा सकता है।
इस मासिक रिटर्न रणनीति में सुधार करने के कुछ तरीके हैंः
वास्तविक ट्रेडिंग रणनीति जोड़ें जिसका प्रदर्शन प्रदर्शित किया जाता है. एक मात्रा रणनीति के साथ संयोजन.
अन्य बेंचमार्क अनुकूलन मापदंड जैसे बेंचमार्क प्रतीक, समय सीमा आदि जोड़ें।
बेहतर दृश्यों के लिए तालिका स्वरूपण में सुधार - रंग, कक्ष, स्वरूपण आदि
अधिक विश्लेषण के लिए अन्य रिटर्न मीट्रिक - सीएजीआर, शार्प अनुपात आदि जोड़ें।
यह एक रणनीति है जो विशेष रूप से आसान विश्लेषण के लिए तालिका प्रारूप में सिस्टम और बेंचमार्क के मासिक रिटर्न प्रदर्शित करने पर केंद्रित है। इसके फायदे अंतर्ज्ञानी विज़ुअलाइज़ेशन और रणनीति बनाम बेंचमार्क की तुलना हैं। जोखिम ट्रेडिंग लॉजिक की कमी और बैकटेस्ट पर निर्भरता हैं। इसे क्वांट रणनीति के साथ जोड़कर, और अधिक अनुकूलन विकल्प और अधिक मीट्रिक जोड़कर बढ़ाया जा सकता है।
/*backtest start: 2023-12-01 00:00:00 end: 2023-12-31 23:59:59 period: 2h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy('Monthly Returns with Benchmark', overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=25, commission_type=strategy.commission.percent, commission_value=0.1) //////////// // Inputs // // Pivot points inputs leftBars = input(2, group = "Pivot Points") rightBars = input(1, group = "Pivot Points") // Styling inputs prec = input(2, title='Return Precision', group = "Monthly Table") from_date = input(timestamp("01 Jan 2000 00:00 +0000"), "From Date", group = "Monthly Table") prof_color = input.color(color.green, title = "Gradient Colors", group = "Monthly Table", inline = "colors") loss_color = input.color(color.red, title = "", group = "Monthly Table", inline = "colors") // Benchmark inputs use_cur = input.bool(true, title = "Use current Symbol for Benchmark", group = "Benchmark") symb_bench = input('BTC_USDT:swap', title = "Benchmark", group = "Benchmark") disp_bench = input.bool(true, title = "Display Benchmark?", group = "Benchmark") disp_alpha = input.bool(true, title = "Display Alpha?", group = "Benchmark") // Pivot Points Strategy swh = ta.pivothigh(leftBars, rightBars) swl = ta.pivotlow(leftBars, rightBars) hprice = 0.0 hprice := not na(swh) ? swh : hprice[1] lprice = 0.0 lprice := not na(swl) ? swl : lprice[1] le = false le := not na(swh) ? true : le[1] and high > hprice ? false : le[1] se = false se := not na(swl) ? true : se[1] and low < lprice ? false : se[1] if le strategy.entry('PivRevLE', strategy.long, comment='PivRevLE', stop=hprice + syminfo.mintick) if se strategy.entry('PivRevSE', strategy.short, comment='PivRevSE', stop=lprice - syminfo.mintick) plot(hprice, color=color.new(color.green, 0), linewidth=2) plot(lprice, color=color.new(color.red, 0), linewidth=2) /////////////////// // MONTHLY TABLE // new_month = month(time) != month(time[1]) new_year = year(time) != year(time[1]) eq = strategy.equity bench_eq = close // benchmark eq bench_eq_htf = request.security(symb_bench, timeframe.period, close) if (not use_cur) bench_eq := bench_eq_htf bar_pnl = eq / eq[1] - 1 bench_pnl = bench_eq / bench_eq[1] - 1 cur_month_pnl = 0.0 cur_year_pnl = 0.0 // Current Monthly P&L cur_month_pnl := bar_index == 0 ? 0 : time >= from_date and (time[1] < from_date or new_month) ? bar_pnl : (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 // Current Yearly P&L cur_year_pnl := bar_index == 0 ? 0 : time >= from_date and (time[1] < from_date or new_year) ? bar_pnl : (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1 bench_cur_month_pnl = 0.0 bench_cur_year_pnl = 0.0 // Current Monthly P&L - Bench bench_cur_month_pnl := bar_index == 0 or (time[1] < from_date and time >= from_date) ? 0 : time >= from_date and new_month ? bench_pnl : (1 + bench_cur_month_pnl[1]) * (1 + bench_pnl) - 1 // Current Yearly P&L - Bench bench_cur_year_pnl := bar_index == 0 ? 0 : time >= from_date and (time[1] < from_date or new_year) ? bench_pnl : (1 + bench_cur_year_pnl[1]) * (1 + bench_pnl) - 1 var month_time = array.new_int(0) var year_time = array.new_int(0) var month_pnl = array.new_float(0) var year_pnl = array.new_float(0) var bench_month_pnl = array.new_float(0) var bench_year_pnl = array.new_float(0) // Filling monthly / yearly pnl arrays if array.size(month_time) > 0 if month(time) == month(array.get(month_time, array.size(month_time) - 1)) array.pop(month_pnl) array.pop(bench_month_pnl) array.pop(month_time) if array.size(year_time) > 0 if year(time) == year(array.get(year_time, array.size(year_time) - 1)) array.pop(year_pnl) array.pop(bench_year_pnl) array.pop(year_time) if (time >= from_date) array.push(month_time, time) array.push(year_time, time) array.push(month_pnl, cur_month_pnl) array.push(year_pnl, cur_year_pnl) array.push(bench_year_pnl, bench_cur_year_pnl) array.push(bench_month_pnl, bench_cur_month_pnl) // Monthly P&L Table var monthly_table = table(na) if array.size(year_pnl) > 0 and barstate.islastconfirmedhistory monthly_table := table.new(position.bottom_right, columns=15, rows=array.size(year_pnl) * 3 + 5, border_width=1) // Fill monthly performance table.cell(monthly_table, 0, 0, 'Perf', bgcolor = #999999) table.cell(monthly_table, 1, 0, 'Jan', bgcolor = #999999) table.cell(monthly_table, 2, 0, 'Feb', bgcolor = #999999) table.cell(monthly_table, 3, 0, 'Mar', bgcolor = #999999) table.cell(monthly_table, 4, 0, 'Apr', bgcolor = #999999) table.cell(monthly_table, 5, 0, 'May', bgcolor = #999999) table.cell(monthly_table, 6, 0, 'Jun', bgcolor = #999999) table.cell(monthly_table, 7, 0, 'Jul', bgcolor = #999999) table.cell(monthly_table, 8, 0, 'Aug', bgcolor = #999999) table.cell(monthly_table, 9, 0, 'Sep', bgcolor = #999999) table.cell(monthly_table, 10, 0, 'Oct', bgcolor = #999999) table.cell(monthly_table, 11, 0, 'Nov', bgcolor = #999999) table.cell(monthly_table, 12, 0, 'Dec', bgcolor = #999999) table.cell(monthly_table, 13, 0, ' ', bgcolor = #999999) table.cell(monthly_table, 14, 0, 'Year', bgcolor = #999999) max_abs_y = math.max(math.abs(array.max(year_pnl)), math.abs(array.min(year_pnl))) max_abs_m = math.max(math.abs(array.max(month_pnl)), math.abs(array.min(month_pnl))) for yi = 0 to array.size(year_pnl) - 1 by 1 table.cell(monthly_table, 0, yi + 1, str.tostring(year(array.get(year_time, yi))), bgcolor=#cccccc) table.cell(monthly_table, 13, yi + 1, ' ', bgcolor=#999999) y_color = color.from_gradient(array.get(year_pnl, yi), -max_abs_y, max_abs_y, loss_color, prof_color) table.cell(monthly_table, 14, yi + 1, str.tostring(math.round(array.get(year_pnl, yi) * 100, prec)), bgcolor=y_color) for mi = 0 to array.size(month_time) - 1 by 1 m_row = year(array.get(month_time, mi)) - year(array.get(year_time, 0)) + 1 m_col = month(array.get(month_time, mi)) m_color = color.from_gradient(array.get(month_pnl, mi), -max_abs_m, max_abs_m, loss_color, prof_color) table.cell(monthly_table, m_col, m_row, str.tostring(math.round(array.get(month_pnl, mi) * 100, prec)), bgcolor=m_color) // Fill benchmark performance next_row = array.size(year_pnl) + 1 if (disp_bench) table.cell(monthly_table, 0, next_row, 'Bench', bgcolor=#999999) table.cell(monthly_table, 1, next_row, 'Jan', bgcolor=#999999) table.cell(monthly_table, 2, next_row, 'Feb', bgcolor=#999999) table.cell(monthly_table, 3, next_row, 'Mar', bgcolor=#999999) table.cell(monthly_table, 4, next_row, 'Apr', bgcolor=#999999) table.cell(monthly_table, 5, next_row, 'May', bgcolor=#999999) table.cell(monthly_table, 6, next_row, 'Jun', bgcolor=#999999) table.cell(monthly_table, 7, next_row, 'Jul', bgcolor=#999999) table.cell(monthly_table, 8, next_row, 'Aug', bgcolor=#999999) table.cell(monthly_table, 9, next_row, 'Sep', bgcolor=#999999) table.cell(monthly_table, 10, next_row, 'Oct', bgcolor=#999999) table.cell(monthly_table, 11, next_row, 'Nov', bgcolor=#999999) table.cell(monthly_table, 12, next_row, 'Dec', bgcolor=#999999) table.cell(monthly_table, 13, next_row, ' ', bgcolor = #999999) table.cell(monthly_table, 14, next_row, 'Year', bgcolor=#999999) max_bench_abs_y = math.max(math.abs(array.max(bench_year_pnl)), math.abs(array.min(bench_year_pnl))) max_bench_abs_m = math.max(math.abs(array.max(bench_month_pnl)), math.abs(array.min(bench_month_pnl))) for yi = 0 to array.size(year_time) - 1 by 1 table.cell(monthly_table, 0, yi + 1 + next_row + 1, str.tostring(year(array.get(year_time, yi))), bgcolor=#cccccc) table.cell(monthly_table, 13, yi + 1 + next_row + 1, ' ', bgcolor=#999999) y_color = color.from_gradient(array.get(bench_year_pnl, yi), -max_bench_abs_y, max_bench_abs_y, loss_color, prof_color) table.cell(monthly_table, 14, yi + 1 + next_row + 1, str.tostring(math.round(array.get(bench_year_pnl, yi) * 100, prec)), bgcolor=y_color) for mi = 0 to array.size(month_time) - 1 by 1 m_row = year(array.get(month_time, mi)) - year(array.get(year_time, 0)) + 1 m_col = month(array.get(month_time, mi)) m_color = color.from_gradient(array.get(bench_month_pnl, mi), -max_bench_abs_m, max_bench_abs_m, loss_color, prof_color) table.cell(monthly_table, m_col, m_row + next_row + 1, str.tostring(math.round(array.get(bench_month_pnl, mi) * 100, prec)), bgcolor=m_color) // Fill Alpha if (disp_alpha) next_row := array.size(year_pnl) * 2 + 3 table.cell(monthly_table, 0, next_row, 'Alpha', bgcolor=#999999) table.cell(monthly_table, 1, next_row, 'Jan', bgcolor=#999999) table.cell(monthly_table, 2, next_row, 'Feb', bgcolor=#999999) table.cell(monthly_table, 3, next_row, 'Mar', bgcolor=#999999) table.cell(monthly_table, 4, next_row, 'Apr', bgcolor=#999999) table.cell(monthly_table, 5, next_row, 'May', bgcolor=#999999) table.cell(monthly_table, 6, next_row, 'Jun', bgcolor=#999999) table.cell(monthly_table, 7, next_row, 'Jul', bgcolor=#999999) table.cell(monthly_table, 8, next_row, 'Aug', bgcolor=#999999) table.cell(monthly_table, 9, next_row, 'Sep', bgcolor=#999999) table.cell(monthly_table, 10, next_row, 'Oct', bgcolor=#999999) table.cell(monthly_table, 11, next_row, 'Nov', bgcolor=#999999) table.cell(monthly_table, 12, next_row, 'Dec', bgcolor=#999999) table.cell(monthly_table, 13, next_row, '', bgcolor=#999999) table.cell(monthly_table, 14, next_row, 'Year', bgcolor=#999999) max_alpha_abs_y = 0.0 for yi = 0 to array.size(year_time) - 1 by 1 if (math.abs(array.get(year_pnl, yi) - array.get(bench_year_pnl, yi)) > max_alpha_abs_y) max_alpha_abs_y := math.abs(array.get(year_pnl, yi) - array.get(bench_year_pnl, yi)) max_alpha_abs_m = 0.0 for mi = 0 to array.size(month_pnl) - 1 by 1 if (math.abs(array.get(month_pnl, mi) - array.get(bench_month_pnl, mi)) > max_alpha_abs_m) max_alpha_abs_m := math.abs(array.get(month_pnl, mi) - array.get(bench_month_pnl, mi)) for yi = 0 to array.size(year_time) - 1 by 1 table.cell(monthly_table, 0, yi + 1 + next_row + 1, str.tostring(year(array.get(year_time, yi))), bgcolor=#cccccc) table.cell(monthly_table, 13, yi + 1 + next_row + 1, ' ', bgcolor=#999999) y_color = color.from_gradient(array.get(year_pnl, yi) - array.get(bench_year_pnl, yi), -max_alpha_abs_y, max_alpha_abs_y, loss_color, prof_color) table.cell(monthly_table, 14, yi + 1 + next_row + 1, str.tostring(math.round((array.get(year_pnl, yi) - array.get(bench_year_pnl, yi)) * 100, prec)), bgcolor=y_color) for mi = 0 to array.size(month_time) - 1 by 1 m_row = year(array.get(month_time, mi)) - year(array.get(year_time, 0)) + 1 m_col = month(array.get(month_time, mi)) m_color = color.from_gradient(array.get(month_pnl, mi) - array.get(bench_month_pnl, mi), -max_alpha_abs_m, max_alpha_abs_m, loss_color, prof_color) table.cell(monthly_table, m_col, m_row + next_row + 1, str.tostring(math.round((array.get(month_pnl, mi) - array.get(bench_month_pnl, mi)) * 100, prec)), bgcolor=m_color)