이 전략은 이중 이동 평균 라인을 사용하여 시장 트렌드 방향을 결정하고 볼링거 밴드를 사용하여 과잉 구매 및 과잉 판매 조건을 식별하여 수익을 얻기 위해 낮은 구매와 높은 판매를 달성합니다.
이 전략은 시장의 전반적인 방향을 확인하기 위해 이중 이동 평균을 사용하며 특정 입시 신호를 위해 볼링거 밴드 (Bollinger Band) 에 의존합니다.
이중 이동 평균 규칙은 단기 및 장기 지수 이동 평균 라인을 계산하도록 규정하고 있으며, 단기 라인이 장기 라인을 상향으로 가로 지르면 구매 신호를 나타냅니다. 단기 라인이 장기 라인을 상향으로 가로 지르면 판매 신호를 구성합니다.
볼링거 밴드 지표는 가격이 과잉 구매 또는 과잉 판매되는지를 결정합니다. 볼링거 밴드의 중간 밴드는 n 기간 종료 가격의 이동 평균 라인이며, 밴드 폭은 지난 n 기간 동안 이동 평균의 표준 편차를 나타냅니다. 상단 지대에 접근하는 가격은 과잉 구매 상태를 나타냅니다. 하단 지대에 접근하는 것은 과잉 판매 상황을 구성합니다.
전략 규칙은 다음과 같이 정의됩니다. 짧은 평균선이 긴 평균선을 상향으로 가로질러 닫기 가격과 볼링거 상단선을 넘을 때, 길게 가십시오. 짧은 라인이 긴 라인을 가로질러 하향으로 가로질러 닫기 가격과 볼링거 하단선을 넘을 때, 짧게 가십시오.
장기간 거래 후의 스톱 로스는 지난 n 일 동안 가장 낮은 수준으로 설정되며, 영업이익은 입시 가격의 1.6 배로 설정됩니다. 단편 판매 후의 스톱 로스는 지난 n 일 동안 가장 높은 수준에 고정되며, 영업이익은 입시 가격의 0.6 배로 설정됩니다.
또한 전략은 EMA 트렌드 인덱스를 고려하여 트렌드 반전을 피합니다.
위의 위험을 해결하기 위해 볼링거 매개 변수 조합을 최적화하고 최적의 설정을 선택하기 위해 다른 스톱 로스/프로프트 캡처 임계 수준을 테스트하십시오.
이 전략은 이중 이동 평균을 사용하여 전반적인 트렌드를 확인하고 특정 입시 신호에 볼링거 밴드를 의존함으로써 백테스트에서 신뢰성있게 수행되었습니다. 지속적인 매개 변수 최적화 및 규칙 수정으로 추가 성능 개선이 예상 될 수 있습니다. 스톱 손실 / 이익 취득 메커니즘은 또한 적응을 위해 다른 시스템에 이전 할 수 있습니다.
/*backtest start: 2023-12-05 00:00:00 end: 2023-12-06 22:00:00 period: 15m basePeriod: 5m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This close code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © AugustoErni //@version=5 strategy('Bollinger Bands Modified (Stormer)', overlay=true) bbL = input.int(20, title='BB Length/Comprimento da Banda de Bollinger', minval=1, step=1, tooltip='Calculate the length of bollinger bands./Calcula o comprimento das bandas de bollinger.') mult = input.float(0.38, title='BB Standard Deviation/Desvio Padrão da Banda de Bollinger', minval=0.01, step=0.01, tooltip='Calculate the standard deviation of bollinger bands./Calcula o desvio padrão das bandas de bollinger.') emaL = input.int(80, title='EMA Length/Comprimento da Média Móvel Exponencial', minval=1, step=1, tooltip='Calculate the length of EMA./Calcula o comprimento da EMA.') highestHighL = input.int(7, title='Highest High Length/Comprimento da Alta Maior', minval=1, step=1, tooltip='Fetches the highest high candle from length input. Use to set stop loss for short position./Obtém a vela de maior alta com base na medida fornecida. Usa para definir o stop loss para uma posição curta.') lowestLowL = input.int(7, title='Lowest Low Length/Comprimento da Baixa Menor', minval=1, step=1, tooltip='Fetches the lowest low candle from length input. Use to set stop loss for long position./Obter a vela de menor baixa com base na medida fornecida. Usa para definir o stop loss para uma posição longa.') targetFactor = input.float(1.6, title='Target Take Profit/Objetivo de Lucro Alvo', minval=0.1, step=0.1, tooltip='Calculate the take profit factor when entry position./Calcula o fator do alvo lucro ao entrar na posição.') emaTrend = input.bool(true, title='Check Trend EMA/Verificar Tendência da Média Móvel Exponencial', tooltip='Use EMA as trend verify for opening position./Usa a EMA como verificação de tendência para abrir posição.') crossoverCheck = input.bool(false, title='Add Another Crossover Check/Adicionar Mais uma Verificação de Cruzamento Superior', tooltip='This option is to add one more veryfication attempt to check if price is crossover upper bollinger band./Esta opção é para adicionar uma verificação adicional para avaliar se o preço cruza a banda superior da banda de bollinger.') crossunderCheck = input.bool(false, title='Add Another Crossunder Check/Adicionar Mais uma Verificação de Cruzamento Inferior', tooltip='This option is to add one more veryfication attempt to check if price is crossunder lower bollinger band./Esta opção é para adicionar uma verificação adicional para avaliar se o preço cruza a banda inferior da banda de bollinger.') insideBarPatternCheck = input.bool(true, title='Show Inside Bar Pattern/Mostrar Padrão de Inside Bar', tooltip='This option is to show possible inside bar pattern./Esta opção é para mostrar um possível padrão de inside bar.') [middle, upper, lower] = ta.bb(close, bbL, mult) ema = ta.ema(close, emaL) highestHigh = ta.highest(high, highestHighL) lowestLow = ta.lowest(low, lowestLowL) isCrossover = ta.crossover(close, upper) ? 1 : 0 isCrossunder = ta.crossunder(close, lower) ? 1 : 0 isPrevBarHighGreaterCurBarHigh = high[1] > high ? 1 : 0 isPrevBarLowLesserCurBarLow = low[1] < low ? 1 : 0 isInsideBar = isPrevBarHighGreaterCurBarHigh and isPrevBarLowLesserCurBarLow ? 1 : 0 isBarLong = ((close - open) > 0) ? 1 : 0 isBarShort = ((close - open) < 0) ? 1 : 0 isLongCross = crossoverCheck ? ((isBarLong and not isBarShort) and (open < upper and close > upper)) ? 1 : 0 : isCrossover ? 1 : 0 isShortCross = crossunderCheck ? ((isBarShort and not isBarLong) and (close < lower and open > lower)) ? 1 : 0 : isCrossunder ? 1 : 0 isCandleAboveEma = close > ema ? 1 : 0 isCandleBelowEma = close < ema ? 1 : 0 isLongCondition = emaTrend ? isLongCross and isCandleAboveEma ? 1 : 0 : isLongCross isShortCondition = emaTrend ? isShortCross and isCandleBelowEma ? 1 : 0 : isShortCross isPositionNone = strategy.position_size == 0 ? 1 : 0 isPositionLong = strategy.position_size > 0 ? 1 : 0 isPositionShort = strategy.position_size < 0 ? 1 : 0 var float enterLong = 0.0 var float stopLossLong = 0.0 var float targetLong = 0.0 var float enterShort = 0.0 var float stopLossShort = 0.0 var float targetShort = 0.0 var bool isLongEntry = false var bool isShortEntry = false if (isPositionNone) isLongEntry := false isShortEntry := false enterLong := 0.0 stopLossLong := 0.0 targetLong := 0.0 enterShort := 0.0 stopLossShort := 0.0 targetShort := 0.0 if (isPositionShort or isPositionNone) isLongEntry := false enterLong := 0.0 stopLossLong := 0.0 targetLong := 0.0 if (isPositionLong or isPositionNone) isShortEntry := false enterShort := 0.0 stopLossShort := 0.0 targetShort := 0.0 if (isPositionLong and isLongEntry) isLongEntry := true isShortEntry := false enterShort := 0.0 stopLossShort := 0.0 targetShort := 0.0 if (isPositionShort and isShortEntry) isShortEntry := true isLongEntry := false enterLong := 0.0 stopLossLong := 0.0 targetLong := 0.0 if (isLongCondition and not isLongEntry) isLongEntry := true enterLong := close stopLossLong := lowestLow targetLong := (enterLong + (math.abs(enterLong - stopLossLong) * targetFactor)) alertMessage = '{ "side/lado": "buy", "entry/entrada": ' + str.tostring(enterLong) + ', "stop": ' + str.tostring(stopLossLong) + ', "target/alvo": ' + str.tostring(targetLong) + ' }' alert(alertMessage) strategy.entry('Long', strategy.long) strategy.exit('Exit Long', 'Long', stop=stopLossLong, limit=targetLong) if (isShortCondition and not isShortEntry) isShortEntry := true enterShort := close stopLossShort := highestHigh targetShort := (enterShort - (math.abs(enterShort - stopLossShort) * targetFactor)) alertMessage = '{ "side/lado": "sell", "entry/entrada": ' + str.tostring(enterShort) + ', "stop": ' + str.tostring(stopLossShort) + ', "target/alvo": ' + str.tostring(targetShort) + ' }' alert(alertMessage) strategy.entry('Short', strategy.short) strategy.exit('Exit Short', 'Short', stop=stopLossShort, limit=targetShort) plot(upper, title='Upper Band', color=color.blue) plot(middle, title='Middle Band', color=color.gray) plot(lower, title='Lower Band', color=color.blue) plot(ema, title='EMA', color=color.white) barcolor(insideBarPatternCheck and isInsideBar and isBarLong ? color.lime : insideBarPatternCheck and isInsideBar and isBarShort ? color.maroon : na, title='Inside Bar Color in Long Bar Long and in Short Bar Short/Cor do Inside Bar em Barra Longa Longa e em Barra Curta Curta') tablePosition = position.bottom_right tableColumns = 2 tableRows = 5 tableFrameWidth = 1 tableBorderColor = color.gray tableBorderWidth = 1 tableInfoTrade = table.new(position=tablePosition, columns=tableColumns, rows=tableRows, frame_width=tableFrameWidth, border_color=tableBorderColor, border_width=tableBorderWidth) table.cell(table_id=tableInfoTrade, column=0, row=0) table.cell(table_id=tableInfoTrade, column=1, row=0) table.cell(table_id=tableInfoTrade, column=0, row=1, text='Entry Side/Lado da Entrada', text_color=color.white) table.cell(table_id=tableInfoTrade, column=0, row=2, text=isLongEntry ? 'LONG' : isShortEntry ? 'SHORT' : 'NONE/NENHUM', text_color=color.yellow) table.cell(table_id=tableInfoTrade, column=1, row=1, text='Entry Price/Preço da Entrada', text_color=color.white) table.cell(table_id=tableInfoTrade, column=1, row=2, text=isLongEntry ? str.tostring(enterLong) : isShortEntry ? str.tostring(enterShort) : 'NONE/NENHUM', text_color=color.blue) table.cell(table_id=tableInfoTrade, column=0, row=3, text='Take Profit Price/Preço Alvo Lucro', text_color=color.white) table.cell(table_id=tableInfoTrade, column=0, row=4, text=isLongEntry ? str.tostring(targetLong) : isShortEntry ? str.tostring(targetShort) : 'NONE/NENHUM', text_color=color.green) table.cell(table_id=tableInfoTrade, column=1, row=3, text='Stop Loss Price/Preço Stop Loss', text_color=color.white) table.cell(table_id=tableInfoTrade, column=1, row=4, text=isLongEntry ? str.tostring(stopLossLong) : isShortEntry ? str.tostring(stopLossShort) : 'NONE/NENHUM', text_color=color.red)