2つの移動平均線を捕捉する戦略

作者: リン・ハーンチャオチャン開催日:2023年12月13日15時28分50秒
タグ:

img

概要

この戦略は,市場傾向の方向性を決定するために2つの移動平均線を使用し,ボリンジャー帯を組み合わせて,低価格で購入し,高価格で販売し,利益を得ることを目的として,過剰購入と過剰売却の条件を特定します.

戦略の論理

この戦略は,市場全体の方向性を確かめるために二重移動平均を使用し,特定のエントリー信号のためにボリンジャーバンドに依存します.

二重移動平均法則は,短期間の指数関数移動平均線と長期間の指数関数移動平均線を計算することを規定しており,短期間の線が長期間の線を上向きに横切ると購入信号を示し,短期間の線が長期間の線を下向きに横切ると販売信号を構成する.

ボリンジャーバンド指標は,価格が過買いまたは過売れているかどうかを決定する.ボリンジャーバンドの中央帯はn期間の閉店価格の移動平均線であり,帯幅は過去n期間の移動平均値の標準偏差を表します.上部帯に近づく価格は過買い状態を示し,下部帯に近づく価格は過売状態を構成します.

戦略規則は以下のように定義されています. ショート平均線がロング平均線を上向きに横切ると,ボーリンガー上部帯を突破した閉値が加わると,ロングになります.ショートラインがロングラインを下向きに横切ると,ボーリンガー下部帯を下回る閉値が加わると,ショートになります.

ロング後ストップロスは過去 n 日間の最低値に設定され,テイクプロフィートはエントリー価格の 1.6 倍に設定されます.ショートセール後のストップロスは過去 n 日間の最高値に固定され,テイクプロフィートはエントリー価格の 0.6 倍に設定されます.

さらに,戦略では,トレンド逆転を避けるために,EMAトレンドインデックスも考慮しています.

利点分析

  1. 総方向性を決定するために二重移動平均を用い,特定のエントリーポイントを強調するためにボリンジャー帯を組み合わせると,合理的な指標の組み合わせを示します.
  2. 長期取引では最低値がストップ損失であり,ショート取引では最高値がストップ損失である場合,ストップ損失の可能性を減少させる.
  3. 収益目標の1.6倍を導入価格に設定することで,十分な利益を得ることが容易になります.
  4. EMAトレンドインデックスは,主要なトレンドに対する取引を回避し,システム損失を減らすのに役立ちます.

リスク分析

  1. ボリンジャー・バンドのパラメータを不適切に最適化すると,取引頻度が過度に高くなり,信号が不十分になる可能性があります.
  2. 過剰に緩いストップ・ロスは,より大きな損失を招く.
  3. 利得制限が過度に厳しくなった場合 より大きな利益が失われます

上記のリスクに対処するために,ボリンジャーパラメータの組み合わせを最適化し,最適な設定を選択するために,異なるストップ・ロース/プロフィートキャプチャの値レベルをテストします.

最適化方向

  1. Bollinger Bands の入力パラメータを最適化して理想的な組み合わせを特定する.
  2. ストップ損失増幅の様々なパラメータを調査し,ストップが実行される可能性を減らす.
  3. 利得倍数値を取って 最大の利益を得られるようにします

結論

この戦略は,デュアル移動平均値を使用して全体的なトレンドを確認し,特定のエントリー信号のためにボリンジャー帯に依存することで,バックテストで信頼性のあるパフォーマンスを発揮しています. 継続的なパラメータ最適化とルール修正により,追加のパフォーマンス改善が予想されます. ストップ損失/利益取りメカニズムは,適応のために他のシステムにも転送できます.


/*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)

もっと