Торговая стратегия прорыва в канале Дончиан

Автор:Чао Чжан, Дата: 2023-11-08 12:31:56
Тэги:

img

Обзор

Данная стратегия подходит для высоковолатильных акций и криптовалют.

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

Эта стратегия строит канал, рассчитывая самую высокую цену pcmax и самую низкую цену pcmin за последние исторические периоды.

Верхняя рельса yh = pcmax - (pcmax - pcmin) * (100 - %Dev)/100

Нижняя рельса yl = pcmin + (pcmax - pcmin) * %Dev/100

где %Dev по умолчанию 13.

Длинный сигнал генерируется, когда цена проходит через верхнюю рельсу. Короткий сигнал генерируется, когда цена проходит через нижнюю рельсу.

Конкретная логика генерации торговых сигналов:

  1. boundup = high > yh для определения нарушения верхней рельсы

  2. bounddn = low < yl для определения нарушения нижней рельсы

  3. upsign = sma(bounddn, 2) == 1 использует sma bounddn для определения постоянного прорыва нижней рельсы

  4. dnsign = sma(boundup, 2) == 1 использует sma из boundup для определения стойкого прорыва верхней рельсы

  5. выход = dnsign прорыв верхней рельсы генерирует выходный сигнал

  6. exitdn = upsign прорыв нижней рельсы генерирует выходный сигнал

  7. если отрыв верхнего сигнала от нижнего рельса генерирует длинный сигнал

  8. если нарушение сигналов верхней рельсы генерирует короткий сигнал

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

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

  1. Использует канал Дончиана для определения тенденций, хорошие результаты обратных тестов

  2. Имеет как длинные, так и короткие сигналы, позволяет торговать двусторонне.

  3. Использует SMA для фильтрации сигналов и избегания плохих сделок

  4. Необязательное прекращение потерь для контроля рисков

  5. Установление времени начала и окончания торговли для избежания рисков на ночь

Риски стратегии

  1. Чувствительный к истории и параметрам %Dev, нуждается в оптимизации для разных продуктов

  2. Может генерировать ложные сигналы на рынках с диапазоном

  3. Не учитывает управление заказами, может повлиять на прибыльность в режиме реального времени

  4. Не учитывает размер позиций, риски чрезмерного размера позиций

  5. Не рассматривает управление деньгами, нуждается в разумном торговом капитале

Идеи улучшения

  1. Оптимизировать историю и параметры %Dev для различных продуктов

  2. Добавление фильтров для предотвращения ложных сигналов на различных рынках

  3. Добавить модуль размещения позиций для управления размером одной позиции

  4. Добавить модуль управления деньгами для ограничения общего размера позиции

  5. Добавить управление заказами для оптимального исполнения заказов

Заключение

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


/*backtest
start: 2023-10-31 00:00:00
end: 2023-11-07 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

////////////////////////////////////////////////////////////
//  Copyright by AlexInc v1.0 02/07/2018  @aav_1980
// PriceChannel strategy
// If you find this script helpful, you can also help me by sending donation to 
// BTC 16d9vgFvCmXpLf8FiKY6zsy6pauaCyFnzS
// LTC LQ5emyqNRjdRMqHPHEqREgryUJqmvYhffM
////////////////////////////////////////////////////////////
//@version=3
strategy("AlexInc PriceChannel Str", overlay=false)
history = input(20)
percentDev = input(13)
capital = input(100)

needlong = input(true, defval = true, title = "Long")
needshort = input(true, defval = true, title = "Short")
usestoploss = input(true, defval = true, title = "Stop Loss")
stoplossmult = input(3.8, defval = 3.8, minval = 1, maxval = 10, title = "Stop loss multiplicator")


fromyear = input(2018, defval = 2018, minval = 1900, maxval = 2100, title = "From Year")
toyear = input(2100, defval = 2100, minval = 1900, maxval = 2100, title = "To Year")
frommonth = input(01, defval = 01, minval = 01, maxval = 12, title = "From Month")
tomonth = input(12, defval = 12, minval = 01, maxval = 12, title = "To Month")
fromday = input(01, defval = 01, minval = 01, maxval = 31, title = "From day")
today = input(31, defval = 31, minval = 01, maxval = 31, title = "To day")

bodymin = min( open, close)
bodymax = max(open, close)

pcmax = highest(bodymax, history)
pcmin = lowest(bodymin, history)

yh = ((pcmax - pcmin) / 100 * (100 - percentDev)) + pcmin
yl = ((pcmax - pcmin) / 100 * percentDev) + pcmin

plot(pcmax)
plot(pcmin)
plot(yh)
plot(yl)

//1
bounddn = low < yl ? 1 : 0
boundup = high > yh ? 1 : 0
upsign = sma(bounddn, 2) == 1
dnsign = sma(boundup, 2) == 1
//2
//upsign = crossover(bodymin, yl)
//dnsign = crossunder(bodymax , yh)


exitup = dnsign
exitdn = upsign

lot = strategy.equity / close * capital / 100


xATR = atr(history)
nLoss = usestoploss ? stoplossmult * xATR : na

stop_level_long = 0.0
stop_level_long := nz(stop_level_long[1])

stop_level_short = 0.0
stop_level_short := nz(stop_level_short[1])

pos = strategy.position_size
if pos >0 and pos[1] <= 0 //crossover(pos, 0.5)
    stop_level_long = strategy.position_avg_price - nLoss
if pos < 0 and pos[1] >= 0 //crossunder(pos, -0.5)
    stop_level_short = strategy.position_avg_price + nLoss
if pos == 0    
    stop_level_long = bodymin - nLoss
    stop_level_short = bodymax + nLoss

//plot(bodymax + nLoss, color=red)
//plot(bodymin - nLoss, color=red)
plot(stop_level_long, color=red)
plot(stop_level_short, color=red)

if upsign
    strategy.entry("Long", strategy.long, needlong == false ? 0 : lot)

if dnsign
    strategy.entry("Short", strategy.short, needshort == false ? 0 : na)

if true
    strategy.close_all()


//if strategy.position_size != 0
//    strategy.exit("Exit Long", from_entry = "Long", stop = stop_level_long)
//    strategy.exit("Exit Short", from_entry = "Short", stop = stop_level_short)

Больше