
এই কৌশলটির মূল ধারণা হল একটি ক্যালম্যান ফিল্টার এবং ট্র্যাকিং স্টপকে একত্রিত করে একটি গতিশীল সমন্বয়যুক্ত স্টপ ট্র্যাক তৈরি করা। ক্যালম্যান ফিল্টারটি মূল্য অনুসরণ করতে ব্যবহৃত হয় এবং দামের পূর্বাভাস দেওয়া হয়। স্টপ ট্র্যাকটি গতিশীল ট্র্যাকিং মূল্যের জন্য নির্দিষ্ট শতাংশের উপর ভিত্তি করে নির্মিত হয়। এইভাবে, একটি উত্তেজনাপূর্ণ চলমান পর্যায়ে ইতালিয়ান মুনাফা অর্জন করা যায়, যখন একটি বিপরীতমুখী সময়ে সময়মতো ক্ষতি বন্ধ করা যায়।
পুরো কৌশলটি ট্রেন্ডিং মার্কেটে ভাল কাজ করতে পারে।
এই কৌশলটি মূলত নিম্নলিখিত অংশগুলি নিয়ে গঠিতঃ
কালমান ফিল্টার
কক্ষপথের ক্ষতি
পুনর্নির্মাণ এবং বন্ধ
পুরো কৌশলটির প্রধান কার্যক্রম নিম্নরূপঃ
এই কৌশলটির প্রধান সুবিধাগুলি হলঃ
এই কৌশলটির প্রধান ঝুঁকিগুলো হলঃ
নিম্নলিখিত উপায়ে অপ্টিমাইজ করা যায়ঃ
এই কৌশলটি নিম্নলিখিত দিকগুলি থেকেও উন্নত করা যেতে পারেঃ
সামগ্রিকভাবে, এই অভিযোজিত ক্ষতির কক্ষপথ কৌশলটি কারম্যান পূর্বাভাস এবং গতিশীল ক্ষতির সাথে একত্রিত করে একটি অনন্য ধারণা তৈরি করে। উপযুক্ত প্যারামিটার সমন্বয় করা হলে, ভাল ফলাফল পাওয়া যায়। আরও মডিউল ডিজাইন এবং অপ্টিমাইজেশনের মাধ্যমে, এই কৌশলটি আরও উন্নত এবং আরও বাজারে প্রয়োগ করা যেতে পারে।
/*backtest
start: 2023-06-01 00:00:00
end: 2024-01-01 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © BigCoinHunter
// ____ _ _____ _ _ _ _
// | _ \(_) / ____| (_) | | | | | |
// | |_) |_ __ _| | ___ _ _ __ | |__| |_ _ _ __ | |_ ___ _ __
// | _ <| |/ _` | | / _ \| | '_ \| __ | | | | '_ \| __/ _ \ '__|
// | |_) | | (_| | |___| (_) | | | | | | | | |_| | | | | || __/ |
// |____/|_|\__, |\_____\___/|_|_| |_|_| |_|\__,_|_| |_|\__\___|_|
// __/ |
// |___/
//@version=5
strategy(title='Loft Strategy V4', overlay=true,
pyramiding=0, default_qty_type=strategy.cash,
default_qty_value=100, initial_capital=10000,
currency=currency.USD, commission_value=0.05,
commission_type=strategy.commission.percent,
process_orders_on_close=true)
//-------------- fetch user inputs ------------------
gain = input.float(title="Kalman Gain:", defval=100.0, minval=1, maxval=10000.0, step=1)
src = input(defval=close, title='Source:')
stopPercentBase = input.float(title='Beginning Approach(%)', defval=5.0, minval=0.1, maxval=30.0, step=0.1)
stopPercentMin = input.float(title='Final Approach(%)', defval=1.0, minval=0.1, maxval=30.0, step=0.1)
downStep = input.float(title='Approach Decrease Step', defval=0.001, minval=0.0, maxval = 5, step=0.001)
//stopPercentDeviation = input.float(title="Approach Deviation", defval=1.0, minval=0.1, maxval = 5.0, step=0.1)
baseOrderQty = input.float(title="Base Order Quantity", defval=100.0, minval=0.001)
maxOrderCount = input.int(title="Max Safe Order Attemp", defval=4, minval=1)
priceDeviation = input.float(title="Safe Order Deviation", defval=3, minval=1.0, step=0.1)
profitDeviation = input.float(title="Profit Deviation", defval=1.0, minval=1.0, maxval=10, step=0.1)
maxTakeProfit = input.float(title="Max Take Profit(%)", defval=25.0, maxval=100, step=0.1)
maxOrderQty = input.float(title="Max Order Quantity", defval=1.0, minval=0.01)
baseTP1 = input.float(title="TP1(%)", defval=1.0, minval=0.0, maxval=100.0, step=0.1, inline="0")
qt1 = input.int(title="QT1(%):", defval=40, minval=1, maxval=100, step=5, inline="0")
baseTP2 = input.float(title="TP2(%)", defval=3.0, minval=0.0, maxval=100.0, step=0.1, inline="1")
qt2 = input.int(title="QT2(%):", defval=30, minval=1, maxval=100, step=5, inline="1")
baseTP3 = input.float(title="TP3(%)", defval=5.0, minval=0.0, maxval=100.0, step=0.1, inline="2")
qt3 = input.int(title="QT3(%):", defval=30, minval=1, maxval=100, step=5, inline="2")
initialStopLoss = input.float(title="Stop Loss(%)", defval=0.0, minval=0.0, maxval=100.0, step=0.1)
longEntry = input.bool(defval=true, title= 'Long Entry', inline="3")
shortEntry = input.bool(defval=true, title='Short Entry', inline="3")
useSafeStop2 = input.bool(defval = true, title="Safe Stop After TP2", inline="6")
useSafeStop1 = input.bool(defval = false, title="Safe Stop After TP1", inline="6")
//---------- backtest range setup ------------
fromDay = input.int(defval = 1, title = "From Date:", minval = 1, maxval = 31, inline="4")
fromMonth = input.int(defval = 1, title = "/", minval = 1, maxval = 12, inline="4")
fromYear = input.int(defval = 2021, title = "/", minval = 2010, inline="4")
toDay = input.int(defval = 30, title = "To__ Date:", minval = 1, maxval = 31, inline="5")
toMonth = input.int(defval = 12, title = "/", minval = 1, maxval = 12, inline="5")
toYear = input.int(defval = 2022, title = "/", minval = 2010, inline="5")
//------------ time interval setup -----------
start = timestamp(fromYear, fromMonth, fromDay, 00, 00) // backtest start window
finish = timestamp(toYear, toMonth, toDay, 23, 59) // backtest finish window
window() => true // create function "within window of time"
//------- define the order comments ------
enterLongComment = ""
exitLongComment = ""
enterShortComment = ""
exitShortComment = ""
longTPSL = ""
longTP = ""
longSL = ""
shortTPSL = ""
shortTP = ""
shortSL = ""
//--------- Define global variables -----------
var bool long = true
var bool stoppedOutLong = false
var bool stoppedOutShort = false
var float kf = 0.0
var float velo = 0.0
var float orderQty = baseOrderQty
var float stopLoss = initialStopLoss
var bool isProfit = false
var int barindex = 1
var int winCounter = 0
var int winCounterBuffer = 0
var int failCounter = 0
var float tp1 = baseTP1
var float tp2 = baseTP2
var float tp3 = baseTP3
var bool isTakeTP1 = false
var bool isTakeTP2 = false
var bool isTakeTP3 = false
var bool isLastProfit = true
var float stopPercentMax = stopPercentBase
var float stopPercent = stopPercentBase
var float stopLine = 0.0
var labelColor = color.blue
//------ kalman filter calculation --------
dk = src - nz(kf[1], src)
smooth = nz(kf[1], src) + dk * math.sqrt(gain / 10000 * 2)
velo := nz(velo[1], 0) + gain / 10000 * dk
kf := smooth + velo
//--------- calculate the loft stopLoss line ---------
//stopPercentMax := isLastProfit ? stopPercentBase : (stopPercentBase * stopPercentDeviation)
if long == true
stopLine := kf - (kf * (stopPercent / 100))
if long[1] == true and stopLine <= stopLine[1]
stopLine := stopLine[1]
else if (long[1] == true)
stopPercent := stopPercent - downStep
if(stopPercent < stopPercentMin)
stopPercent := stopPercentMin
if(kf < stopLine)
long := false
stopPercent := stopPercentMax
stopLine := kf + (kf * (stopPercent / 100))
else
stopLine := kf + (kf * (stopPercent / 100))
if long[1] == false and stopLine >= stopLine[1]
stopLine := stopLine[1]
else if(long[1] == false)
stopPercent := stopPercent - downStep
if(stopPercent < stopPercentMin)
stopPercent := stopPercentMin
if(kf > stopLine)
long := true
stopPercent := stopPercentMax
stopLine := kf - (kf * (stopPercent / 100))
//------------------- determine buy and sell points ---------------------
buySignall = window() and long and (not stoppedOutLong)
sellSignall = window() and (not long) and (not stoppedOutShort)
if longEntry and shortEntry
if buySignall and baseTP1 <= 0.0
if strategy.position_size < 0
if close < strategy.position_avg_price
isLastProfit := true
else if strategy.position_size == 0
if strategy.wintrades > winCounter //strategy.wintrades[ barindex ]
isLastProfit := true
else
isLastProfit := false
else if sellSignall and baseTP1 <= 0.0
if strategy.position_size > 0
if close > strategy.position_avg_price
isLastProfit := true
else if strategy.position_size == 0
if strategy.wintrades > winCounter //strategy.wintrades[ barindex ]
isLastProfit := true
else
isLastProfit := false
else if isTakeTP2 == true
isLastProfit := true
else
isLastProfit := false
else if longEntry
if sellSignall
winCounterBuffer := winCounter
if buySignall
if winCounter > winCounterBuffer
isLastProfit := true
else
isLastProfit := false
else if shortEntry
if buySignall
winCounterBuffer := winCounter
if sellSignall
if winCounter > winCounterBuffer
isLastProfit := true
else
isLastProfit := false
//------------- set the deviations ------------
var float maxOrderSize = (baseOrderQty * math.pow(priceDeviation, maxOrderCount - 1))
if buySignall or sellSignall
if isLastProfit == false
orderQty := orderQty * priceDeviation
tp1 := tp1 * profitDeviation
tp2 := tp2 * profitDeviation
tp3 := tp3 * profitDeviation
tp1 := math.min(tp1, maxTakeProfit)
tp2 := math.min(tp2, maxTakeProfit)
tp3 := math.min(tp3, maxTakeProfit)
if orderQty > maxOrderSize
failCounter := failCounter + 1
orderQty := baseOrderQty
tp1 := baseTP1
tp2 := baseTP2
tp3 := baseTP3
else
orderQty := baseOrderQty
tp1 := baseTP1
tp2 := baseTP2
tp3 := baseTP3
// ----------------- put debug labels -------------------
if orderQty == maxOrderSize
labelColor := color.red
else
labelColor := isLastProfit ? color.lime : color.yellow
if longEntry and shortEntry
if buySignall or sellSignall
label.new( x=bar_index, y=high, text="Qty:"+str.tostring(math.min(orderQty, maxOrderQty))+" | Worst Case:"+str.tostring(failCounter) ,color = labelColor )
else if longEntry
if buySignall
label.new( x=bar_index, y=high, text="Qty:"+str.tostring(math.min(orderQty, maxOrderQty))+" | Worst Case:"+str.tostring(failCounter) ,color = labelColor )
else if shortEntry
if sellSignall
label.new( x=bar_index, y=high, text="Qty:"+str.tostring(math.min(orderQty, maxOrderQty))+" | Worst Case:"+str.tostring(failCounter) ,color = labelColor )
//---------- execute the strategy -----------------
nz(orderQty, baseOrderQty)
if longEntry and shortEntry
if long
strategy.close_all( when = buySignall, comment = exitShortComment)
strategy.entry("LONG", strategy.long, when = buySignall, qty=math.min(orderQty, maxOrderQty), comment = enterLongComment)
stoppedOutLong := true
stoppedOutShort := false
else
strategy.close_all(when=sellSignall, comment = exitLongComment)
strategy.entry("SHORT", strategy.short, when = sellSignall, qty=math.min(orderQty, maxOrderQty), comment = enterShortComment)
stoppedOutLong := false
stoppedOutShort := true
else if(longEntry)
strategy.entry("LONG", strategy.long, when = buySignall, qty=math.min(orderQty, maxOrderQty), comment = enterLongComment)
strategy.close("LONG", when = sellSignall, comment = exitLongComment)
if long
stoppedOutLong := true
stoppedOutShort := false
else
stoppedOutLong := false
stoppedOutShort := true
else if(shortEntry)
strategy.entry("SHORT", strategy.short, when = sellSignall, qty=math.min(orderQty, maxOrderQty), comment = enterShortComment)
strategy.close("SHORT", when = buySignall, comment = exitShortComment)
if not long
stoppedOutShort := true
stoppedOutLong := false
else
stoppedOutShort := false
stoppedOutLong := true
//--------- calculate the TP/SL entries -----------
longProfitPrice1 = strategy.position_avg_price * (1 + tp1 * 0.01)
longProfitPrice2 = strategy.position_avg_price * (1 + tp2 * 0.01)
longProfitPrice3 = strategy.position_avg_price * (1 + tp3 * 0.01)
shortProfitPrice1 = strategy.position_avg_price * (1 - tp1 * 0.01)
shortProfitPrice2 = strategy.position_avg_price * (1 - tp2 * 0.01)
shortProfitPrice3 = strategy.position_avg_price * (1 - tp3 * 0.01)
longStopPrice = strategy.position_avg_price * (1 - stopLoss * 0.01)
shortStopPrice = strategy.position_avg_price * (1 + stopLoss * 0.01)
shortSafeStopPrice2 = strategy.position_avg_price * (1 - 0.2 * 0.01)
longSafeStopPrice2 = strategy.position_avg_price * (1 + 0.2 * 0.01)
longSafeStopPrice1 = stopLine
shortSafeStopPrice1 = stopLine
//----------- calculate TP quantity values -----------
takeQty1 = math.min(orderQty, maxOrderQty) * qt1 / 100
takeQty2 = math.min(orderQty, maxOrderQty) * qt2 / 100
takeQty3 = math.min(orderQty, maxOrderQty) * qt3 / 100
//----------------- take profit and stop loss processes -----------------
if strategy.position_size > 0
if close > longProfitPrice1 and tp1 > 0 and isTakeTP1 == false
strategy.close(id="LONG", qty=takeQty1, comment = "longTP 1")
isTakeTP1 := true
if close > longProfitPrice2 and tp2 > 0 and isTakeTP2 == false
strategy.close(id="LONG", qty=takeQty2, comment = "longTP 2")
isTakeTP2 := true
if close > longProfitPrice3 and tp3 > 0 and isTakeTP3 == false
strategy.close(id="LONG", qty=takeQty3, comment = "longTP 3")
isTakeTP3 := true
if isTakeTP2 == true and useSafeStop2
strategy.exit(id="LONG", stop=longSafeStopPrice2, comment = "Long Safe Stop2")
if isTakeTP1 == true and useSafeStop1
strategy.exit(id="LONG", stop=longSafeStopPrice1, comment = "Long Safe Stop1")
if strategy.position_size < 0
if close < shortProfitPrice1 and tp1 > 0 and isTakeTP1 == false
strategy.close(id="SHORT", qty=takeQty1, comment = "Short TP 1")
isTakeTP1 := true
if close < shortProfitPrice2 and tp2 > 0 and isTakeTP2 == false
strategy.close(id="SHORT", qty=takeQty2, comment = "Short TP 2")
isTakeTP2 := true
if close < shortProfitPrice3 and tp3 > 0 and isTakeTP3 == false
strategy.close(id="SHORT", qty=takeQty3, comment = "Short TP 3")
isTakeTP3 := true
if isTakeTP2 == true and useSafeStop2
strategy.exit(id="SHORT", stop=shortSafeStopPrice2, comment = "Short Safe Stop2")
if isTakeTP1 == true and useSafeStop1
strategy.exit(id="SHORT", stop=shortSafeStopPrice1, comment = "Short Safe Stop1")
if(initialStopLoss>0.0)
if ( strategy.position_size > 0 )
strategy.exit(id="LONG", stop=longStopPrice, comment = "Long Stop Loss")
else if ( strategy.position_size < 0 )
strategy.exit(id="SHORT", stop=shortStopPrice, comment = "Short Stop Loss")
if buySignall or sellSignall
isTakeTP1 := false
isTakeTP2 := false
isTakeTP3 := false
// winCounter := strategy.wintrades
//------------- plot charts ---------------------
lineColor1 = long ? color.green : color.red
lineColor2 = long ? color.aqua : color.fuchsia
kalmanPlot = plot(kf, color=lineColor1, linewidth=3, title = "Kalman Filter")
stopPlot = plot(stopLine, color=lineColor2, linewidth=2, title = "Stop Loss Line")