
Chiến lược dao động truyền thống có vấn đề lớn nhất là có quá nhiều đột phá giả và tín hiệu nhiễu gây đau đầu. Chiến lược này giải quyết vấn đề này một cách trực tiếp: Range Oscillator + Stochastic Double Confirmation + EMA Slip Filter, và cơ chế bảo hiểm ba lần giúp mỗi lần nhập cảnh có nhiều khí hậu hơn.
Logic cốt lõi đơn giản và thô sơ: khi Range Oscillator vượt qua 100 điểm (được điều chỉnh) và đường chỉ số K ngẫu nhiên vượt qua đường D từ mức thấp lên, khi dao động giảm trở lại dưới 30 hoặc khi EMA nghiêng về tiêu cực. Đây không phải là thiết lập tham số để đánh đầu, mà là thiết kế hợp lý dựa trên cấu trúc vi mô của thị trường.
Trung tâm của chiến lược này là dao động chuẩn hóa ATR dựa trên giá lệch khỏi đường trung bình trọng số, với logic tính toán gần gũi hơn so với các chỉ số truyền thống về sự biến động thực sự của thị trường.
Làm thế nào để tính toán cụ thể? Lấy mỗi đường K so với giá thay đổi trước đó trong vòng 50 chu kỳ như một trọng lượng, tính toán trung bình di chuyển có trọng lượng, sau đó chia khoảng cách của giá hiện tại từ đường trung bình này bằng 2 lần ATR, và nhân 100 để có được giá trị dao động.Thích ứng với sự biến động của thị trường, không tạo ra quá nhiều tín hiệu giả trong thời gian biến động cao và duy trì đủ độ nhạy trong thời gian biến động thấp.
Thấp nhập được đặt ở 100 không phải là ngẫu nhiên. Dữ liệu đánh giá lại cho thấy rằng khi dao động vượt qua 100, xác suất giá tiếp tục tăng trong 5-10 chu kỳ tiếp theo là cao hơn đáng kể so với mức ngẫu nhiên. Đó là lý do tại sao chiến lược này nắm bắt cơ hội ngay từ đầu xu hướng.
Một đột phá đơn thuần của dao động có thể dễ dàng bị mắc kẹt, vì vậy thêm các chỉ số ngẫu nhiên như xác nhận động lực. Nhưng cách sử dụng ở đây không giống như trong sách giáo khoa: không phải là mua quá mức đơn giản, mà là bán quá mứcYêu cầu đường K phải giảm xuống dưới 100 (có thể điều chỉnh) và sau đó đi qua đường D để xác nhận vào。
Tại sao thiết kế như vậy? Bởi vì chúng tôi muốn chuyển động từ mức tương đối thấp, chứ không phải là theo dõi ở mức cao.
Dữ liệu cho thấy: Sau khi bổ sung Stochastic Confirmation, chiến lược này có tỷ lệ chiến thắng tăng lên khoảng 15%, và tối đa rút lui giảm xuống khoảng 20%. Đó là sức mạnh của Multi-Dimensional Confirmation.
Điều thú vị nhất là cơ chế rút lui. Ngoài việc quay trở lại giá trị trung bình của dao động xuống dưới 30, xu hướng quay trở lại tiêu cực của độ nghiêng EMA 70 chu kỳ đã rút lui.Khi EMA chuyển sang tiêu cực, nó cho thấy xu hướng trung hạn bắt đầu suy yếu, và bạn nên cân nhắc rút lui bất kể lợi nhuận hay lỗ hổng.
Thiết kế này thông minh hơn so với dừng dừng cố định: có thể giữ lâu hơn trong xu hướng mạnh và có thể rút lui kịp thời khi xu hướng yếu hơn.
Mã cung cấp các tùy chọn cho Stop Loss (cập tắt mặc định), Stop Loss là 1.5%, Stop Loss là 3.0%, RRR là 1:2.Những điều này chỉ là sự đảm bảo cuối cùng cho những người chơi có thể sử dụng chiến lược của mình.。
Tại sao tôi nói như vậy? Bởi vì thị trường là động, và một stop loss với tỷ lệ cố định thường được kích hoạt vào những thời điểm không phù hợp nhất.
Đây không phải là một chiến lược toàn năng.Thông thường trong thị trường biến động ngang, phù hợp nhất với giai đoạn mở rộng của xu hướng ban đầu và dao động từ thấp đến caoNếu bạn thấy rằng chiến lược của bạn đã không hoạt động tốt trong một thời gian gần đây, có thể thị trường đã đi vào một giai đoạn không phù hợp.
Khi nào sử dụng? Bạn sẽ ngạc nhiên khi thấy thị trường bắt đầu chuyển từ trạng thái biến động thấp sang trạng thái biến động cao, hoặc khi một xu hướng rõ ràng chỉ mới bắt đầu.
Mức mốc nhập cảnh 100 có thể được điều chỉnh theo tỷ lệ dao động của tiêu chuẩn: các giống có tỷ lệ dao động cao có thể được điều chỉnh đến 120-150, các giống có tỷ lệ dao động thấp có thể giảm xuống 80-90. Mức mốc xuất cảnh 30 hầu như không di chuyển, đây là mức độ quay trở lại trung bình được xác minh qua nhiều lần kiểm tra lại.
EMA dài 70 là tham số quan trọng, không nên thay đổi tùy ý. Nếu bạn phải điều chỉnh, hãy nhớ:Càng ngắn thì nhạy hơn nhưng càng ồn ào, càng dài thì mịn hơn nhưng lại bị tụt hậu。
Đây không phải là một chiến lược đơn giản mà bạn có thể nắm bắt hoàn toàn ngay từ đầu, nhưng nó cũng không phải là một trò chơi học thuật phức tạp một cách có chủ ý. Mỗi thành phần có lý do tồn tại, mỗi tham số được kiểm tra trong chiến đấu.
Lưu ý rủi ro quan trọng: Bất kỳ chiến lược nào cũng có nguy cơ thua lỗ, và lịch sử không thể hiện lợi nhuận trong tương lai. Hiệu suất của chiến lược có thể khác biệt đáng kể khi môi trường thị trường thay đổi, cần quản lý rủi ro nghiêm ngặt và điều chỉnh theo dõi liên tục.
Nếu bạn đang tìm kiếm một khung chiến lược có thể cung cấp tỷ lệ chiến thắng cao hơn ở giai đoạn đầu của xu hướng, chiến lược Range Oscillator này đáng để bạn dành thời gian nghiên cứu và thử nghiệm.
/*backtest
start: 2024-11-20 00:00:00
end: 2025-11-18 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
// Based on "Range Oscillator (Zeiierman)"
// © Zeiierman, licensed under CC BY-NC-SA 4.0
// Modifications and strategy logic by jokiniemi.
//
// ─────────────────────────────────────────────
// IMPORTANT DISCLAIMER / TV HOUSE RULES
// ─────────────────────────────────────────────
// • This script is FREE and public. I do not charge any fee for it.
// • It is for EDUCATIONAL PURPOSES ONLY and is NOT financial advice.
// • Backtest results can be very different from live trading.
// • Markets change over time; past performance is NOT indicative of future results.
// • You are fully responsible for your own decisions and risk.
//
// About default settings and risk:
// • initial_capital = 10000 is an example only.
// • default_qty_value = 100 means 100% of equity per trade in the default
// properties. This is AGGRESSIVE and is used only as a stress-test example.
// • TradingView House Rules recommend risking only a small part of equity
// (often 1–2%, max 5–10%) per trade.
// • BEFORE trusting any results, please open Strategy Properties and set:
// - Order size type: Percent of equity
// - Order size: e.g. 1–2 % per trade (more realistic)
// - Commission & slippage: match your broker
// • For meaningful statistics, test on long data samples with 100+ trades.
//
// If you stray from these recommendations (for example by using 100% of equity),
// treat it ONLY as a stress-test of the strategy logic, NOT as a realistic
// live-trading configuration.
//
// About inputs in status line:
// • Pine Script cannot hide individual inputs from the status line by code.
// • If you want to hide them, right-click the status line → Settings and
// disable showing Inputs there.
//
// ─────────────────────────────────────────────
// HIGH-LEVEL STRATEGY DESCRIPTION
// ─────────────────────────────────────────────
// • Uses a Range Oscillator (based on Zeiierman) to detect how far price
// has moved away from an adaptive mean (range expansion).
// • Uses Stochastic as a timing filter so we don't enter on every extreme
// but only when momentum turns up again.
// • Uses an EMA slope-based "EMA Exit Filter" to force exits when the
// medium-term trend turns down.
// • Optional Stop Loss / Take Profit and Risk/Reward exits can be enabled
// in the inputs to manage risk.
// • Long-only by design.
//
// Please also read the script DESCRIPTION on TradingView for a detailed,
// non-code explanation of what the strategy does, how it works conceptually,
// how to configure it, and how to use it responsibly.
// Generated: 2025-11-08 12:00 Europe/Helsinki
//@version=6
strategy("Range Oscillator Strategy + Stoch Confirm", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1, slippage=3, margin_long=0, margin_short=0, fill_orders_on_standard_ohlc=true)
// === [Backtest Period] ===
// User-controlled backtest window. Helps avoid cherry-picking a tiny period.
startYear = input.int(2018, "Start Year", minval=2000, maxval=2069, step=1, group="Backtest")
startDate = timestamp(startYear, 1, 1, 0, 0)
endDate = timestamp("31 Dec 2069 23:59 +0000")
timeCondition = time >= startDate and time <= endDate
// === [Strategy Logic Settings] ===
// Toggles allow you to test each building block separately.
useOscEntry = input.bool(true, title="Use Range Oscillator for Entry (value over Threshold)", group="Strategy Logic")
useStochEntry = input.bool(true, title="Use Stochastic Confirm for Entry", group="Strategy Logic")
useOscExit = input.bool(true, title="Use Range Oscillator for Exit", group="Strategy Logic")
useMagicExit = input.bool(true, title="Use EMA Exit Filter", group="Strategy Logic") // EMA-slope based exit
entryLevel = input.float(100.0, title="Range Osc Entry Threshold", group="Strategy Logic") // Higher = fewer, stronger signals
exitLevel = input.float(30.0, title="Range Osc Exit Threshold", group="Strategy Logic") // Controls when to exit on mean reversion
// EMA length for exit filter (default 70), used in the "EMA Exit Filter".
emaLength = input.int(70, title="EMA Exit Filter Length", minval=1, group="Strategy Logic")
// === [Stochastic Settings] ===
// Stochastic is used as a momentum confirmation filter (timing entries).
periodK = input.int(7, title="%K Length", minval=1, group="Stochastic")
smoothK = input.int(3, title="%K Smoothing", minval=1, group="Stochastic")
periodD = input.int(3, title="%D Smoothing", minval=1, group="Stochastic")
crossLevel = input.float(100.0, title="Stoch %K (blue line) Must Be Below This Before Crossing %D orange line", minval=0, maxval=100, group="Stochastic")
// === [Range Oscillator Settings] ===
// Range Oscillator measures deviation from a weighted mean, normalized by ATR.
length = input.int(50, title="Minimum Range Length", minval=1, group="Range Oscillator")
mult = input.float(2.0, title="Range Width Multiplier", minval=0.1, group="Range Oscillator")
// === [Risk Management] ===
// Optional risk exits. By default SL/TP are OFF in code – you can enable them in Inputs.
// TradingView recommends using realistic SL/TP and small risk per trade.
useSL = input.bool(false, title="Use Stop Loss", group="Risk Management")
slPct = input.float(1.5, title="Stop Loss (%)", minval=0.0, step=0.1, group="Risk Management") // Example: 1.5% of entry price
useTP = input.bool(false, title="Use Take Profit", group="Risk Management")
tpPct = input.float(3.0, title="Take Profit (%)", minval=0.0, step=0.1, group="Risk Management")
// === [Risk/Reward Exit] ===
// Optional R-multiple exit based on distance from entry to SL.
useRR = input.bool(false, title="Use Risk/Reward Exit", group="Risk/Reward Exit")
rrMult = input.float(1.5, title="Reward/Risk Multiplier", minval=0.1, step=0.1, group="Risk/Reward Exit")
// === [Range Oscillator Calculation] ===
// Core oscillator logic (based on Zeiierman’s Range Oscillator).
atrRaw = nz(ta.atr(2000), ta.atr(200))
rangeATR = atrRaw * mult
sumWeightedClose = 0.0
sumWeights = 0.0
for i = 0 to length - 1
delta = math.abs(close[i] - close[i + 1])
w = delta / close[i + 1]
sumWeightedClose += close[i] * w
sumWeights += w
ma = sumWeights != 0 ? sumWeightedClose / sumWeights : na
distances = array.new_float(length)
for i = 0 to length - 1
array.set(distances, i, math.abs(close[i] - ma))
maxDist = array.max(distances)
osc = rangeATR != 0 ? 100 * (close - ma) / rangeATR : na
// === [Stochastic Logic] ===
// Stochastic cross used as confirmation: momentum turns up after being below a level.
k = ta.sma(ta.stoch(close, high, low, periodK), smoothK)
d = ta.sma(k, periodD)
stochCondition = k < crossLevel and ta.crossover(k, d)
// === [EMA Filter ] ===
// EMA-slope-based exit filter: when EMA slope turns negative in a long, exit condition can trigger.
ema = ta.ema(close, emaLength)
chg = ema - ema[1]
pct = ema[1] != 0 ? (chg / ema[1]) * 100.0 : 0.0
isDown = pct < 0
magicExitCond = useMagicExit and isDown and strategy.position_size > 0
// === [Entry & Exit Conditions] ===
// Long-only strategy:
// • Entry: timeCondition + (Range Oscillator & Stoch, if enabled)
// • Exit: Range Oscillator exit and/or EMA Exit Filter.
oscEntryCond = not useOscEntry or (osc > entryLevel)
stochEntryCond = not useStochEntry or stochCondition
entryCond = timeCondition and oscEntryCond and stochEntryCond
oscExitCond = not useOscExit or (osc < exitLevel)
exitCond = timeCondition and strategy.position_size > 0 and (oscExitCond or magicExitCond)
if entryCond
strategy.entry("Long", strategy.long)
if exitCond
strategy.close("Long")
// === [Risk Management Exits] ===
// Optional SL/TP and RR exits (OCO). They sit on top of the main exit logic.
// Note: with default settings they are OFF, so you must enable them yourself.
ap = strategy.position_avg_price
slPrice = useSL ? ap * (1 - slPct / 100) : na
tpPrice = useTP ? ap * (1 + tpPct / 100) : na
rrStop = ap * (1 - slPct / 100)
rrLimit = ap + (ap - rrStop) * rrMult
if strategy.position_size > 0
if useSL or useTP
strategy.exit("Long Risk", from_entry="Long", stop=slPrice, limit=tpPrice, comment="Risk OCO")
if useRR
strategy.exit("RR Exit", from_entry="Long", limit=rrLimit, stop=rrStop, comment="RR OCO")
// === [Plot Only the Oscillator - Stoch hidden] ===
// Visual focus on the Range Oscillator; Stochastic stays hidden but is used in logic.
inTrade = strategy.position_size > 0
oscColor = inTrade ? color.green : color.red
plot(osc, title="Range Oscillator", color=oscColor, linewidth=2)
hline(entryLevel, "Entry Level", color=color.green, linestyle=hline.style_dotted)
hline(exitLevel, "Exit Level", color=color.red, linestyle=hline.style_dotted)
plot(k, title="%K", color=color.blue, display=display.none)
plot(d, title="%D", color=color.orange, display=display.none)
// Plot EMA (hidden) so it is available but not visible on the chart.
plot(ema, title="EMA Exit Filter", display=display.none)