পিভট বিপরীত ভিত্তিক পরিমাণগত ট্রেডিং কৌশল

লেখক:চাওঝাং, তারিখ: ২০২৩-১২-১২ ১১ঃ০৭ঃ৪৬
ট্যাগঃ

img

সারসংক্ষেপ

এটি একটি পরিমাণগত ট্রেডিং কৌশল যা প্রবেশের সংকেত হিসাবে পিভট পয়েন্টগুলি ব্যবহার করে। এটি উত্থান পিভট পয়েন্ট এবং পতন পিভট পয়েন্টগুলি গণনা করে। একবার দাম এই পিভট পয়েন্টগুলি ভেঙে গেলে, এটি দীর্ঘ বা সংক্ষিপ্ত অবস্থানগুলি শুরু করবে।

কৌশল নীতি

এই কৌশলটি মূলত পিভট বিপরীত তত্ত্বের উপর ভিত্তি করে। এটি প্রথমে বাম এন বার এবং ডান এম বারগুলির উপর ভিত্তি করে পিভট পয়েন্টগুলি গণনা করে। তারপরে এটি রিয়েল টাইমে পর্যবেক্ষণ করে যে দামটি এই পিভট পয়েন্টগুলি ভেঙেছে কিনা।

যখন মূল্য উত্থান পিভট পয়েন্টটি ভেঙে যায়, এর অর্থ হল যে দামকে আরও বাড়িয়ে তুলতে আপগ্রেডের গতি আর যথেষ্ট নয়। এই সময়ে, শর্ট যেতে ভাল রিটার্ন দিতে পারে। যখন মূল্য হ্রাস পিভট পয়েন্টটি ভেঙে যায়, এর অর্থ হ'ল ডাউনগ্রেডের গতি শেষ হয়ে গেছে। এই সময়ে, দীর্ঘ যেতে ভাল রিটার্ন পেতে পারে।

বিশেষত, এই কৌশলটি ta.pivothigh এবং ta.pivotlow ফাংশনগুলির মাধ্যমে উত্থান পিভট পয়েন্ট এবং পতনের পিভট পয়েন্টগুলি গণনা করে। তারপরে এটি বর্তমান সর্বোচ্চ মূল্যটি উত্থান পিভট পয়েন্টটি ভেঙে দেয় এবং সর্বনিম্ন মূল্যটি পতনের পিভট পয়েন্টটি ভেঙে দেয় কিনা তা তুলনা করে। যদি কোনও অগ্রগতি হয় তবে সংশ্লিষ্ট দীর্ঘ বা সংক্ষিপ্ত কৌশলটি শুরু করা হবে।

এছাড়াও, এই কৌশলটি ঝুঁকি নিয়ন্ত্রণের জন্য স্টপ লসও ব্যবহার করে। বিশেষত, যখন দাম পিভট পয়েন্টটি ভেঙে যায়, তখন এটি পিভট পয়েন্টের অন্য দিকে স্টপ লস সেট করার সময় অবিলম্বে একটি অর্ডার দেয়। এটি একটি ব্যর্থ সংকেতের কারণে ক্ষতি হ্রাস করতে পারে।

সুবিধা বিশ্লেষণ

এই পিভট বিপরীত ভিত্তিক কৌশল নিম্নলিখিত সুবিধা আছেঃ

  1. পিভট বিপরীত সংকেত একটি উচ্চ বিজয়ী হার সঙ্গে বেশ নির্ভরযোগ্য
  2. যুক্তিসঙ্গত স্টপ লস সেটিং দিয়ে ঝুঁকি ভালভাবে নিয়ন্ত্রিত
  3. সংক্ষিপ্ত কোড দিয়ে এটি বাস্তবায়ন করা সহজ
  4. এটি ভাল নমনীয়তা সহ বিভিন্ন পণ্যের জন্য প্রযোজ্য

ঝুঁকি বিশ্লেষণ

এই কৌশলটির কিছু ঝুঁকি রয়েছেঃ

  1. পিভট পয়েন্ট ব্যর্থ হতে পারে, যার ফলে ভুল সংকেত
  2. পিভট পয়েন্ট ভঙ্গ করার পর সেখানে pullback হতে পারে, স্টপ লস ট্রিগার কারণ
  3. ট্রেডিং ফ্রিকোয়েন্সি উচ্চ হতে পারে, যার ফলে গোপন ট্রেডিং খরচ হতে পারে
  4. পারফরম্যান্স পণ্য নির্বাচন এবং পরামিতি মিটিং উপর নির্ভর করে

