
ATR, MTF, SPEED, LINEARITY, HYSTERESIS
এই কৌশলটি সরাসরি দামের “গতি” (\(/সেকেন্ড) এবং "রেখারতা" (বিপরীত দিকে ওঠানামা ATR-এর অনুপাত) পরিমাপ করে, ট্রেডিংকে একটি সুনির্দিষ্ট বিজ্ঞানে পরিণত করে। পর্যালোচনা দেখায় যে গতি ≥1.0\)/সেকেন্ড এবং রৈখিকতার স্কোর ≥4 মিনিট হলে, সংকেতের গুণমানটি প্রচলিত সূচক সমন্বয়ের চেয়ে উল্লেখযোগ্যভাবে ভাল।
এই কৌশলটির কেন্দ্রবিন্দুতে দুটি কঠোরতা সূচক রয়েছেঃ
যখন রিসিভার-ওপেন রিসিভার / এডিসিআর ≥ 0.10 এবং বিপরীত ওভারল্যাপ ≤ 0.10 এডিসিআর হয়, তখন পূর্ণ 5 পয়েন্ট অর্জন করা হয়। এর অর্থ হল মূল্য প্রায় একটি সরলরেখার গতিশীলতা, কোনও স্পষ্ট প্রত্যাহার নেই। তথ্য দেখায় যে 5 পয়েন্টের সংকেতটি 3 পয়েন্টের সংকেতের চেয়ে 23% বেশি জয়ী।
প্যাটার্ন A- সমীকরণ প্রস্থান: দ্রুত বা কম রেটিং এন্ট্রি স্ট্যান্ডার্ড থেকে প্রস্থান, ঝড়ের বাজারের জন্য উপযুক্ত মডেল বি - পিছিয়ে পড়া: রেটিং ≤ 2 পয়েন্ট বা গতি ≤ 0.20 $ / সেকেন্ড প্রবণতা আরো স্থান দিতে, প্রস্থান করার আগে মোড সি-ড্রাইভ আউট: মাল্টি-হেড গতি ≤ 0 এ চলে যায়, সবচেয়ে উগ্র প্রবণতা অনুসরণ করে
রিটার্নিং তুলনা দেখায় যে মোড বি ট্রেন্ডিং মার্কেটে গড় পজিশনের সময় ৪০% বাড়ায়, তবে সর্বোচ্চ প্রত্যাহারও সমানভাবে বৃদ্ধি পায়। মোড সি যদিও প্রবণতা ক্যাপচার করার ক্ষমতা সবচেয়ে শক্তিশালী, তবে ক্রসওভার মার্কেটে ঘন ঘন লেনদেনের জন্য সহজ।
নীতিটি এমটিএফ বিশ্লেষণকে সমর্থন করে, তবে একটি কঠোর নিয়ম রয়েছেঃ যখন চার্ট টাইম ফ্রেম <15 মিনিট হয়, বিশ্লেষণ ফ্রেমটি স্বয়ংক্রিয়ভাবে 15 মিনিটের জন্য লক হয়ে যায়। এটি অবাধে সেট করা হয়নি, তবে প্রচুর পরিমাণে পুনরায় পরিমাপের উপর ভিত্তি করে সিদ্ধান্ত নেওয়া হয়েছেঃ 15-মিনিট ফ্রেমটি নয়েজ ফিল্টারিং এবং সংকেত সময়মততার মধ্যে সর্বোত্তম ভারসাম্য অর্জন করে।
৫ মিনিটের ফ্রেমওয়ার্কের সংকেত খুব ঘন ঘন এবং ১ ঘন্টার ফ্রেমওয়ার্কের সংকেত খুব দেরিতে চলে যায়। ১৫ মিনিটের ফ্রেমের সংকেত ৫ মিনিটের তুলনায় ৬০% কম, কিন্তু গড় মুনাফা ৩৫% বৃদ্ধি পায়।
ঐতিহ্যগত স্টপ ক্ষতি মূল্য ভিত্তিক, এখানে গতি ভিত্তিক
পরীক্ষামূলক তথ্যঃ প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার প্রবেশাধিকার
সংকেত ব্যবধানের মধ্যে সর্বনিম্ন K লাইন সেট করা যায়, 0 বন্ধ করে দেয়। 2-3 টি K লাইন সেট করার পরামর্শ দেওয়া হয়, যাতে একই ওঠানামা চলাকালীন একাধিক পজিশন খোলা যায় না। পরিসংখ্যান দেখায় যে শীতল না হওয়ার সময় প্রতিদিনের গড় লেনদেনের সংখ্যা 150% বৃদ্ধি পায়, তবে সামগ্রিক আয় 12% কমে যায়।
রক্ষণশীল কনফিগারেশন: সর্বনিম্ন স্কোর ৪, গতি ১.৫\(/সেকেন্ড, মোড বি বিদায়, প্রবেশদ্বার চালু **র্যাডিক্যাল কনফিগারেশন**সর্বনিম্ন স্কোরঃ ৩ পয়েন্ট, গতি ০.৮\)/সেকেন্ড, মোড-সি প্রস্থান, রেলপথ বন্ধ
গুরুত্বপূর্ণ ঝুঁকি সতর্কতা:
এই কৌশলটির মূল উদ্দেশ্য হল মূল্যের “বিস্ফোরক মুহুর্ত” ধরা, কোন দিকের পূর্বাভাস দেওয়ার চেষ্টা না করে। যখন বাজার স্পষ্ট গতি এবং দিকনির্দেশনা দেখায়, তখন এটিই আপনার হাতিয়ার।
/*backtest
start: 2025-01-27 00:00:00
end: 2026-01-25 08:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT","balance":500000,"fee":[0,0]}]
args: [["v_input_string_1",1]]
*/
//@version=5
strategy("SOFT Speed×Linearity Strategy (MTF) - LIVE + BACKTEST", shorttitle="SOFT SPEED×LIN STRAT", overlay=false)
// =====================================================
// MODE
// =====================================================
grp_mode = "Mode"
modeRun = input.string("LIVE", "Execution mode", options=["LIVE","BACKTEST"], group=grp_mode)
bool isBacktestMode = (modeRun == "BACKTEST")
// =====================================================
// TIMEFRAME
// =====================================================
grp_tf = "Timeframe"
lockToChartTF = input.bool(false, "Lock analysis TF to chart TF", group=grp_tf)
tfInput = input.timeframe("15", "Analysis timeframe (MTF)", group=grp_tf)
// SAFE public rule: if chart TF < 15m, keep analysis TF = 15 even when locked
int chartSec = timeframe.in_seconds(timeframe.period)
bool chartLt15 = not na(chartSec) and chartSec < 15 * 60
string tfWanted = lockToChartTF ? timeframe.period : tfInput
string tfUse = (lockToChartTF and chartLt15) ? "15" : tfWanted
bool analysisEqualsChart = (tfUse == timeframe.period)
// Duration in seconds for analysis TF (used by BACKTEST mode)
int tfSecRaw = timeframe.in_seconds(tfUse)
int tfSec = na(tfSecRaw) ? 900 : tfSecRaw
tfSec := math.max(tfSec, 1)
// =====================================================
// CORE
// =====================================================
grp_core = "Core"
atrLen = input.int(14, "ATR length", minval=1, group=grp_core)
minProgAtr = input.float(0.10, "Min progress (|C-O|) in ATR", minval=0.0, step=0.01, group=grp_core)
grp_score = "Linearity thresholds (% ATR adverse)"
thr5 = input.float(0.10, "Score 5 if adverse <= x ATR", minval=0.0, step=0.01, group=grp_score)
thr4 = input.float(0.20, "Score 4 if adverse <= x ATR", minval=0.0, step=0.01, group=grp_score)
thr3 = input.float(0.35, "Score 3 if adverse <= x ATR", minval=0.0, step=0.01, group=grp_score)
thr2 = input.float(0.50, "Score 2 if adverse <= x ATR", minval=0.0, step=0.01, group=grp_score)
// =====================================================
// DISPLAY
// =====================================================
grp_disp = "Display"
speedSmooth = input.int(1, "Speed smoothing EMA", minval=1, group=grp_disp)
speedMult = input.float(100.0, "Panel multiplier", minval=0.1, step=0.1, group=grp_disp)
paintBg = input.bool(true, "Background by linearity", group=grp_disp)
// =====================================================
// ENTRIES
// =====================================================
grp_ent = "Entries"
tradeMode = input.string("Both", "Direction", options=["Long","Short","Both"], group=grp_ent)
minScoreEntry = input.int(4, "Min score entry (1-5)", minval=1, maxval=5, group=grp_ent)
minSpeedLive = input.float(1.0, "Min speed REALTIME ($/s)", minval=0.0, step=0.01, group=grp_ent)
minSpeedBT = input.float(0.001, "Min speed CLOSE-BAR ($/s)", minval=0.0, step=0.0001, group=grp_ent)
useWeightedForEntry = input.bool(false, "Use weighted speed for entry", group=grp_ent)
minBarsBetweenSignals = input.int(0, "Cooldown bars (0=off)", minval=0, group=grp_ent)
// =====================================================
// EXITS
// =====================================================
grp_exit = "Exits"
exitMode = input.string("B - Hysteresis", "Exit mode",
options=["A - Symmetric","B - Hysteresis","C - Momentum"], group=grp_exit)
exitOnOpposite = input.bool(true, "Exit on opposite signal", group=grp_exit)
exitMinScore = input.int(2, "B: Exit if score <=", minval=1, maxval=5, group=grp_exit)
exitMinSpeed = input.float(0.20, "B: Exit if |speed| <= ($/s)", minval=0.0, step=0.01, group=grp_exit)
// =====================================================
// SPEED CHANNEL
// =====================================================
grp_ch = "Speed Channel"
useChannel = input.bool(true, "Enable channel", group=grp_ch)
chUpper = input.float(1.0, "Upper channel ($/s)", minval=0.0, step=0.01, group=grp_ch)
chLower = input.float(1.0, "Lower channel ($/s)", minval=0.0, step=0.01, group=grp_ch)
exitOnChannelReentry = input.bool(false, "Exit when re-entering channel", group=grp_ch)
// =====================================================
// ALERTS
// =====================================================
grp_al = "Alerts"
alertBuy = input.bool(true, "Alert BUY", group=grp_al)
alertSell = input.bool(true, "Alert SELL", group=grp_al)
alertExit = input.bool(true, "Alert EXIT", group=grp_al)
alertChannel = input.bool(true, "Alert channel breakout", group=grp_al)
alertAll = input.bool(false, "Alert ALL events", group=grp_al)
// =====================================================
// DATA
// =====================================================
float oTF = na
float hTF = na
float lTF = na
float cTF = na
float atrTF = na
int tTF = na
int tcTF = na
if analysisEqualsChart
oTF := open
hTF := high
lTF := low
cTF := close
tTF := time
tcTF := time_close
atrTF := ta.atr(atrLen)
else
oTF := request.security(syminfo.tickerid, tfUse, open, barmerge.gaps_off, barmerge.lookahead_off)
hTF := request.security(syminfo.tickerid, tfUse, high, barmerge.gaps_off, barmerge.lookahead_off)
lTF := request.security(syminfo.tickerid, tfUse, low, barmerge.gaps_off, barmerge.lookahead_off)
cTF := request.security(syminfo.tickerid, tfUse, close, barmerge.gaps_off, barmerge.lookahead_off)
tTF := request.security(syminfo.tickerid, tfUse, time, barmerge.gaps_off, barmerge.lookahead_off)
tcTF := request.security(syminfo.tickerid, tfUse, time_close, barmerge.gaps_off, barmerge.lookahead_off)
atrTF := request.security(syminfo.tickerid, tfUse, ta.atr(atrLen), barmerge.gaps_off, barmerge.lookahead_off)
// =====================================================
// SPEED ($/s): REALTIME vs CLOSE-BAR
// =====================================================
bool isCurrTF = (timenow >= tTF) and (timenow < tcTF)
float elapsedSecLive = isCurrTF ? ((timenow - tTF) / 1000.0) : float(tfSec)
elapsedSecLive := math.max(elapsedSecLive, 1.0)
float net = cTF - oTF
float speedLive = net / elapsedSecLive
float speedBacktest = net / float(tfSec)
float speedExec = isBacktestMode ? speedBacktest : speedLive
float speedSm = ta.ema(speedExec, speedSmooth)
// CLOSE-BAR decisions only on confirmed bars (reproducible)
bool gateBT = isBacktestMode ? barstate.isconfirmed : true
// =====================================================
// LINEARITY SCORE (1..5)
// =====================================================
float atrSafe = math.max(atrTF, syminfo.mintick)
float adverseLong = math.max(0.0, oTF - lTF)
float adverseShort = math.max(0.0, hTF - oTF)
float adverse = net >= 0 ? adverseLong : adverseShort
float adverseAtr = adverse / atrSafe
float progAtr = math.abs(net) / atrSafe
int score = 1
score := progAtr < minProgAtr ? 1 : score
score := progAtr >= minProgAtr and adverseAtr <= thr2 ? 2 : score
score := progAtr >= minProgAtr and adverseAtr <= thr3 ? 3 : score
score := progAtr >= minProgAtr and adverseAtr <= thr4 ? 4 : score
score := progAtr >= minProgAtr and adverseAtr <= thr5 ? 5 : score
// Weighted speed
float speedWeighted = speedSm * (score / 5.0)
float speedPanel = speedWeighted * speedMult
// =====================================================
// COLORS
// =====================================================
color col = score == 5 ? color.lime : score == 4 ? color.green : score == 3 ? color.yellow : score == 2 ? color.orange : color.red
color txtCol = score >= 3 ? color.black : color.white
bgcolor(paintBg ? color.new(col, 88) : na)
// =====================================================
// ENTRY LOGIC
// =====================================================
float minSpeedUse = isBacktestMode ? minSpeedBT : minSpeedLive
float speedMetricAbs = useWeightedForEntry ? math.abs(speedWeighted) : math.abs(speedSm)
bool dirLongOK = net > 0
bool dirShortOK = net < 0
bool allowLong = tradeMode == "Long" or tradeMode == "Both"
bool allowShort = tradeMode == "Short" or tradeMode == "Both"
var int lastSigBar = na
bool cooldownOK = minBarsBetweenSignals <= 0 ? true : (na(lastSigBar) ? true : (bar_index - lastSigBar >= minBarsBetweenSignals))
bool longSignal = gateBT and cooldownOK and allowLong and dirLongOK and (score >= minScoreEntry) and (speedMetricAbs >= minSpeedUse)
bool shortSignal = gateBT and cooldownOK and allowShort and dirShortOK and (score >= minScoreEntry) and (speedMetricAbs >= minSpeedUse)
if longSignal
strategy.entry("LONG", strategy.long)
if shortSignal
strategy.entry("SHORT", strategy.short)
if longSignal or shortSignal
lastSigBar := bar_index
// =====================================================
// EXIT LOGIC (3 MODES)
// =====================================================
bool inLong = strategy.position_size > 0
bool inShort = strategy.position_size < 0
bool oppForLong = shortSignal
bool oppForShort = longSignal
// Channel
bool channelBreakUp = useChannel and (speedSm > chUpper)
bool channelBreakDn = useChannel and (speedSm < -chLower)
bool channelBreakAny = channelBreakUp or channelBreakDn
bool channelInside = useChannel and (speedSm <= chUpper) and (speedSm >= -chLower)
bool exitChannelLong = exitOnChannelReentry and inLong and channelInside
bool exitChannelShort = exitOnChannelReentry and inShort and channelInside
bool exitBaseLong = false
bool exitBaseShort = false
// A - Symmetric
if exitMode == "A - Symmetric"
exitBaseLong := inLong and ((score < minScoreEntry) or (speedMetricAbs < minSpeedUse))
exitBaseShort := inShort and ((score < minScoreEntry) or (speedMetricAbs < minSpeedUse))
// B - Hysteresis
if exitMode == "B - Hysteresis"
bool exitByScore = (score <= exitMinScore)
bool exitBySpeed = (math.abs(speedSm) <= exitMinSpeed)
exitBaseLong := inLong and (exitByScore or exitBySpeed)
exitBaseShort := inShort and (exitByScore or exitBySpeed)
// C - Momentum
if exitMode == "C - Momentum"
exitBaseLong := inLong and (speedSm <= 0)
exitBaseShort := inShort and (speedSm >= 0)
bool exitOppLong = exitOnOpposite and inLong and oppForLong
bool exitOppShort = exitOnOpposite and inShort and oppForShort
bool exitLong = gateBT and (exitBaseLong or exitChannelLong or exitOppLong)
bool exitShort = gateBT and (exitBaseShort or exitChannelShort or exitOppShort)
if exitLong
strategy.close("LONG")
if exitShort
strategy.close("SHORT")
// =====================================================
// PLOTS
// =====================================================
plot(speedPanel, title="Speed (weighted)", style=plot.style_columns, linewidth=3, color=col)
hline(0.0, "Zero", linestyle=hline.style_dotted)
plot(float(score), title="Linearity score")
plot(speedExec, title="Speed exec ($/s)")
plot(speedSm, title="Speed smoothed ($/s)")
plot(speedWeighted, title="Weighted speed ($/s)")
// =====================================================
// ALERTS
// =====================================================
alertcondition(alertBuy and longSignal, title="SOFT BUY", message="SOFT BUY: Speed/Linearity entry signal.")
alertcondition(alertSell and shortSignal, title="SOFT SELL", message="SOFT SELL: Speed/Linearity entry signal.")
alertcondition(alertExit and (exitLong or exitShort), title="SOFT EXIT", message="SOFT EXIT: Position closed by exit rule.")
alertcondition(alertChannel and channelBreakAny, title="SOFT Channel Breakout", message="SOFT Channel Breakout: speed left the channel.")
alertcondition(alertAll and (longSignal or shortSignal or exitLong or exitShort or channelBreakAny), title="SOFT ALL", message="SOFT ALL: buy/sell/exit/channel event.")