
এই কৌশলটি একটি পরিমাণগত ট্রেডিং কৌশল যা দ্বি-মুখী মূল্যের অস্থিরতার উপর ভিত্তি করে তৈরি করা হয়েছে। এটি পিভট উচ্চ-নিম্নগুলিকে মূল্যের মূল প্রতিরোধের স্তর হিসাবে ব্যবহার করে এবং দামগুলি পিভট উচ্চতা অতিক্রম করার সময় অতিরিক্ত করে এবং পিভট নিম্নের সময় ফাঁকা করে, দ্বি-মুখী অপারেশনটি সম্পাদন করে।
এই কৌশলটির কেন্দ্রীয় যুক্তিটি দ্বি-মুখী মূল্যের মূল পয়েন্টের উপর ভিত্তি করে। বিশেষ করে, নিম্নলিখিত পদক্ষেপগুলি রয়েছেঃ
একটি নির্দিষ্ট সময়ের জন্য Pivot High ও Low গণনা করুন। এখানে ta.pivothigh () এবং ta.pivotlow () ফাংশন ব্যবহার করা হয়। সর্বশেষ 2 দিনের সর্বোচ্চ মূল্যকে উচ্চ হিসাবে গণনা করা হয় এবং সর্বশেষ 1 দিনের সর্বনিম্ন মূল্যকে নিম্ন হিসাবে গণনা করা হয়।
যখন দাম উপরে গণনা করা সমালোচনামূলক উচ্চতা অতিক্রম করে, তখন অতিরিক্ত প্রবেশ করুন। যখন দাম সমালোচনামূলক নিম্নতা অতিক্রম করে, তখন খালি প্রবেশ করুন।
স্টপ লস পয়েন্ট ব্যবহার করুন। স্টপ লস উচ্চতম বিন্দু + সর্বনিম্ন মূল্য পরিবর্তন ইউনিট; স্টপ লস নিম্নতম বিন্দু - সর্বনিম্ন মূল্য পরিবর্তন ইউনিট।
এই ছবিগুলোতে দেখা যায় যে, এই ছবিগুলোতে কি-ওয়ার্ডস (কি-ওয়ার্ডস) ও কি-ওয়ার্ডস (কি-ওয়ার্ডস) রয়েছে।
এইভাবে, যখন দামের ঝাঁকুনি হয়, তখন কী পয়েন্টটি ভেঙে যাওয়ার সময় সময়মতো প্রবেশ করা যায় এবং দ্রুত ক্ষতি হয়, যার ফলে লাভ হয়। যখন দামগুলি নতুন উচ্চতা বা নতুন নিম্নতা অতিক্রম করে, তখন কৌশলটি একাধিক ক্রমাগত লাভ অর্জন করতে পারে।
এই দ্বি-মুখী কৌশলটির প্রধান সুবিধাগুলি হলঃ
সহজেই বোঝা যায়, সহজেই বাস্তবায়ন করা যায়। এই কৌশলটি কেবলমাত্র পিভট উচ্চ এবং নিম্ন পয়েন্টগুলি অতিক্রম করে প্রবেশের উপর নির্ভর করে, খুব সহজ।
সহজেই স্টপ সেট করা যায়। উচ্চ এবং নিম্ন + সর্বনিম্ন পরিবর্তনের দূরত্বের সাথে স্টপ পয়েন্ট হিসাবে আরও কমানো করা যায়, দ্রুত স্টপ করা যায় এবং ঝুঁকি কার্যকরভাবে নিয়ন্ত্রণ করা যায়।
এই কৌশলটি দুই দিকের অপারেশন করতে সক্ষম। এটি চলমান এবং লাভজনক হতে পারে, যাই হোক না কেন বাজি বা পতন।
যখন দামের ঘন ঘন উত্থান-পতন হয়, তখন কৌশলটি ঘন ঘন মাঠে প্রবেশ করে মুনাফা অর্জন করতে পারে।
যদিও এই কৌশলটি উপরের সুবিধাগুলির মধ্যে রয়েছে, তবে এর কিছু ঝুঁকি রয়েছে যা সম্পর্কে সতর্ক হওয়া দরকারঃ
ভুলভাবে মূল পয়েন্ট নির্ধারণ করলে ক্ষতি বাড়তে পারে। যদি মূল উচ্চ ও নিম্ন পয়েন্টটি ভুলভাবে সেট করা হয়, তবে চরম পরিস্থিতিতে উচ্চ ও নিচে নামতে পারে।
ঝড়ের শেষে ক্ষতির সূত্রপাত হতে পারে। যখন দামের ঝড়ের পরিবর্তে একতরফা ব্রেকডাউন শুরু হয় তখন এই কৌশলটি লাভজনক হতে পারে না।
একটি ব্রেকআউট হতে পারে একটি স্বল্পমেয়াদী মিথ্যা ব্রেকআউট। একটি স্বল্পমেয়াদী মিথ্যা ব্রেকআউটও হতে পারে, যা কৌশলটিকে ভুল লেনদেনের দিকে নিয়ে যায়।
সামগ্রিকভাবে, এই কৌশলটি ঝড়ের পরিস্থিতিতে ব্যবহারের জন্য আরও উপযুক্ত। বিনিয়োগকারীদের ট্রেন্ডিং পরিস্থিতিতে এই কৌশলটি ব্যবহার করা এড়াতে সতর্কতা অবলম্বন করা উচিত।
উপরোক্ত ঝুঁকির পরিপ্রেক্ষিতে, এই কৌশলটির জন্য অপ্টিমাইজেশনের সুযোগ রয়েছে, বিশেষ করে নিম্নলিখিত দিকগুলোতেঃ
স্মার্ট নির্বাচন কী উচ্চ এবং নিম্ন পয়েন্ট প্যারামিটার. মেশিন লার্নিং এবং অন্যান্য উপায়ে, সিস্টেমটি স্বয়ংক্রিয়ভাবে উপযুক্ত কী পয়েন্ট প্যারামিটার নির্বাচন করতে পারে।
প্রবণতা বিচার সমন্বয় কৌশল ভিত্তিতে প্রবণতা বিচার যুক্তিবিজ্ঞান যুক্ত করুন, শক পরিস্থিতিতে এই কৌশলটি ব্যবহার করুন, একতরফা প্রবণতার সময় কৌশলটি বন্ধ করুন, যার ফলে ক্ষতি হ্রাস করুন
স্টপ স্ট্র্যাটেজি বাড়ান। ঝুঁকি নিয়ন্ত্রণের জন্য আরও সুনির্দিষ্ট স্টপ স্ট্র্যাটেজি ডিজাইন করা যেতে পারে, যেমন মুভিং স্টপ, ব্রেকিং স্টপ ইত্যাদি।
এই কৌশলটি একটি সহজ ব্যবহারিক দ্বি-মুখী ব্রেকিং কৌশল। এটি মূল্যের মূল বিন্দুতে প্রবেশের উপর নির্ভর করে এবং স্টপ লস গ্যারান্টিযুক্ত ঝুঁকি নিয়ন্ত্রণযোগ্য। এই কৌশলটি অস্থিরতার জন্য উপযুক্ত এবং দ্বি-মুখী ব্যবসায়ের জন্য লাভজনক হতে পারে। তবে এই কৌশলটিও কিছু ঝুঁকি রয়েছে, বিনিয়োগকারীদের সতর্কতার সাথে ব্যবহার করা দরকার, বুদ্ধিমান নির্বাচনের পরামিতি, প্রবণতা বিচার এবং আরও সূক্ষ্ম স্টপ লস কৌশল ডিজাইনের সাথে সংযুক্ত।
/*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)