KDJ Trending View with Signals and MA Strategy

Author: ChaoZhang, Date: 2024-05-11 11:46:11



This strategy utilizes the KDJ indicator and Moving Average (MA) to identify market trends and generate trading signals. When the KDJ indicator exceeds the overbought level and the price breaks below the MA, a short signal is generated; when the KDJ indicator is below the oversold level and the price breaks above the MA, a long signal is generated. By combining the KDJ indicator with MA trend confirmation, this strategy can better capture market trends while avoiding false signals in ranging markets.

Strategy Principles

  1. Calculate the K, D, and J values of the KDJ indicator, where K is the N-day moving average of RSV, D is the M-day moving average of K, and J is calculated by the formula “3K-2D”.
  2. Calculate the Moving Average (MA) to determine the current price trend.
  3. Determine the direction of the MA, with a bullish signal when the price crosses above and a bearish signal when it crosses below.
  4. Generate a short signal when the J value of KDJ is greater than the overbought level and the price crosses below the MA; generate a long signal when the J value is less than the oversold level and the price crosses above the MA.
  5. Open fixed-size (1 unit) long or short positions based on the signals.


  1. Considers both overbought/oversold conditions and trend direction, allowing for better trend capturing.
  2. Uses MA as trend confirmation to effectively filter out false signals from the KDJ indicator in ranging markets.
  3. Includes adjustable overbought/oversold thresholds, increasing the flexibility of the strategy.
  4. The color of the moving average line changes based on trend direction, providing intuitive trend recognition.
  5. Plots trading signals on the chart for easy observation and analysis of strategy performance.


  1. The KDJ indicator is sensitive to parameters, and performance may vary significantly under different settings, requiring optimization for different instruments and timeframes.
  2. In ranging markets, even with MA as trend confirmation, the strategy may still generate numerous false signals, leading to losses.
  3. Fixed position sizing does not consider risk management and may take on significant risk during high market volatility.
  4. The strategy lacks stop-loss and take-profit mechanisms, potentially missing profit opportunities or magnifying losses.

Optimization Directions

  1. Optimize the parameters of the KDJ indicator to find the best combination suitable for the current instrument and timeframe.
  2. Introduce additional technical indicators such as RSI, MACD, etc., to enrich trend judgment and signal filtering conditions, improving signal quality.
  3. Optimize position management by dynamically adjusting position size based on market volatility or account equity to control risk.
  4. Add stop-loss and take-profit logic to close positions when predefined conditions are met, reducing single losses and locking in profits.
  5. Backtest and optimize the strategy to find the best parameter combinations and market adaptability.


By combining the KDJ indicator with moving averages, this strategy can effectively capture market trends and generate trading signals. Reasonable utilization of overbought/oversold information and trend direction can lead to robust trading performance. However, there is still room for optimization, such as introducing more filtering conditions, dynamic position management, stop-loss and take-profit, etc., to further enhance the strategy’s robustness and profitability. In practical application, the strategy needs to be fine-tuned and tested for different market environments and instruments to verify its effectiveness and applicability.

start: 2024-04-01 00:00:00
end: 2024-04-30 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]

strategy("KDJ Trending View with Signals and MA Strategy", overlay=true)

// KDJ Settings
kdjLength = input.int(9, title="KDJ Length")
kdjSignal = input.int(3, title="KDJ Signal")
kdjOverbought = input.int(80, title="KDJ Overbought Level")
kdjOversold = input.int(20, title="KDJ Oversold Level")

// Margin Settings
longMargin = input.float(2.0, title="Long Margin", step=0.01)
shortMargin = input.float(2.0, title="Short Margin", step=0.01)

// MA Settings
maLength = input.int(20, title="MA Length")
maType = input.string("SMA", title="MA Type (SMA, EMA, etc.)")

// Calculate KDJ
kdj_highest = ta.highest(high, kdjLength)
kdj_lowest = ta.lowest(low, kdjLength)
kdjRSV = 100 * ((close - kdj_lowest) / (kdj_highest - kdj_lowest))
kdjK = ta.sma(kdjRSV, kdjSignal)
kdjD = ta.sma(kdjK, kdjSignal)
kdjJ = 3 * kdjK - 2 * kdjD

// Calculate Moving Average
ma = ta.sma(close, maLength) // SMA kullanarak ortalama hesaplama

// Determine MA Direction
maCrossUp = ta.crossover(close, ma)
maCrossDown = ta.crossunder(close, ma)

// Plot MA with Direction Color Change
maColor = maCrossUp ? color.green : maCrossDown ? color.red : color.gray
plot(ma, color=maColor, title="Moving Average")

// Plot Trading Signals
plotshape(kdjJ >= kdjOverbought ? low : na, style=shape.triangleup, location=location.belowbar, color=color.red, size=size.small, title="Short Signal")
plotshape(kdjJ <= kdjOversold ? high : na, style=shape.triangledown, location=location.abovebar, color=color.green, size=size.small, title="Long Signal")

// Trading Strategy with Manual Margin and MA Strategy
if (kdjJ >= kdjOverbought and maCrossDown)
    strategy.entry("Short", strategy.short, qty=1, comment="Short Entry")
if (kdjJ <= kdjOversold and maCrossUp)
    strategy.entry("Long", strategy.long, qty=1, comment="Long Entry")