ঝুঁকি হ্রাস করার জন্য, নিম্নলিখিত দিকগুলি বিবেচনা করা যেতে পারেঃ

  1. নির্ভরযোগ্য পিভট পয়েন্ট গণনা নিশ্চিত করার জন্য বাম এবং ডান বার সংখ্যা অপ্টিমাইজ
  2. অতিরিক্ত টাইটনেস এড়ানোর জন্য স্টপ লসকে কিছুটা হ্রাস করুন
  3. ঘন ঘন রুট ট্রেডিং কমাতে ন্যূনতম মুনাফা লক্ষ্য নির্ধারণ করুন
  4. সর্বোত্তম কনফিগারেশন খুঁজে পেতে বিভিন্ন পণ্য এবং পরামিতি উপর পরীক্ষা

অপ্টিমাইজেশান নির্দেশাবলী

এই কৌশল আরও উন্নত করার সুযোগ রয়েছেঃ

  1. পিভট অগ্রগতির নির্ভরযোগ্যতা মূল্যায়নের জন্য অন্যান্য সূচক অন্তর্ভুক্ত করুন
  2. দামের প্রবণতা নির্ধারণের জন্য মেশিন লার্নিং মডেল যুক্ত করুন
  3. সিগন্যাল সংবেদনশীলতা উন্নত করতে উচ্চ-ফ্রিকোয়েন্সি ডেটা ব্যবহার করুন
  4. গতিশীলভাবে অবস্থান সামঞ্জস্য করার জন্য অবস্থান আকার মডিউল চালু করুন
  5. প্রকৃত ট্রেডিং খরচ গণনা করতে বিস্তারিত অ্যাকাউন্ট মডিউল সংযোগ করুন

এই অপ্টিমাইজেশানগুলি কৌশলটির জয় হার, লাভজনকতা এবং স্থিতিশীলতা উন্নত করতে পারে।

সিদ্ধান্ত

সংক্ষেপে, এটি পিভট বিপরীত তত্ত্বের উপর ভিত্তি করে একটি পরিমাণগত ট্রেডিং কৌশল। এটি ঝুঁকি নিয়ন্ত্রণের জন্য স্টপ লস গ্রহণ করার সময় ট্রেডিং সিগন্যাল হিসাবে মূল্যের অগ্রগতি পিভট পয়েন্টগুলি ব্যবহার করে। এই কৌশলটি বাস্তবায়ন করা সহজ এবং ব্যাপকভাবে প্রয়োগযোগ্য, এটিকে একটি ব্যবহারিক পরিমাণগত ট্রেডিং কৌশল করে তোলে। তবে এটি কিছু ঝুঁকি বহন করে এবং বাস্তব ট্রেডিংয়ে সর্বোত্তম কনফিগারেশন খুঁজে পেতে আরও পরীক্ষা এবং অপ্টিমাইজেশনের প্রয়োজন।


