Количественная торговая стратегия с колеблющейся линией K


Дата создания: 2023-09-26 20:05:55 Последнее изменение: 2023-09-26 20:05:55
Копировать: 0 Количество просмотров: 724
1
Подписаться
1617
Подписчики

Обзор

Эта стратегия является динамической стратегией, основанной на показателях, используя индикаторы осцилляторов, таких как RSI, Stoch и MACD, для создания стратегических торговых сигналов. Основная идея стратегии заключается в том, чтобы использовать индикаторы для определения направления тенденции при возникновении колебаний в ценах и вводить в действие в соответствии с индикаторными сигналами.

Стратегический принцип

Эта стратегия сначала вызывает пользовательскую функцию f_getOscilatorValues, чтобы получить значения различных показателей осцилляторов, включая RSI, Stoch, MACD и т. Д. Затем, с помощью функции f_getSupertrend, вычисляется значение задержки сверхтенденциального показателя, используемого для отслеживания стоп-стопов.

После вычисления индикатора, стратегия вызывает функцию f_getBuySellStops, которая вычисляет входные и стоп-стопы в зависимости от значения индикатора. В частности, она вычисляет индикатор ATR и использует ATR, умноженный на коэффициент стоп-стопа в качестве входного стоп-стопа, и ATR, умноженный на коэффициент стоп-стопа в качестве стоп-стопа.

Затем стратегия определяет физическое направление K-линии, если она является восходящей K-линией, то она изображена в зеленом цвете, а понижающая K-линия изображена в красном цвете. После изображения K-линии и индикатора стратегия определяет, соответствует ли она условиям входа. Условия входа заключаются в том, что, когда индикатор показывает перекуп, цена делает больше, когда она пробивается вверх; когда индикатор показывает перепродажу, цена делает пустоту, когда она пробивается вниз.

После входа, стоп-стоп будет отслеживаться, отслеживать стоп-стоп будет вверх или вниз, whichever is closer. Когда стоп-стоп был вызван, после этого он был снят.

Анализ преимуществ стратегии

Эта стратегия имеет следующие преимущества:

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

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

  3. В зависимости от рисков ATR, можно динамически регулировать размер позиции.

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

  5. Стратегия частичного остановки, позволяющая сохранить прибыль и заблокировать часть прибыли

  6. Стратегическая концепция проста, понятна, легко понятна и подходит для новичков в количественной торговле.

Анализ стратегических рисков

Однако эта стратегия также несет в себе некоторые риски:

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

  2. Приближаясь к точке остановки, возможен прорыв остановки. Можно соответствующим образом расширить диапазон остановки или использовать динамическую стратегию остановки, такую как Chandelier Stop.

  3. После частичного остановки оставшаяся позиция может быть остановлена. Можно снизить пропорцию частичного остановки, чтобы оставить место.

  4. Риск обратной совместимости данных. Необходимо многократно проверять данные на разных рынках, чтобы избежать пересоответствия.

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

Направление оптимизации стратегии

Эта стратегия может быть оптимизирована в следующих аспектах:

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

  2. Попробуйте перевести частичный тормоз в движущийся тормоз и установить положение тормоза в соответствии с ATR или движущейся средней.

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

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

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

  6. Добавление модуля управления ветром с помощью машинного обучения, динамическая оптимизация стоп-поста, стоп-стажировки, позиционирования и т. Д.

  7. Добавление торговых сигналов треугольного арбитража или срочного арбитража, чтобы получить прибыль от разницы в цене между фьючерсами и наличными товарами.

Подвести итог

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

Исходный код стратегии
/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Oscilator candles - strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"])
length = input(3)
shortlength = input(3)
longlength = input(9)

showSupertrend = input(true)
AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(30, step=10)
stopMultiplier  = input(4)
targetMultiplier  = input(3)
wicks = input(true)
considerWicksForDelayByStep = input(false)
colorByPreviousClose = input(true)

useHTFPivot = input(false)
resolution = input("12M", type=input.resolution)
HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1)
PivotLength = input(2, step=1)

tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time)
i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time)
inDateRange = true

