動向平均とキャンドルスティックパターンのトレンドフォロー戦略

作者: リン・ハーンチャオチャン,日付: 2024-02-02 17:53:43
タグ:

img

概要

この戦略は,トレンドの方向性を決定するために移動平均値とキャンドルスタイクパターンを組み合わせ,トレンドの後のトレンドを実装するために,潜在的な逆転点を特定する.戦略は,まず移動平均値を利用して全体的なトレンド方向を判断し,その後トレンドの方向に沿ったエントリー信号として潜在的な逆転キャンドルスタイクパターンを探します.

戦略原則

この戦略は,価格傾向を決定するために10日間の単純な移動平均値を採用する.価格が移動平均値を超える場合,上昇傾向にあり,移動平均値を下回る場合,下落傾向にあると考えられる.

トレンド方向を決定した後,戦略は,多種多様な上昇傾向と下落傾向のキャンドルスティックパターンに基づいて,潜在的なトレンド逆転点を判断する.一般的な上昇傾向パターンには,モーニングスター,ブリーッシュ・エングルフィング,三人のホワイト・ソルジャーなど;一般的な下落傾向パターンには,イブニングスター,三人のブラック・クロウなどが含まれます.上昇傾向で上昇信号が特定された場合,戦略は購入注文をします.下落傾向で下落信号が特定された場合,戦略は販売注文をします.

さらに,戦略は,特定のエントリー価格を決定するために主要なサポートとレジスタンスレベルも組み込む.例えば,上昇傾向で購入する場合,最初のサポートレベルを突破すると購入します.

利点

この戦略の最大の利点は,トレンド判断と逆転シグナルの両方を組み合わせて,トレンドのターニングポイントをタイムリーに把握してトレンドをフォローできるようにすることです.単純な移動平均戦略と比較して,この戦略は収益性を大幅に向上させることができます.

また,キャンドルスタイクパターンの判断を組み込むことで,突然のイベントに対処する能力も向上します.低確率のイベントが市場で偽のブレイクを引き起こす場合,キャンドルスタイクパターンは間違った取引を避けるためのフィルターとしての役割を果たします.

リスク

この戦略の主なリスクは,移動平均パラメータ設定の正確性とキャンドルスタイルのパターン判断にあります.移動平均期間が正しく設定されていない場合,誤ったトレンド決定につながります.キャンドルスタイルのパターンの判断にエラーがある場合,間違った取引決定につながります.

さらに,逆転キャンドルスタイクパターンは100%確実でトレンド逆転を保証することはできません.したがって,戦略にはまだいくつかのリスクがあります.市場が大きな逆転を見るとき,戦略に大きな損失をもたらす可能性があります.

オプティマイゼーションの方向性

この戦略には依然として最適化のためのかなりの余地があります.例えば,移動平均のパラメータを動的に調整し,異なる市場段階で異なる移動平均期間を採用することを検討できます.また,判断の正確性を向上させるために,歴史的なデータを使用してキャンドルスタイプパターン判断モデルを訓練するための機械学習方法を導入することができます.

さらに,トレンドやホットエリアを判断するためのより多くの要因,例えば取引量の変化,変動指標なども考慮し,戦略をより包括的で堅牢なものにすることができます.

結論

一般的には,この戦略は株式市場の中期トレンドを追跡するのに非常に適しており,比較的高く安定した収益を得ることができます.さらに最適化されれば,うまく機能する定量戦略になる可能性があります.投資家がこの戦略の使用を理解すれば,より良い過剰収益を得ながら個々の株式リスクを制御するために長期保有を構築するためにも使用できます.


