এটি মাসিক রিটার্ন প্রদর্শনের উপর ভিত্তি করে একটি পরিমাণগত ট্রেডিং কৌশল। এটি বিশ্লেষণের জন্য চার্টে একটি টেবিলে কৌশলটির মাসিক এবং বার্ষিক রিটার্ন, পাশাপাশি বেঞ্চমার্ক রিটার্নগুলি গণনা এবং উপস্থাপন করতে পাইন স্ক্রিপ্ট ব্যবহার করে।
এই কৌশলটির মূল যুক্তি হ'ল মাসিক এবং বার্ষিক কর্মক্ষমতা ট্র্যাক এবং গণনা করা এবং এটি একটি টেবিল ফর্ম্যাটে প্রদর্শন করা। মূল পদক্ষেপগুলি হ'লঃ
শেয়ারের পরিবর্তনের উপর ভিত্তি করে মাসিক ও বার্ষিক রিটার্ন গণনা করুন।
দামের পরিবর্তনের ভিত্তিতে মাসিক এবং বার্ষিক রেফারেন্স রিটার্ন গণনা করুন।
মাসিক এবং বার্ষিক রিটার্নগুলি অ্যারেগুলিতে সংরক্ষণ করুন।
যখন বারটি নিশ্চিত করা হয়, তখন মাসিক পারফরম্যান্স উপস্থাপনের জন্য সঞ্চিত রিটার্ন অ্যারে ব্যবহার করে একটি টেবিল পূরণ করুন।
টেবিলের দ্বিতীয় সারিতে বেঞ্চমার্ক প্রদর্শন করুন। তৃতীয় সারিতে আলফা প্রদর্শন করুন।
এটি করে, এই স্ক্রিপ্টটি একটি সংগঠিত টেবিলে মাসিক রিটার্নগুলি পরিষ্কারভাবে উপস্থাপন করতে পারে, বেঞ্চমার্ক তুলনা সহ। এটি কর্মক্ষমতা বিশ্লেষণ করতে সহায়তা করে।
এই মাসিক রিটার্ন কৌশলটির প্রধান সুবিধা হলঃ
মাসিক রিটার্নের স্বজ্ঞাত প্রদর্শন। টেবিল বিন্যাস কর্মক্ষমতা বিশ্লেষণ সহজ করে তোলে।
সুস্পষ্ট রেফারেন্সের তুলনা। একটি পৃথক রেফারেন্সের সারি প্রদর্শন করা কৌশল বনাম বাজার কর্মক্ষমতা বিশ্লেষণের অনুমতি দেয়।
আলফা গণনাঃ আলফা রেখায় দেখানো হয় যে কৌশলটি বেঞ্চমার্ককে ছাড়িয়ে যাচ্ছে/নিচে যাচ্ছে কিনা।
নমনীয়তার জন্য কাস্টমাইজযোগ্য পরামিতি। ব্যবহারকারী প্রয়োজন অনুযায়ী রং, তারিখ পরিসীমা, বেঞ্চমার্ক প্রতীক ইত্যাদি সেট করতে পারেন।
এই কৌশলটির সাথে কিছু ঝুঁকি রয়েছেঃ
কোন ট্রেডিং লজিক নেই, এটি কেবল রিটার্ন দেখায়, প্রকৃত ট্রেডগুলি অন্তর্ভুক্ত করে না।
ঐতিহাসিক পারফরম্যান্স অব্যাহত থাকতে পারে না। যেকোনো ব্যাকটেস্টের মতো, অতীতের রিটার্ন ভবিষ্যতের পারফরম্যান্সের গ্যারান্টি দেয় না।
রিটার্ন হিসাবের সম্ভাব্য ত্রুটি। বাগগুলি ভুল মাসিক রিটার্ন পরিসংখ্যান হতে পারে।
সামগ্রিকভাবে এই স্ক্রিপ্টটি মূলত পারফরম্যান্স ভিজ্যুয়ালাইজেশন সরঞ্জাম হিসাবে কাজ করে। রিটার্ন গণনার নির্ভুলতা নিশ্চিত করে এবং কেবল ব্যাকটেস্টের উপর নির্ভর না করে ঝুঁকিগুলি হ্রাস করা যেতে পারে।
এই মাসিক রিটার্ন কৌশল উন্নত করার কিছু উপায় হলঃ
প্রকৃত ট্রেডিং কৌশল যোগ করুন যার পারফরম্যান্স প্রদর্শিত হয়।
আরও বেঞ্চমার্ক কাস্টমাইজেশন প্যারামিটার যুক্ত করুন যেমন বেঞ্চমার্ক প্রতীক, সময়সীমা ইত্যাদি।
আরও ভাল ভিজ্যুয়ালের জন্য টেবিল ফরম্যাটিং উন্নত করুন - রং, কোষ, ফরম্যাটিং ইত্যাদি
আরও বিশ্লেষণের জন্য অন্যান্য রিটার্ন মেট্রিক্স - সিএজিআর, শার্প অনুপাত ইত্যাদি যুক্ত করুন।
এটি একটি কৌশল যা সহজ বিশ্লেষণের জন্য টেবিল ফর্ম্যাটে সিস্টেম এবং বেঞ্চমার্কের মাসিক রিটার্ন প্রদর্শনের উপর বিশেষভাবে দৃষ্টি নিবদ্ধ করে। এর সুবিধাগুলি হ'ল স্বজ্ঞাত ভিজ্যুয়ালাইজেশন এবং কৌশল বনাম বেঞ্চমার্কের তুলনা। ঝুঁকিগুলি হ'ল ট্রেডিং লজিকের অভাব এবং ব্যাকটেস্টের উপর নির্ভরশীলতা। এটি কোয়ান্ট কৌশলটির সাথে একত্রিত করে, আরও কাস্টমাইজেশন বিকল্প এবং আরও মেট্রিক যুক্ত করে উন্নত করা যেতে পারে।
/*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)