f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=>
    oOpen = rsi(open, length)
    oClose = rsi(close, length)
    oHigh = rsi(high, length)
    oLow = rsi(low, length)
    if(oscilatorType == "tsi")
        oOpen := tsi(open, shortlength, longlength)
        oClose := tsi(close, shortlength, longlength)
        oHigh := tsi(high, shortlength, longlength)
        oLow := tsi(low, shortlength, longlength)
    if(oscilatorType == "stoch")
        oOpen := stoch(open, longlength, shortlength, length)
        oClose := stoch(close, longlength, shortlength, length)
        oHigh := stoch(high, longlength, shortlength, length)
        oLow := stoch(low, longlength, shortlength, length)
    if(oscilatorType == "cci")
        oOpen := cci(open, length)
        oClose := cci(close, length)
        oHigh := cci(high, length)
        oLow := cci(low, length)
    if(oscilatorType == "cog")
        oOpen := cog(open, length)
        oClose := cog(close, length)
        oHigh := cog(high, length)
        oLow := cog(low, length)
    if(oscilatorType == "cmo")
        oOpen := cmo(open, length)
        oClose := cmo(close, length)
        oHigh := cmo(high, length)
        oLow := cmo(low, length)
    if(oscilatorType == "mfi")
        oOpen := mfi(open, length)
        oClose := mfi(close, length)
        oHigh := mfi(high, length)
        oLow := mfi(low, length)
    if(oscilatorType == "macd")
        [macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length)
        [macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length)
        [macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length)
        [macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length)
        oOpen := macdLineOpen
        oClose := macdLineClose
        oHigh := macdLineHigh
        oLow := macdLineLow
    [oOpen, oClose, oHigh, oLow]

f_getMovingAverage(source, MAType, length)=>
    ma = sma(source, length)
    if(MAType == "ema")
        ma := ema(source,length)
    if(MAType == "hma")
        ma := hma(source,length)
    if(MAType == "rma")
        ma := rma(source,length)
    if(MAType == "vwma")
        ma := vwma(source,length)
    if(MAType == "wma")
        ma := wma(source,length)
    ma

f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=>
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
    atr = averagetruerange * stopMultiplier

    longStop = oClose - atr
    longStopPrev = nz(longStop[1], longStop)
    longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop
    
    shortStop = oClose + atr
    shortStopPrev = nz(shortStop[1], shortStop)
    shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop
    
    dir = 1
    dir := nz(dir[1], dir)
    dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir
    
    trailingStop = dir == 1? longStop : shortStop
    
    [dir, trailingStop]


f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=>
    barState = 0
    source = oClose
    
    truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
    
    atr = f_getMovingAverage(truerange, AtrMAType, AtrLength)

    buyStop = source - atr * stopMultiplier
    sellStop = source + atr * stopMultiplier
    buyStopDerived = buyStop
    sellStopDerived = sellStop
    highTarget = considerWicks ? oHigh : source
    lowTarget = considerWicks ? oLow : source
    
    highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source
    lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source
    
    barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0)
    
    buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier
    sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier
    buyStop := source - atr * buyMultiplier
    sellStop := source + atr * sellMultiplier
    buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop
    sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop
    
    buyStopDerived := buyStop
    sellStopDerived := sellStop
    
    buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived
    sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived

    [buyStopDerived, sellStopDerived, barState]


f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off)

f_multiple_resolution(HTFMultiplier) => 
    target_Res_In_Min = timeframe.multiplier * HTFMultiplier * (
      timeframe.isseconds   ? 1. / 60. :
      timeframe.isminutes   ? 1. :
      timeframe.isdaily     ? 1440. :
      timeframe.isweekly    ? 7. * 24. * 60. :
      timeframe.ismonthly   ? 30.417 * 24. * 60. : na)

    target_Res_In_Min     <= 0.0417       ? "1S"  :
      target_Res_In_Min   <= 0.167        ? "5S"  :
      target_Res_In_Min   <= 0.376        ? "15S" :
      target_Res_In_Min   <= 0.751        ? "30S" :
      target_Res_In_Min   <= 1440         ? tostring(round(target_Res_In_Min)) :
      tostring(round(min(target_Res_In_Min / 1440, 365))) + "D"
    
f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=>
    derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution
    HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh)
    HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow)
    CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose)
    pivothi = pivothigh(HTFHigh, PivotLength, PivotLength)
    pivotlo = pivotlow(HTFLow, PivotLength, PivotLength)
    pivothi := na(pivothi)? nz(pivothi[1]) : pivothi
    pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo
    [pivothi, pivotlo]
    
[oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength)
[dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)

candleColor = colorByPreviousClose ?
                 (oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) : 
                 (oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver)
plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor)

[buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)

trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived

plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red)

[pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength)

buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot)
exitBuyConditin = (barState == -1)
sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot)
exitSellCondition = (barState == 1)

// strategy.risk.allow_entry_in(tradeDirection)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca")
strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca")
strategy.close("Buy", when = exitBuyConditin)
strategy.close( "Sell", when = exitSellCondition)