/*backtest
start: 2022-12-05 00:00:00
end: 2023-12-11 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy('Weekly 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(1, title='Return Precision',                            group = "Weekly Table")
from_date  = input(timestamp("01 Jan 3000 00:00 +0000"), "From Date", group = "Weekhly Table")
prof_color = input.color(color.green, title = "Gradient Colors", group = "Weeky Table", inline = "colors")
loss_color = input.color(color.red,   title = "",                group = "Weeky 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(false,       title = "Display Benchmark?",               group = "Benchmark")
disp_alpha = input.bool(false,       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)


///////////////////
// WEEKLY TABLE //

new_week = weekofyear(time[1]) != weekofyear(time)
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



// Current Weekly P&L
cur_week_pnl  = 0.0
cur_week_pnl := bar_index == 0 ? 0 : 
                 time >= from_date and (time[1] < from_date or new_week) ? bar_pnl : 
                 (1 + cur_week_pnl[1]) * (1 + bar_pnl) - 1

// Current Yearly P&L
cur_year_pnl  = 0.0
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


// Current Weekly P&L - Bench
bench_cur_week_pnl  = 0.0
bench_cur_week_pnl := bar_index == 0 or (time[1] < from_date and time >= from_date) ? 0 : 
                       time >= from_date and new_week ? bench_pnl : 
                       (1 + bench_cur_week_pnl[1]) * (1 + bench_pnl) - 1 

// Current Yearly P&L - Bench
bench_cur_year_pnl  = 0.0
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 week_time = array.new_int(0)
var year_time = array.new_int(0)

var week_pnl = array.new_float(0)
var year_pnl = array.new_float(0)

var bench_week_pnl = array.new_float(0)
var bench_year_pnl = array.new_float(0)


// Filling weekly / yearly pnl arrays
if array.size(week_time) > 0
    if weekofyear(time) == weekofyear(array.get(week_time, array.size(week_time) - 1))
        array.pop(week_pnl)
        array.pop(bench_week_pnl)
        array.pop(week_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(week_time, time)
    array.push(year_time, time)
    
    array.push(week_pnl, cur_week_pnl)
    array.push(year_pnl, cur_year_pnl)
    
    array.push(bench_year_pnl, bench_cur_year_pnl)
    array.push(bench_week_pnl, bench_cur_week_pnl)


// Weekly P&L Table  

table_size = size.tiny
var weekly_table = table(na)

if array.size(year_pnl) > 0 and barstate.islastconfirmedhistory

    weekly_table := table.new(position.bottom_right, 
                 columns=56, rows=array.size(year_pnl) * 3 + 5, border_width=1)

// Fill weekly performance
    table.cell(weekly_table, 0, 0,  'Perf', 
                 bgcolor = #999999, text_size= table_size)


    for numW = 1 to 53 by 1
        table.cell(weekly_table, numW, 0,  str.tostring(numW), 
                 bgcolor= #999999, text_size= table_size)


    table.cell(weekly_table, 54, 0, ' ',    
                 bgcolor = #999999, text_size= table_size)
    table.cell(weekly_table, 55, 0, 'Year', 
                 bgcolor = #999999, text_size= table_size)

    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(week_pnl)), math.abs(array.min(week_pnl)))

    
    for yi = 0 to array.size(year_pnl) - 1 by 1
        table.cell(weekly_table, 0,  yi + 1,
                 str.tostring(year(array.get(year_time, yi))), 
                 bgcolor=#cccccc, text_size=table_size)
                 
        table.cell(weekly_table, 53, yi + 1, ' ',   
                 bgcolor=#999999, text_size=table_size)
                 
        table.cell(weekly_table, 54, yi + 1, ' ',   
                 bgcolor=#999999, text_size=table_size)

        y_color = color.from_gradient(array.get(year_pnl, yi), -max_abs_y, max_abs_y, loss_color, prof_color) 

        table.cell(weekly_table, 55, yi + 1, 
                 str.tostring(math.round(array.get(year_pnl, yi) * 100, prec)), 
                 bgcolor=y_color, text_size=table_size)
    
    int iw_row= na
    int iw_col= na

    for wi = 0 to array.size(week_time) - 2 by 1
        w_row   = year(array.get(week_time, wi)) - year(array.get(year_time, 0)) + 1
        w_col   = weekofyear(array.get(week_time, wi))

        w_color = color.from_gradient(array.get(week_pnl, wi), -max_abs_m, max_abs_m, loss_color, prof_color)
        
        if iw_row + 1 == w_row and iw_col + 1 == w_col
            table.cell(weekly_table, w_col, w_row-1,
                 str.tostring(math.round(array.get(week_pnl, wi) * 100, prec)), 
                 bgcolor=w_color, text_size=table_size)
        else
            table.cell(weekly_table, w_col, w_row,
                 str.tostring(math.round(array.get(week_pnl, wi) * 100, prec)), 
                 bgcolor=w_color, text_size=table_size)
        
        
        iw_row:= w_row
        iw_col:= w_col


    // Fill benchmark performance
    next_row =  array.size(year_pnl) + 1  

    if (disp_bench)
    
        table.cell(weekly_table, 0,  next_row, 'Bench', 
                 bgcolor=#999999, text_size=table_size)
        
        for numW = 1 to 53 by 1
            table.cell(weekly_table, numW, next_row,  str.tostring(numW), 
                 bgcolor= #999999, text_size= table_size)

        table.cell(weekly_table, 54, next_row, ' '   ,   
                 bgcolor = #999999, text_size=table_size)
        table.cell(weekly_table, 55, next_row, 'Year',   
                 bgcolor = #999999, text_size=table_size)
    
        max_bench_abs_y = math.max(math.abs(array.max(bench_year_pnl)), math.abs(array.min(bench_year_pnl)))
        max_bench_abs_w = math.max(math.abs(array.max(bench_week_pnl)), math.abs(array.min(bench_week_pnl)))
    
        for yi = 0 to array.size(year_time) - 1 by 1
            table.cell(weekly_table, 0,  yi + 1 + next_row + 1, 
                 str.tostring(year(array.get(year_time, yi))), 
                 bgcolor=#cccccc, text_size=table_size)

            table.cell(weekly_table, 53, yi + 1 + next_row + 1, ' ',   
                 bgcolor=#999999, text_size=table_size)
            
            table.cell(weekly_table, 54, yi + 1 + next_row + 1, ' ', 
                 bgcolor=#999999, text_size=table_size)
                 
            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(weekly_table, 55, yi + 1 + next_row + 1, 
                 str.tostring(math.round(array.get(bench_year_pnl, yi) * 100, prec)), 
                 bgcolor=y_color, text_size=table_size)
     
    
        int iw_row1= na
        int iw_col1= na

        for wi = 0 to array.size(week_time) - 1 by 1
            w_row   = year(array.get(week_time, wi)) - year(array.get(year_time, 0)) + 1
            w_col   = weekofyear(array.get(week_time, wi))
        
            w_color = color.from_gradient(array.get(bench_week_pnl, wi), -max_bench_abs_w, max_bench_abs_w, loss_color, prof_color)
    
            if iw_row1 + 1 == w_row and iw_col1 + 1 == w_col
                table.cell(weekly_table, w_col, w_row  + next_row    , 
                 str.tostring(math.round(array.get(bench_week_pnl, wi) * 100, prec)),
                 bgcolor=w_color, text_size=table_size)
            else
                table.cell(weekly_table, w_col, w_row  + next_row + 1, 
                 str.tostring(math.round(array.get(bench_week_pnl, wi) * 100, prec)), 
                 bgcolor=w_color, text_size=table_size)
                
            iw_row1:= w_row
            iw_col1:= w_col
    
    
// Fill Alpha
    if (disp_alpha)
    
        // columns
        next_row :=  array.size(year_pnl) * 2 + 3   
        table.cell(weekly_table, 0,  next_row, 'Alpha', 
                 bgcolor=#999999, text_size= table_size)


        for numW = 1 to 53 by 1
            table.cell(weekly_table, numW, next_row,  str.tostring(numW), 
                 bgcolor= #999999, text_size= table_size)


        table.cell(weekly_table, 54, next_row, ' '   ,  
                 bgcolor=#999999, text_size= table_size)
        table.cell(weekly_table, 55, next_row, 'Year',  
                 bgcolor=#999999, text_size= table_size)
        
        
        
        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_w = 0.0
        for wi = 0 to array.size(week_pnl) - 1 by 1
            if (math.abs(array.get(week_pnl, wi) - array.get(bench_week_pnl, wi)) > max_alpha_abs_w)
                max_alpha_abs_w := math.abs(array.get(week_pnl, wi) - array.get(bench_week_pnl, wi))
    
    
        for yi = 0 to array.size(year_time) - 1 by 1
            table.cell(weekly_table, 0,  yi + 1 + next_row + 1, 
                 str.tostring(year(array.get(year_time, yi))), 
                 bgcolor=#cccccc, text_size= table_size)
                 
            table.cell(weekly_table, 53, yi + 1 + next_row + 1, ' ',   
                 bgcolor=#999999, text_size= table_size)
                 
            table.cell(weekly_table, 54, yi + 1 + next_row + 1, ' ',   
                 bgcolor=#999999, text_size= table_size)

            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(weekly_table, 55, 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, text_size= table_size)
     
     
        int iw_row2= na
        int iw_col2= na
        
        for wi = 0 to array.size(week_time) - 1 by 1
            w_row   = year(array.get(week_time, wi)) - year(array.get(year_time, 0)) + 1
            w_col   = weekofyear(array.get(week_time, wi))
            w_color = color.from_gradient(array.get(week_pnl, wi) - array.get(bench_week_pnl, wi), -max_alpha_abs_w, max_alpha_abs_w, loss_color, prof_color)
    
            if iw_row2 + 1 == w_row and iw_col2 + 1 == w_col
                table.cell(weekly_table, w_col, w_row  + next_row , 
                     str.tostring(math.round((array.get(week_pnl, wi) - array.get(bench_week_pnl, wi)) * 100, prec)), 
                     bgcolor=w_color, text_size= table_size)
            else
                table.cell(weekly_table, w_col, w_row  + next_row + 1 , 
                     str.tostring(math.round((array.get(week_pnl, wi) - array.get(bench_week_pnl, wi)) * 100, prec)), 
                     bgcolor=w_color, text_size= table_size)
        
            iw_row2:= w_row
            iw_col2:= w_col


আরো