
Стратегия представляет собой двунаправленную торговую систему, которая сочетает экспоненциальную скользящую среднюю (EMA) с временными интервалами. Система определяет основное направление торговли в соответствии с соотношением позиций EMA разных периодов в фиксированном временном интервале, определенном пользователем. В то же время, отслеживая сигнал пересечения другого набора индикаторов EMA или когда время приближается к следующему В ходе торгового цикла система выбирает подходящее время для проведения обратных хеджирующих сделок, тем самым реализуя возможности двусторонней торговли.
Работа стратегии основана на двух основных механизмах: первичной торговле с фиксированными временными интервалами и гибкой разворотной торговле. Основная транзакция основана на относительном положении 5⁄40-минутной EMA для определения направления тренда, и транзакция выполняется на каждом торговом интервале (по умолчанию — 30 минут). Обратная торговля осуществляется путем отслеживания сигнала пересечения 5⁄10-минутной EMA или за 1 минуту до следующей крупной сделки, в зависимости от того, что произойдет раньше. Вся транзакция выполняется в течение заданного пользователем временного окна, чтобы обеспечить ее своевременность.
Это комплексная стратегия, которая сочетает отслеживание тренда и обратную торговлю. Благодаря координации временных интервалов и индикаторов EMA достигается двусторонний захват торговых возможностей. Стратегия легко настраивается и имеет хороший потенциал контроля рисков, но требует оптимизации параметров и улучшения управления рисками на основе реальных рыночных условий. При применении в режиме реального времени рекомендуется проводить достаточное бэктестинг и оптимизацию параметров, а также вносить целевые корректировки на основе характеристик рынка.
/*backtest
start: 2025-01-02 00:00:00
end: 2025-01-09 00:00:00
period: 3m
basePeriod: 3m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("SPX EMA Strategy with Opposite Trades", overlay=true)
// User-defined inputs
tradeIntervalMinutes = input.int(30, title="Main Trade Interval (in minutes)", minval=1)
oppositeTradeDelayMinutes = input.int(1, title="Opposite Trade time from next trade (in minutes)", minval=1) // Delay of opposite trade (1 min before the next trade)
startHour = input.int(10, title="Start Hour", minval=0, maxval=23)
startMinute = input.int(30, title="Start Minute", minval=0, maxval=59)
stopHour = input.int(15, title="Stop Hour", minval=0, maxval=23)
stopMinute = input.int(0, title="Stop Minute", minval=0, maxval=59)
// User-defined EMA periods for main trade and opposite trade
mainEmaShortPeriod = input.int(5, title="Main Trade EMA Short Period", minval=1)
mainEmaLongPeriod = input.int(40, title="Main Trade EMA Long Period", minval=1)
oppositeEmaShortPeriod = input.int(5, title="Opposite Trade EMA Short Period", minval=1)
oppositeEmaLongPeriod = input.int(10, title="Opposite Trade EMA Long Period", minval=1)
// Calculate the EMAs for main trade
emaMainShort = ta.ema(close, mainEmaShortPeriod)
emaMainLong = ta.ema(close, mainEmaLongPeriod)
// Calculate the EMAs for opposite trade (using different periods)
emaOppositeShort = ta.ema(close, oppositeEmaShortPeriod)
emaOppositeLong = ta.ema(close, oppositeEmaLongPeriod)
// Condition to check if it is during the user-defined time window
startTime = timestamp(year, month, dayofmonth, startHour, startMinute)
stopTime = timestamp(year, month, dayofmonth, stopHour, stopMinute)
currentTime = timestamp(year, month, dayofmonth, hour, minute)
// Ensure the script only trades within the user-defined time window
isTradingTime = currentTime >= startTime and currentTime <= stopTime
// Time condition: Execute the trade every tradeIntervalMinutes
var float lastTradeTime = na
timePassed = na(lastTradeTime) or (currentTime - lastTradeTime) >= tradeIntervalMinutes * 60 * 1000
// Entry Conditions for Main Trade
longCondition = emaMainShort > emaMainLong // Enter long if short EMA is greater than long EMA
shortCondition = emaMainShort < emaMainLong // Enter short if short EMA is less than long EMA
// Detect EMA crossovers for opposite trade (bullish or bearish)
bullishCrossoverOpposite = ta.crossover(emaOppositeShort, emaOppositeLong) // Opposite EMA short crosses above long
bearishCrossoverOpposite = ta.crossunder(emaOppositeShort, emaOppositeLong) // Opposite EMA short crosses below long
// Track the direction of the last main trade (true for long, false for short)
var bool isLastTradeLong = na
// Track whether an opposite trade has already been executed after the last main trade
var bool oppositeTradeExecuted = false
// Execute the main trades if within the time window and at the user-defined interval
if isTradingTime and timePassed
if longCondition
strategy.entry("Main Long", strategy.long)
isLastTradeLong := true // Mark the last trade as long
oppositeTradeExecuted := false // Reset opposite trade status
lastTradeTime := currentTime
// label.new(bar_index, low, "Main Long", color=color.green, textcolor=color.white, size=size.small)
else if shortCondition
strategy.entry("Main Short", strategy.short)
isLastTradeLong := false // Mark the last trade as short
oppositeTradeExecuted := false // Reset opposite trade status
lastTradeTime := currentTime
// label.new(bar_index, high, "Main Short", color=color.red, textcolor=color.white, size=size.small)
// Execute the opposite trade only once after the main trade
if isTradingTime and not oppositeTradeExecuted
// 1 minute before the next main trade or EMA crossover
if (currentTime - lastTradeTime) >= (tradeIntervalMinutes - oppositeTradeDelayMinutes) * 60 * 1000 or bullishCrossoverOpposite or bearishCrossoverOpposite
if isLastTradeLong
// If the last main trade was long, enter opposite short trade
strategy.entry("Opposite Short", strategy.short)
//label.new(bar_index, high, "Opposite Short", color=color.red, textcolor=color.white, size=size.small)
else
// If the last main trade was short, enter opposite long trade
strategy.entry("Opposite Long", strategy.long)
//label.new(bar_index, low, "Opposite Long", color=color.green, textcolor=color.white, size=size.small)
// After entering the opposite trade, set the flag to true so no further opposite trades are placed
oppositeTradeExecuted := true
// Plot the EMAs for visual reference
plot(emaMainShort, title="Main Trade Short EMA", color=color.blue)
plot(emaMainLong, title="Main Trade Long EMA", color=color.red)
plot(emaOppositeShort, title="Opposite Trade Short EMA", color=color.purple)
plot(emaOppositeLong, title="Opposite Trade Long EMA", color=color.orange)