
Двухразовая стратегия арбитражного трейдинга - это высокочастотная система торговли в течение дня, основанная на стохастическом осцилляторе, в основе которой используются два различных параметра, установленных для генерирования и подтверждения торговых сигналов в течение 15-секундных временных рамок. Основная логика идентифицирует потенциальные точки входа через пересечение %K-линии и %D-линии основного случайного индикатора, ссылаясь на значение %D второстепенного случайного индикатора в качестве фильтра состояния рынка, который сочетает в себе движущиеся средние и рыночные временные фильтрационные условия и создает многоуровневую механизм подтверждения.
Стратегия использует двойную систему случайных шоковых показателей, называемых основными и референсными:
Основные параметры случайных сейсмических параметров:
Смотрите настройки случайных сейсмических показателей:
Входная логика имеет тонкий дизайн, многоуровневый подтверждающий эффективность сигнала:
Условия участия:
Условия приема:
Логика выхода основана на сочетании временных и технических сигналов:
В стратегии также включены функции распознавания форм:
Многоуровневый механизм подтверждения: взаимное подтверждение с помощью двух различных конфигураций случайных показателей колебаний, уменьшение ложного сигнала, создаваемого одним показателем, повышение надежности сигнала.
Точные правила входа и выходаВ частности, в стратегии определены четкие условия входа и выхода, исключена субъективность в принятии торговых решений, достигнута полная систематизация торгов.
Способность распознавать формуЭто функция, которую не могут реализовать многие простые стратегии: способность распознавать “более высокие” и “менее высокие” формы на рынке, чтобы поймать возможность продолжения тренда.
Фильтр времениСнижение скольжения и уменьшение затрат путем ограничения времени торговли в обычные рыночные часы, избежание высокой волатильности и низкой ликвидности перед открытием и закрытием.
Фильтрация по движущимся средним: Функция фильтрации выборных движущихся средних добавляет уровень подтверждения тренда, обеспечивающий соответствие направления торговли общей тенденции.
Различия в цене и параметры емкостиВ стратегии введены множество параметров, которые контролируют величину изменения цены и диапазон отклонений показателя, эффективно фильтруя шумовые сигналы, создаваемые незначительными колебаниями.
Динамическая логическая конверсияСистема способна динамично адаптироваться к условиям перехода от многого к пустому и от пустого к многого, основываясь на состоянии рынка.
Всеобъемлющая система оповещенияВ стратегии встроены широкие условия оповещения для мониторинга и выполнения транзакций в реальном времени.
Риски высокой частоты торгов в короткие временные рамкиСтратегия использования 15-секундных временных рамок может привести к избыточному количеству сигналов, что приведет к частым сделкам, увеличению стоимости торговли и может привести к большому количеству ложных сигналов при больших колебаниях на рынке.
Отсутствие механизмов сдерживанияВ коде отсутствует четкая реализация стоп-лора, что может привести к большому риску потерь при резком реверсии тренда. Отсутствие контроля риска является одним из основных недостатков стратегии.
Параметр ЧувствительностьПримечание: несколько точных параметров, используемых в стратегии (например, порог разницы 0,15, порог разницы 0,1% и т. д.), могут быть слишком чувствительны к различным рыночным условиям и нуждаются в частых корректировках.
Временные издержкиВ то же время, в некоторых странах, например, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае, в Китае.
Зависимость от ликвидности: высокочастотная стратегия может иметь проблемы со скольжениями на низколиквидном рынке, где фактическая цена исполнения может существенно отличаться от цены, когда сигнал генерируется.
Задержка технических показателейИндекс случайных колебаний сам по себе имеет определенную отсталость, особенно в быстро меняющихся рынках, и может не успеть вовремя зафиксировать переломные моменты.
Риск переизмеримостиНапример, если вы используете более высокий уровень риска, то вы можете получить более высокий уровень риска, если вы используете более высокий уровень риска, чем если вы используете более высокий уровень риска.
Увеличение убыточностиКлючевым пунктом оптимизации является реализация интеллектуальной системы остановки, при которой можно рассмотреть стратегию остановки на основе ATR (средний реальный диапазон колебаний) или использовать уровень техники (например, высокие и низкие точки в предыдущем периоде) в качестве точки остановки, чтобы ограничить максимальные потери в одной сделке.
Введение управления позициямиДинамическая корректировка масштаба сделок на основе рыночной волатильности и рисковой устойчивости счета, использование различных позиционных конфигураций при различной силе сигнала для оптимизации использования средств и рисково-доходной части.
Добавить подтверждение транзакции: интегрировать показатели трафика в систему, требуя, чтобы важные входящие сигналы имели достаточную поддержку трафика, чтобы отфильтровывать ненадежные сигналы в условиях низкого трафика.
Слияние нескольких показателейВзаимодействие с другими динамическими и трендовыми индикаторами, такими как RSI, MACD или BRI, для создания более полного взгляда на рынок и повышения устойчивости системы.
Оптимизация временных рамок: тестирование различных базовых временных рамок, таких как 1 минута или 5 минут, которые могут уменьшить шум, сохраняя при этом достаточные возможности для торговли, чтобы найти оптимальный баланс между качеством и количеством сигналов.
Добавление отслеживаемой статистикиВнедрение более полного анализа показателей эффективности, таких как максимальный отказ, коэффициент Шарпа, коэффициент выигрыша, коэффициент убытка и т. д., для более научной оценки эффективности стратегии.
Параметры адаптации: преобразование фиксированных параметров в адаптивные параметры, основанные на динамике рыночной волатильности, что позволяет стратегии адаптироваться к различным рыночным условиям.
Увеличение рыночных фильтровПрименение VIX (индекс волатильности) или аналогичных показателей в качестве фильтрации рыночной среды, для корректировки параметров стратегии или приостановки торговли в условиях высокой волатильности.
Двухвременная стратегия арбитража является тщательно разработанной системой краткосрочной торговли с высокой частотой, которая повышает надежность торговых сигналов с помощью многоуровневых механизмов подтверждения, таких как двойной случайный индикатор колебаний, фильтрация движущихся средних и временная фильтрация. Эта стратегия идентифицирует переломные моменты и продолжение тенденции в течение коротких периодов времени на регулярных рынках, подходящие для рынков с достаточной ликвидностью и умеренной волатильностью.
Несмотря на совершенствование структуры разработки стратегии, существует недостаток в ключевых механизмах управления рисками, таких как риски, присущие высокочастотным сделкам, и отсутствие остановок. Для повышения устойчивости и долгосрочной прибыльности стратегии рекомендуется добавить оптимизационные меры, такие как остановочные механизмы, системы управления позициями, подтверждение объема сделок и интеграция нескольких показателей. Кроме того, преобразование фиксированных параметров в адаптивные параметры и увеличение полного статистического отслеживания обратной связи помогут стратегии сохранять стабильную производительность в различных рыночных условиях.
С глубоким пониманием и постоянной оптимизацией этой стратегии, система торговли имеет потенциал стать эффективной частью инструментария для торговли в течение суток, особенно подходящей для трейдеров, которые имеют глубокое понимание технических показателей и могут своевременно контролировать рынок.
/*backtest
start: 2025-01-01 00:00:00
end: 2025-06-17 00:00:00
period: 4h
basePeriod: 4h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
*/
//@version=6
strategy("Dual TF Stochastic Strategy", overlay=false)
// Input parameters with updated defaults
primaryLen = input.int(12, "Primary Stoch K Length", minval=1) // Changed from 14 to 12
primarySmooth = input.int(12, "Primary Stoch K Smoothing", minval=1) // Changed from 3 to 12
primaryDLen = input.int(12, "Primary Stoch D Length", minval=1) // Changed from 3 to 12
primaryRes = input.timeframe("15S", "Primary Timeframe") // Changed from "" to "15S"
refLen = input.int(12, "Reference Stoch K Length", minval=1) // Changed from 14 to 12
refSmooth = input.int(15, "Reference Stoch K Smoothing", minval=1) // Changed from 3 to 15
refDLen = input.int(30, "Reference Stoch D Length", minval=1) // Changed from 3 to 30
refRes = input.timeframe("15S", "Reference Timeframe") // Changed from "D" to "15S"
tolerance = input.float(0.1, "Ref D Tolerance %", minval=0.1, maxval=10.0, step=0.1) // Changed from 1.0 to 0.1
maxPriceDiff = input.float(0.1, "Maximum Price % Difference", minval=0.1, maxval=5.0, step=0.1) // Changed from 1.0 to 0.1
closeKThreshold = input.float(0.7, "Close %K Tolerance %", minval=0.1, maxval=10.0, step=0.1) // Changed from 5.0 to 0.7
minPriceDiffShort = input.float(0.1, "Min Price % Diff for Close %K Short", minval=0.1, maxval=5.0, step=0.1) // Changed from 0.5 to 0.1
showLabels = input.bool(true, "Show Crossover/Crossunder Labels")
// Time Filters (America/New_York timezone, UTC-4)
is_premarket = hour(time, "America/New_York") < 9
is_postmarket = hour(time, "America/New_York") >= 16
is_regular_hours = hour(time, "America/New_York") >= 9 and hour(time, "America/New_York") < 16
is_exit_time = hour(time, "America/New_York") >= 15 and minute(time, "America/New_York") >= 30 // 3:30 PM ET
// Moving Average Settings
useMAFilter = input.bool(true, "Use Moving Average Filter")
maLength = input.int(200, "Moving Average Length", minval=1)
maType = input.string("SMA", "Moving Average Type", options=["SMA", "EMA", "WMA", "VWMA"])
maTimeframe = input.timeframe("", "Moving Average Timeframe")
// Stochastic Calculations
primaryHighest = ta.highest(high, primaryLen)
primaryLowest = ta.lowest(low, primaryLen)
primaryK_raw = 100 * (close - primaryLowest) / (primaryHighest - primaryLowest)
primaryK = ta.sma(primaryK_raw, primarySmooth)
primaryD = ta.sma(primaryK, primaryDLen)
[primaryK_tf, primaryD_tf] = request.security(syminfo.tickerid, primaryRes, [primaryK, primaryD])
refHighest = ta.highest(high, refLen)
refLowest = ta.lowest(low, refLen)
refK_raw = 100 * (close - refLowest) / (refHighest - refLowest)
refK = ta.sma(refK_raw, refSmooth)
refD = ta.sma(refK, refDLen)
[refK_tf, refD_tf] = request.security(syminfo.tickerid, refRes, [refK, refD])
// Calculate Moving Average
var float ma = na
if useMAFilter
if maType == "SMA"
ma := request.security(syminfo.tickerid, maTimeframe, ta.sma(close, maLength))
else if maType == "EMA"
ma := request.security(syminfo.tickerid, maTimeframe, ta.ema(close, maLength))
else if maType == "WMA"
ma := request.security(syminfo.tickerid, maTimeframe, ta.wma(close, maLength))
else if maType == "VWMA"
ma := request.security(syminfo.tickerid, maTimeframe, ta.vwma(close, maLength))
// Price relative to MA
priceAboveMA = not useMAFilter or close > ma
priceBelowMA = not useMAFilter or close < ma
// Crossover Detection and Tracking
crossOver = ta.crossover(primaryK_tf, primaryD_tf)
crossUnder = ta.crossunder(primaryK_tf, primaryD_tf)
// Separate tracking for crossover and crossunder %K and price
var float lastCrossOverK = na
var float lastCrossOverPrice = na
var float currentCrossOverK = na
var float currentCrossOverPrice = na
var float lastCrossUnderK = na
var float lastCrossUnderPrice = na
var float currentCrossUnderK = na
var float currentCrossUnderPrice = na
// Update crossover tracking variables
if crossOver
lastCrossOverK := nz(currentCrossOverK, primaryK_tf[1])
lastCrossOverPrice := nz(currentCrossOverPrice, close[1])
currentCrossOverK := primaryK_tf
currentCrossOverPrice := close
// Update crossunder tracking variables
if crossUnder
lastCrossUnderK := nz(currentCrossUnderK, primaryK_tf[1])
lastCrossUnderPrice := nz(currentCrossUnderPrice, close[1])
currentCrossUnderK := primaryK_tf
currentCrossUnderPrice := close
// Calculate differences separately
crossOverPriceDiffPercent = math.abs((currentCrossOverPrice - lastCrossOverPrice) / lastCrossOverPrice * 100)
crossOverKDiffPercent = math.abs((currentCrossOverK - lastCrossOverK) / lastCrossOverK * 100)
crossUnderPriceDiffPercent = math.abs((currentCrossUnderPrice - lastCrossUnderPrice) / lastCrossUnderPrice * 100)
crossUnderKDiffPercent = math.abs((currentCrossUnderK - lastCrossUnderK) / lastCrossUnderK * 100)
isKCloseCrossUnder = crossUnderKDiffPercent <= closeKThreshold and not na(lastCrossUnderK)
// New condition for long entry based on %K and refD_tf difference
kAndRefDDiffClose = crossOver and math.abs(currentCrossOverK - refD_tf) <= 0.15
// Labels for crossover and crossunder (optional)
if showLabels
if crossOver
diffKandRefD = math.abs(currentCrossOverK - refD_tf)
label.new(bar_index, 50, "CrossOver\nDiff K-RefD: " + str.tostring(diffKandRefD, "#.###"), color=color.green, textcolor=color.black, style=label.style_label_up)
if crossUnder
diffKandRefD = math.abs(currentCrossUnderK - refD_tf)
label.new(bar_index, 50, "CrossUnder\nDiff K-RefD: " + str.tostring(diffKandRefD, "#.###"), color=color.red, textcolor=color.black, style=label.style_label_down)
// Entry Conditions
longKCondition = crossOver and (na(lastCrossOverK) or currentCrossOverK > lastCrossOverK)
shortKCondition = crossUnder and (crossUnderPriceDiffPercent <= maxPriceDiff)
closeKShortCondition = crossUnder and isKCloseCrossUnder and (crossUnderPriceDiffPercent > minPriceDiffShort)
crossUnderBetween50and45 = crossUnder and currentCrossUnderK <= 50 and currentCrossUnderK > 45
// Long to Short if crossunder %K > 80 OR < 60
longToShortCondition = crossUnder and (currentCrossUnderK > 80 or currentCrossUnderK < 60) and strategy.position_size > 0 and is_regular_hours
upperLimit = refD_tf * (1 + tolerance/100)
lowerLimit = refD_tf * (1 - tolerance/100)
withinToleranceLong = primaryK_tf >= lowerLimit and primaryK_tf <= upperLimit
withinToleranceShort = primaryK_tf >= lowerLimit and primaryK_tf <= upperLimit
// Final Entry Conditions with MA filter
longCondition = ((longKCondition and (refD_tf >= 50 or refD_tf < 20)) or kAndRefDDiffClose) and is_regular_hours and not is_exit_time and priceAboveMA
shortCondition = (shortKCondition or (crossUnder and withinToleranceShort and (crossUnderPriceDiffPercent <= maxPriceDiff)) or closeKShortCondition or longToShortCondition or crossUnderBetween50and45) and is_regular_hours and not is_exit_time and priceBelowMA
// Short-to-Long Transition Condition with MA filter
shortToLongCondition = crossOver and currentCrossOverK < 25 and strategy.position_size < 0 and is_regular_hours and not is_exit_time and priceAboveMA
// Tracking for %K crossing under refD_tf
var float lastPrimaryKCrossUnderRefD = na
var float currentPrimaryKCrossUnderRefD = na
var bool isPrimaryKCrossUnderRefD = false
// Check if primary %K crosses under reference %D
isPrimaryKCrossUnderRefD := ta.crossunder(primaryK_tf, refD_tf)
// Update tracking for %K crossing under refD
if isPrimaryKCrossUnderRefD
lastPrimaryKCrossUnderRefD := currentPrimaryKCrossUnderRefD
currentPrimaryKCrossUnderRefD := primaryK_tf
// Exit Conditions
if is_exit_time
strategy.close("Long")
strategy.close("Short")
else if isPrimaryKCrossUnderRefD and not na(lastPrimaryKCrossUnderRefD) and currentPrimaryKCrossUnderRefD < lastPrimaryKCrossUnderRefD
strategy.close("Long")
else if (ta.crossunder(primaryK_tf, primaryD_tf) and primaryK_tf < refD_tf and refD_tf < 60)
strategy.close("Long")
if (ta.crossover(primaryK_tf, primaryD_tf) and primaryK_tf > refD_tf and refD_tf > 20) and not is_exit_time
strategy.close("Short")
// Track if crossunder happens above 85
var bool crossUnderAbove85 = false
// Detect crossunder above 85
if crossUnder and currentCrossUnderK > 85
crossUnderAbove85 := true
// Reset condition if %K crosses over %D
if ta.crossover(primaryK_tf, primaryD_tf)
crossUnderAbove85 := false
// Track previous crossover/crossunder values for Higher Low/Lower High detection
var float prevCrossOverK = na
var float prevCrossUnderK = na
// Update previous values on new crossovers/crossunders
if crossOver
prevCrossOverK := currentCrossOverK
if crossUnder
prevCrossUnderK := currentCrossUnderK
// Higher Low and Lower High conditions
higherLowCondition = crossOver and not na(prevCrossOverK) and currentCrossOverK > prevCrossOverK
lowerHighCondition = crossUnder and not na(prevCrossUnderK) and currentCrossUnderK < prevCrossUnderK
// Strategy Entries and Transitions
if longCondition
strategy.entry("Long", strategy.long)
if shortCondition
if strategy.position_size > 0 // If in a long position, close it first
strategy.close("Long")
strategy.entry("Short", strategy.short)
if shortToLongCondition
strategy.close("Short")
if ((longKCondition and (refD_tf >= 50 or refD_tf < 20)) or kAndRefDDiffClose) // Check full longCondition minus time (already checked)
strategy.entry("Long", strategy.long)
// Add label for Short to Long Transition
if shortToLongCondition
label.new(bar_index, na, "T", color=color.green, textcolor=color.white, style=label.style_label_up)
// Add label for Long to Short Transition
if longToShortCondition
label.new(bar_index, na, "T", color=color.red, textcolor=color.white, style=label.style_label_down)
// Plotting
plot(primaryK_tf, "Primary %K", color=color.white, linewidth=1)
plot(primaryD_tf, "Primary %D", color=color.orange, linewidth=1)
plot(refK_tf, "Reference %K", color=color.navy, linewidth=1)
plot(refD_tf, "Reference %D", color=color.rgb(33, 233, 243), linewidth=2)
// Plot current and last %K only for crossUnder when isKCloseCrossUnder is true and currentCrossUnderK < lastCrossUnderK
plot(crossUnder and isKCloseCrossUnder and currentCrossUnderK < lastCrossUnderK ? currentCrossUnderK : na, "Current CrossUnder %K (Close)", color=color.green, style=plot.style_cross, linewidth=2)
plot(crossUnder and isKCloseCrossUnder and currentCrossUnderK < lastCrossUnderK ? lastCrossUnderK : na, "Last CrossUnder %K (Close)", color=color.red, style=plot.style_cross, linewidth=2)
h0 = hline(85, "Upper Band", color=color.rgb(242, 187, 21))
hline(50, "Middle Band", color=#eaff04)
h1 = hline(20, "Lower Band", color=color.rgb(242, 187, 21))
h2 = hline(40, "Lower Band", color=#787B86)
h3 = hline(60, "Lower Band", color=#787B86)
h = hline(0, "Lower Band", color=#787B86)
h5 = hline(100, "Lower Band", color=#787B86)
fill(h0, h1, color=color.rgb(33, 150, 243, 90), title="Background")
fill(h, h1, color=#1be2781d, title="Background")
fill(h0, h5, color=#e21b742d, title="Background")
// Plot the MA if enabled
plot(useMAFilter ? ma : na, "Moving Average", color=color.yellow, linewidth=2)
// Add plot for visualization (optional)
plot(isPrimaryKCrossUnderRefD ? primaryK_tf : na, "Primary %K CrossUnder RefD", color=color.purple, style=plot.style_cross, linewidth=2)
plot(isPrimaryKCrossUnderRefD and not na(lastPrimaryKCrossUnderRefD) ? lastPrimaryKCrossUnderRefD : na, "Last Primary %K CrossUnder RefD", color=color.fuchsia, style=plot.style_cross, linewidth=2)
// Add new alert conditions
alertcondition(higherLowCondition, title="Stoch Higher Low", message="Stoch Higher Low Pattern Detected")
alertcondition(lowerHighCondition, title="Stoch Lower High", message="Stoch Lower High Pattern Detected")
// Plot markers for Higher Low and Lower High patterns
plot(higherLowCondition ? currentCrossOverK : na, "Higher Low", color=color.green, style=plot.style_cross, linewidth=2)
plot(lowerHighCondition ? currentCrossUnderK : na, "Lower High", color=color.red, style=plot.style_cross, linewidth=2)
// Alert conditions
alertcondition(crossOver, title="Stochastic %K Crossed Over %D", message="Stochastic %K crossed over %D")
alertcondition(crossUnder, title="Stochastic %K Crossed Under %D", message="Stochastic %K crossed under %D")
alertcondition(crossOver and primaryK_tf > 50, title="Stochastic %K Crossed Over %D Above 50", message="Stochastic %K crossed over %D above 50")
alertcondition(crossOver and primaryK_tf > refD_tf, title="Stochastic %K Crossed Over %D Above Reference %D", message="Stochastic %K crossed over %D above Reference %D")
alertcondition(longCondition, title="Long Entry Signal", message="Long entry signal triggered")
alertcondition(shortCondition, title="Short Entry Signal", message="Short entry signal triggered")
alertcondition(shortToLongCondition, title="Short to Long Transition", message="Short to Long transition triggered")
alertcondition(longToShortCondition, title="Long to Short Transition", message="Long to Short transition triggered")
alertcondition(isPrimaryKCrossUnderRefD, title="Primary %K Crossed Under Reference %D", message="Primary %K crossed under Reference %D")
alertcondition(crossOver and primaryK_tf > refD_tf, title="Bullish Crossover Above Ref %D", message="Bull: Dual Stoch")
alertcondition(crossUnder and primaryK_tf < refD_tf, title="Bearish Crossunder Below Ref %D", message="Bear: Dual Stoch")