/*backtest
start: 2024-01-01 00:00:00
end: 2024-01-31 23:59:59
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy("Trend Following Strategy with Candlestick Patterns", overlay=true)

// Moving Average
ma_period = input(10, title="Moving Average Period")
moving_average = ta.sma(close, ma_period)

// Candlestick Patterns
// Custom Function
abs(x) => x >= 0 ? x : -x

// Candlestick Patterns
isDoji() =>
    (close - open) <= (high - low) * 0.1

isMarubozuWhite() =>
    close == high and open == low and close > open

isHammer() =>
    (high - low) >= 3 * abs(open - close) and (close - low) / (0.001 + high - low) > 0.6 and (open - low) / (0.001 + high - low) > 0.6

isInvertedHammer() =>
    (high - low) >= 3 * abs(open - close) and (high - close) / (0.001 + high - low) > 0.6 and (high - open) / (0.001 + high - low) > 0.6

isLongLowerShadow() =>
    (low - close) > 2 * abs(open - close) and (low - open) / (0.001 + high - low) > 0.6

isUpsideTasukiGap() =>
    close[1] < open[1] and open > close and open > close[1] and close < open[1]

isRisingWindow() =>
    high[1] < low and close > open

isPiercing() =>
    close[1] < open[1] and close > open and close > ((open + low) / 2) and close < open[1] and open < close[1]

isBullishEngulfing() =>
    close[1] < open[1] and close > open and high > high[1] and low < low[1]

isTweezerBottom() =>
    low == ta.valuewhen(low == ta.lowest(low, 10), low, 0) and low == ta.valuewhen(low == ta.lowest(low, 20), low, 0)

isBullishAbandonedBaby() =>
    close[2] < open[2] and close[1] > open[1] and low[1] > ta.valuewhen(high == ta.highest(high, 2), high, 0) and open > close and close > ta.valuewhen(high == ta.highest(high, 2), high, 0)

isMorningStar() =>
    close[2] < open[2] and close[1] < open[1] and close > open[1] and open < close[2] and open > close[1]

isMorningDojiStar() =>
    close[2] < open[2] and close[1] < open[1] and isDoji() and close > open[1] and open < close[2] and open > close[1]

isDragonflyDoji() =>
    isDoji() and (high - close) / (0.001 + high - low) < 0.1 and (open - low) / (0.001 + high - low) > 0.6

isThreeWhiteSoldiers() =>
    close[2] < open[2] and close[1] < open[1] and close > open and open < close[2] and open < close[1] and close > open[1]

isRisingThreeMethods() =>
    close[4] < open[4] and close[1] < open[1] and close > open and open < close[4] and open < close[1] and close > open[1]

isMarubozuBlack() =>
    close == low and open == high and open > close

isGravestoneDoji() =>
    isDoji() and (close - low) / (0.001 + high - low) < 0.1 and (high - open) / (0.001 + high - low) > 0.6

isHangingMan() =>
    (high - low) >= 4 * abs(open - close) and (open - close) / (0.001 + high - low) > 0.6 and (high - open) / (0.001 + high - low) > 0.6

isLongUpperShadow() =>
    (high - open) > 2 * abs(open - close) and (high - close) / (0.001 + high - low) > 0.6

isDownsideTasukiGap() =>
    close[1] > open[1] and open < close and open < close[1] and close > open[1]

isFallingWindow() =>
    low[1] > high and close < open

isDarkCloudCover() =>
    close[1] > open[1] and close < open and close < ((open + high) / 2) and close > open[1] and open > close[1]

isBearishEngulfing() =>
    close[1] > open[1] and close < open and high > high[1] and low < low[1]

isTweezerTop() =>
    high == ta.valuewhen(high == ta.highest(high, 10), high, 0) and high == ta.valuewhen(high == ta.highest(high, 20), high, 0)

isAbandonedBaby() =>
    close[2] > open[2] and close[1] < open[1] and high[1] < ta.valuewhen(low == ta.lowest(low, 2), low, 0) and open < close and close < ta.valuewhen(low == ta.lowest(low, 2), low, 0)

isEveningDojiStar() =>
    close[2] > open[2] and close[1] > open[1] and isDoji() and close < open[1] and open > close[2] and open < close[1]

isEveningStar() =>
    close[2] > open[2] and close[1] > open[1] and close < open[1] and open > close[2] and open < close[1]

isThreeBlackCrows() =>
    close[2] > open[2] and close[1] > open[1] and close < open and open > close[2] and open > close[1] and close < open[1]

isFallingThreeMethods() =>
    close[4] > open[4] and close[1] > open

isShootingStar() =>
    (high - low) >= 3 * abs(open - close) and (high - close) / (0.001 + high - low) > 0.6 and (high - open) / (0.001 + high - low) > 0.6

doji = isDoji()
marubozuWhite = isMarubozuWhite()
hammer = isHammer()
invertedHammer = isInvertedHammer()
longLowerShadow = isLongLowerShadow()
upsideTasukiGap = isUpsideTasukiGap()
risingWindow = isRisingWindow()
piercing = isPiercing()
bullishEngulfing = isBullishEngulfing()
tweezerBottom = isTweezerBottom()
bullishAbandonedBaby = isBullishAbandonedBaby()
morningStar = isMorningStar()
morningDojiStar = isMorningDojiStar()
dragonflyDoji = isDragonflyDoji()
threeWhiteSoldiers = isThreeWhiteSoldiers()
risingThreeMethods = isRisingThreeMethods()
marubozuBlack = isMarubozuBlack()
gravestoneDoji = isGravestoneDoji()
hangingMan = isHangingMan()
longUpperShadow = isLongUpperShadow()
downsideTasukiGap = isDownsideTasukiGap()
fallingWindow = isFallingWindow()
darkCloudCover = isDarkCloudCover()
bearishEngulfing = isBearishEngulfing()
tweezerTop = isTweezerTop()
abandonedBaby = isAbandonedBaby()
eveningDojiStar = isEveningDojiStar()
eveningStar = isEveningStar()
threeBlackCrows = isThreeBlackCrows()
fallingThreeMethods = isFallingThreeMethods()
shootingStar = isShootingStar()
isBullishPattern() =>
    (isMarubozuWhite() or isHammer() or isInvertedHammer() or isDoji() or isMorningStar() or isBullishEngulfing() or isThreeWhiteSoldiers() or isMarubozuBlack() or isHangingMan() or isDownsideTasukiGap() or isDarkCloudCover())

isBearishPattern() =>
    (isMarubozuBlack() or isInvertedHammer() or isLongUpperShadow() or isTweezerTop() or isGravestoneDoji() or isEveningStar() or isBearishEngulfing() or isThreeBlackCrows() or isShootingStar())

isBullishCandle = isBullishPattern()
isBearishCandle = isBearishPattern()

// Calculate Pivot Points
pivotPoint(high, low, close) =>
    (high + low + close) / 3

r1 = pivotPoint(high[1], low[1], close[1]) * 2 - low[1]
s1 = pivotPoint(high[1], low[1], close[1]) * 2 - high[1]

r2 = pivotPoint(high[1], low[1], close[1]) + (high[1] - low[1])
s2 = pivotPoint(high[1], low[1], close[1]) - (high[1] - low[1])

r3 = high[1] + 2 * (pivotPoint(high[1], low[1], close[1]) - low[1])
s3 = low[1] - 2 * (high[1] - pivotPoint(high[1], low[1], close[1]))
// Trend Identification
is_uptrend = close > moving_average
is_downtrend = close < moving_average
// Entry and Exit Conditions with Trend Identification
enterLong = is_uptrend and isBullishCandle and close > r1
exitLong = is_uptrend and (bearishEngulfing or doji or close < s1)

enterShort = is_downtrend and isBearishCandle and close < s1
exitShort = is_downtrend and (bullishEngulfing or doji or close > r1)



// Strategy Execution
if enterLong and strategy.position_size == 0 and strategy.position_size[1] == 0 and close > r1
    strategy.entry("Buy", strategy.long, qty=1)

if exitLong and strategy.position_size > 0
    strategy.close("Buy")

if enterShort and strategy.position_size == 0 and close < s1
    strategy.entry("Sell", strategy.short, qty=1)

if exitShort and strategy.position_size < 0
    strategy.close("Sell")


// Stop-Loss and Trailing Stop-Loss
stop_loss_pct = input(2.0, title="Stop Loss Percentage")
trailing_stop_loss_pct = input(1.0, title="Trailing Stop Loss Percentage")
trailing_stop_loss_active = input(true, title="Trailing Stop Loss Active")

// Stop-Loss
stop_loss_level = strategy.position_avg_price * (1 - stop_loss_pct / 100)
strategy.exit("Stop Loss", "Buy", loss=stop_loss_level)

// Trailing Stop-Loss


// Plotting Moving Average
plot(moving_average, color=color.blue, title="Moving Average", linewidth=2)

// Plotting Candlestick Patterns
plotshape(isBullishCandle, title="Bullish Candle", location=location.belowbar, color=color.green, style=shape.labelup)
plotshape(isBearishCandle, title="Bearish Candle", location=location.abovebar, color=color.red, style=shape.labeldown)

// Plotting Support and Resistance Levels
//hline(r1, "Resistance Level 1", color=color.red, linestyle=hline.style_dotted)
//hline(s1, "Support Level 1", color=color.green, linestyle=hline.style_dotted)


もっと