Количественная торговая стратегия пересечения трех скользящих средних + индикатор Уильяма


Дата создания: 2023-09-28 10:58:16 Последнее изменение: 2023-09-28 10:58:16
Копировать: 1 Количество просмотров: 833
1
Подписаться
1617
Подписчики

Обзор

Эта стратегия использует три скользящих средних, относительно сильный индекс (RSI) и индекс Уильямса, чтобы определить направление тренда цены акций и найти возможности для входа в то время, когда тенденция меняется. Когда три медленные средние движущиеся вверх (вниз) выравниваются, RSI выше (ниже) 50 и появляется сигнал Уильямса вниз (вверх), делайте больше (пустые). Стоп-убыток устанавливается на определенный процент от цены входа, а стоп-остановка - на определенный процент от цены входа.

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

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

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

  1. Все скоростные, средние и медленные линии - вверх.
  2. RSI выше 50;
  3. В результате, мы получили более высокие результаты, чем мы ожидали.
  4. Например, в Китае, в Китае, в Китае, в Китае.
  5. В настоящее время нет.

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

  1. Все скоростные, средние и медленные линии обращены вниз.
  2. RSI ниже 50;
  3. Показатель Уильяма вверх;
  4. В результате, цены на акции снизились.
  5. В настоящее время нет.

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

Стратегические преимущества

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

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

  3. Логика стратегии четкая и понятная, параметры настроены разумно, подходит для использования трейдерами разных уровней.

Стратегический риск

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

  2. Стремительный пересечение между линиями может привести к ложному прорыву, и его следует использовать в сочетании с другими показателями. Можно рассмотреть возможность включения показателя загрузки.

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

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

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

  1. Можно тестировать комбинации параметров различных циклов, оптимизировать три средних линии и параметры RSI.

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

  3. Параметры стратегии могут быть настроены для тестирования в зависимости от разных сортов.

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

  5. Можно попробовать провести симуляцию сделок до запуска, оптимизировать параметры.

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

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

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

//This script is a combination of 3 smoothed moving averages, and RSI. When moving averages are aligned upward (downward) and RSI is above (below) 50 and a down (up) William fractal appears, it enters long (short) position. Exiting from long and short entries are defined by StopLoss and TargetProfit.

//@version=5

strategy(title="3SmmaCrossUp + Fractal + RSI", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, currency=currency.USD, commission_type=strategy.commission.percent, commission_value=0.03)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// inputs

// Global
src = input(close, title="Source")
stopLoss = input.float(defval = 0.1, title = "Stop Loss %", minval = 0, maxval=100, step = 0.1)
targetProfit = input.float(defval = 0.4, title = "Target Profit %", minval = 0, maxval=100, step = 0.1)

// Smooth Moving Average
fastSmmaLen = input.int(21, minval=1, title="Fast Length", group = "Smooth Moving Average")
midSmmaLen = input.int(50, minval=1, title="Mid Length",group = "Smooth Moving Average")
slowSmmaLen = input.int(200, minval=1, title="Slow Length",group = "Smooth Moving Average")

// RSI
rsiLen = input.int(defval=14, title="length", minval=1, maxval=1000, step=1, group="RSI")

// Fractals
n = input.int(title="Periods", defval=2, minval=2, group = "Fractals")

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// initialization

var waitingFirstTradeInUpwardTrend = false
var waitingFirstTradeInDownwardTrend = false

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// functions

smma(ma, src, len) => 
    smma = 0.0
    smma := na(smma[1]) ? ma : (smma[1] * (len - 1) + src) / len
    smma
    
fractals(n, highs, lows) =>
    // UpFractal
    bool upflagDownFrontier = true
    bool upflagUpFrontier0 = true
    bool upflagUpFrontier1 = true
    bool upflagUpFrontier2 = true
    bool upflagUpFrontier3 = true
    bool upflagUpFrontier4 = true
    for i = 1 to n
        upflagDownFrontier := upflagDownFrontier and (highs[n-i] < highs[n])
        upflagUpFrontier0 := upflagUpFrontier0 and (highs[n+i] < highs[n])
        upflagUpFrontier1 := upflagUpFrontier1 and (highs[n+1] <= highs[n] and highs[n+i + 1] < highs[n])
        upflagUpFrontier2 := upflagUpFrontier2 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+i + 2] < highs[n])
        upflagUpFrontier3 := upflagUpFrontier3 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+i + 3] < highs[n])
        upflagUpFrontier4 := upflagUpFrontier4 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+4] <= highs[n] and highs[n+i + 4] < highs[n])
    flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4
    
    upFractal = (upflagDownFrontier and flagUpFrontier)
    
    // downFractal
    bool downflagDownFrontier = true
    bool downflagUpFrontier0 = true
    bool downflagUpFrontier1 = true
    bool downflagUpFrontier2 = true
    bool downflagUpFrontier3 = true
    bool downflagUpFrontier4 = true
    
    for i = 1 to n
        downflagDownFrontier := downflagDownFrontier and (lows[n-i] > lows[n])
        downflagUpFrontier0 := downflagUpFrontier0 and (lows[n+i] > lows[n])
        downflagUpFrontier1 := downflagUpFrontier1 and (lows[n+1] >= lows[n] and lows[n+i + 1] > lows[n])
        downflagUpFrontier2 := downflagUpFrontier2 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+i + 2] > lows[n])
        downflagUpFrontier3 := downflagUpFrontier3 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+i + 3] > lows[n])
        downflagUpFrontier4 := downflagUpFrontier4 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+4] >= lows[n] and lows[n+i + 4] > lows[n])
    flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4
    
    downFractal = (downflagDownFrontier and flagDownFrontier)
    [upFractal, downFractal]

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// calcs

