Стратегия спирального прорыва в движущейся средней

Автор:Чао Чжан, Дата: 2024-01-15 11:45:23
Тэги:

img

Обзор

Эта стратегия сочетает в себе индикатор спирального канала и индикатор скорости изменения (ROC). Она генерирует сигналы покупки, когда цена проходит через верхнюю полосу и скользящую среднюю, и сигналы продажи, когда цена проходит через нижнюю полосу и скользящую среднюю.

Логика стратегии

Стратегия основана на двух ключевых показателях:

  1. Спиральные каналы: График верхних и нижних полос для определения направления тренда.

  2. Коэффициент изменения (ROC): обнаруживает ускорение цены. ROC выше положительного порога предполагает ускорение движения цены вверх, в то время как ROC ниже отрицательного порога указывает на ускорение движения цены вниз.

Сигналы покупки генерируются, когда как Спиральный канал, так и ROC дают бычьи индикаторы, а именно перерыв цены выше верхней полосы в сочетании с ускорением восходящего импульса. Сигналы продажи запускаются, когда оба индикатора становятся медвежими.

Объединенные сигналы помогают избежать торговли против тренда и повышают надежность.

Преимущества

  1. Надежные сигналы с более высокой скоростью выигрыша, требующие согласия между трендом и импульсом.

  2. Настраиваемая частота торговли посредством настройки параметров, например, настройка параметров ROC.

  3. Стоп-лосс для ограничения риска снижения на отдельных сделках.

  4. Возобновить механизм для развития и дальнейшего повышения прибыльности.

Риски

  1. Пропуск некоторых торговых возможностей и ограничение потенциала прибыли из-за требования надежности сигнала.

  2. Уязвимы к тому, чтобы попасть в ловушку, когда тенденция меняется, что может привести к большим потерям.

  3. Плохая настройка параметров может привести к слишком малому или слишком большому количеству сигналов.

  4. Фиксированный процент стоп-лосса не может предотвратить серьезные потери при огромных неблагоприятных колебаниях цен.

Возможности для расширения

  1. Оптимизируйте параметры ROC для лучшей производительности.

  2. Проверьте разные уровни стоп-лосса, чтобы сбалансировать риск и прибыль.

  3. Добавьте другие фильтры, такие как объем, индикаторы волатильности, чтобы уточнить сигналы.

  4. Оценить эффективность на разных рынках, чтобы найти лучшее соответствие.

  5. Внедрение динамического размещения позиций для различных рыночных условий.

Заключение

Стратегия сочетает в себе спиральный канал и ROC для оценки направления и импульса тренда. Она направлена на надежность сигнала при сохранении прибыльности за счет повторного входа и настройки параметров. Риск в основном контролируется фиксированным процентным стоп-лосом. В целом это относительно полная структура, достойная базовой количественной торговой стратегии.


/*backtest
start: 2024-01-07 00:00:00
end: 2024-01-14 00:00:00
period: 45m
basePeriod: 5m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("SSL Chaikin BF 🚀", overlay=true, precision=2, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075)

/////////////// Time Frame ///////////////
_0 = input(false,  "════════ Test Period ═══════")
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

/////////////// Chaikin MF /////////////// 
_1 = input(false,  "═══════ Chaikin MF ═══════")
length = input(20, minval=1, title = "Chaikin SMA Length")
upperThreshold = input(0.04, step=0.01, title="Upper Threshold")
lowerThreshold = input(0.02, step=0.01, title="Lower Threshold")
ad = close==high and close==low or high==low ? 0 : ((2*close-low-high)/(high-low))*volume
mf = sum(ad, length) / sum(volume, length)

/////////////// SSL Channels /////////////// 
_2 = input(false,  "═════════ SSL ══════════")
len1=input(title="SMA Length 1", defval=12)
len2=input(title="SMA Length 2", defval=13)

smaHigh = sma(high, len1)
smaLow = sma(low, len2)

Hlv = 0
Hlv := close > smaHigh ? 1 : close < smaLow ? -1 : Hlv[1]
sslDown = Hlv < 0 ? smaHigh : smaLow
sslUp = Hlv < 0 ? smaLow : smaHigh

///////////// Rate Of Change ///////////// 
_3 = input(false,  "══════ Rate of Change ══════")
source = close
roclength = input(13, "ROC Length",  minval=1)
pcntChange = input(4, "ROC % Change", minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

///////////////  Strategy  /////////////// 
long = sslUp > sslDown and isMoving() or crossover(mf, upperThreshold)
short = sslUp < sslDown and isMoving() or crossunder(mf, lowerThreshold)

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1]) 

//////////////// Stop loss /////////////// 
_4 = input(false,  "════════ Stop Loss ═══════")
sl_inp = input(2.0, title='Stop Loss %') / 100

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

/////////////// Execution /////////////// 
if testPeriod()
    strategy.entry("L", strategy.long, when=long)
    strategy.entry("S", strategy.short, when=short)
    strategy.exit("L SL", "L", stop=long_sl, when=since_longEntry > 0)
    strategy.exit("S SL", "S", stop=short_sl, when=since_shortEntry > 0)

/////////////// Plotting /////////////// 
p1 = plot(sslDown, linewidth = 1, color=color.red)
p2 = plot(sslUp, linewidth = 1, color=color.lime)
fill(p1, p2,  color = sslDown < sslUp ? color.lime : color.red, transp=80)
bgcolor(isMoving() ? long ? color.green : short ? color.red : na : color.white, transp=80)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=30)
bgcolor(crossover(mf, upperThreshold) ? color.blue : crossunder(mf, lowerThreshold) ? color.orange : na, transp=30)

Больше