[upFractal, downFractal] = fractals(n, high, low)


rsiIsHigh = ta.rsi(src, rsiLen) >= 50 


slowMa = ta.sma(src, slowSmmaLen)
midMa = ta.sma(src, midSmmaLen)
fastMa = ta.sma(src, fastSmmaLen)

slowSmma = smma(slowMa ,src, slowSmmaLen)
midSmma = smma(midMa, src, midSmmaLen)
fastSmma = smma(fastMa, src, fastSmmaLen)

isFastSmmaUpward = ta.rising(fastSmma, 1)
isMidSmmaUpward = ta.rising(midSmma, 1)
isSlowSmmaUpward = ta.rising(slowSmma, 1)

isFastSmmaDownward = ta.falling(fastSmma, 1)
isMidSmmaDownward = ta.falling(midSmma, 1)
isSlowSmmaDownward = ta.falling(slowSmma, 1)

slowMovingAveragesAreUpward = isMidSmmaUpward and isSlowSmmaUpward
slowMovingAveragesAreDownward = isMidSmmaDownward and isSlowSmmaDownward

justEnteredUpwardTrend = ta.crossover(fastSmma, midSmma) ? true : false
justEnteredDownwardTrend = ta.crossunder(fastSmma, midSmma) ? true : false

waitingFirstTradeInUpwardTrend := justEnteredUpwardTrend == true ? true : (isFastSmmaDownward or isMidSmmaDownward or isSlowSmmaDownward ? false : waitingFirstTradeInUpwardTrend)
waitingFirstTradeInDownwardTrend := justEnteredDownwardTrend == true ? true : (isFastSmmaUpward or isMidSmmaUpward or isSlowSmmaUpward ? false : waitingFirstTradeInDownwardTrend)

priceCrossedOverSlowMa = ta.crossover(close, slowSmma)
priceCrossedUnderSlowMa = ta.crossunder(close, slowSmma)

enterLongCondition = barstate.isconfirmed and low > fastSmma and rsiIsHigh and (downFractal or priceCrossedOverSlowMa) and waitingFirstTradeInUpwardTrend and strategy.position_size == 0

enterShortCondition = barstate.isconfirmed and high < fastSmma and (not rsiIsHigh) and (upFractal or priceCrossedUnderSlowMa) and waitingFirstTradeInDownwardTrend and strategy.position_size == 0

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// strategy

if(enterLongCondition)
    strategy.entry(id="L", direction=strategy.long)
    waitingFirstTradeInUpwardTrend := false

if(enterShortCondition)
    strategy.entry(id="S", direction=strategy.short)
    waitingFirstTradeInDownwardTrend := false
    
if(strategy.position_size > 0)
    strategy.exit(id="EL", stop=strategy.position_avg_price * (1 - stopLoss/100), limit=strategy.position_avg_price * (1+targetProfit/100)) 
if(strategy.position_size < 0)
    strategy.exit(id="ES", stop=strategy.position_avg_price * (1 + stopLoss/100), limit=strategy.position_avg_price * (1-targetProfit/100)) 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// plots

plot(series = slowSmma, title="Slow SMMA", linewidth=3)
plot(series = midSmma, title="Mid SMMA", linewidth=2)
plot(series = fastSmma, title="Fast SMMA", linewidth=1)
plotchar(series=rsiIsHigh, title='rsiIsHigh', char='')
plotchar(series=justEnteredUpwardTrend, title='justEnteredUpwardTrend', char='')
plotchar(series=justEnteredDownwardTrend, title='justEnteredDownwardTrend', char='')
plotchar(series=waitingFirstTradeInUpwardTrend, title='waitingFirstTradeInUpwardTrend', char='')
plotchar(series=waitingFirstTradeInDownwardTrend, title='waitingFirstTradeInDownwardTrend', char='')
plotchar(series=enterLongCondition, title='enterLongCondition' , char='')
plotchar(series=enterShortCondition, title='enterShortCondition' , char='')
plotshape(series=upFractal, title='upFractal', style=shape.triangleup, location=location.abovebar, color=#009688, size = size.tiny)
plotshape(series=downFractal, title='downFractal', style=shape.triangledown, location=location.belowbar, color=color.red, size = size.tiny)