0bps

Strategy vault / Trend following

Dynamic Risk Managed Exponential Moving Average Crossover Strategy

This strategy is a trend-following system based on Exponential Moving Average (EMA) crossovers, incorporating dynamic position sizing and risk management. It uses fast and slow EMA crossover signals to identify…

Author
ChaoZhang
Complexity
Starter · 54 lines
Parameters
0
Backtest bar
1d · swing
Tested on
BTC/USDT · futures

IMG

Overview

This strategy is a trend-following system based on Exponential Moving Average (EMA) crossovers, incorporating dynamic position sizing and risk management. It uses fast and slow EMA crossover signals to identify market trends while dynamically adjusting trade sizes through percentage risk calculations and employing trailing stops to protect profits.

Strategy Principles

The core logic relies on two EMAs with different periods (default 9 and 21). A long entry signal is generated when the fast EMA crosses above the slow EMA, while positions are closed when the fast EMA crosses below the slow EMA. Each trade size is dynamically calculated based on a fixed percentage risk (default 1%) of total account equity, with take-profit levels set according to risk-reward ratios and percentage-based trailing stops.

Strategy Advantages

  1. Dynamic position sizing ensures consistent risk per trade, avoiding the excessive risk of fixed position sizes.
  2. Trailing stop mechanism effectively locks in profits and exits positions when trends reverse.
  3. Risk-reward ratio settings ensure clear profit-loss ratios for each trade.
  4. EMA crossover signals effectively capture medium to long-term trends, reducing false signals.
  5. Fully automated system eliminates emotional interference.

Strategy Risks

  1. May generate frequent false crossover signals in ranging markets, leading to consecutive losses.
  2. Trailing stops might trigger too early in highly volatile markets, missing larger trends.
  3. Fixed percentage risk settings may lack flexibility when market volatility changes.
  4. Stop losses might be jumped over in quick reversal markets, resulting in larger than expected losses.

Optimization Directions

  1. Incorporate volatility indicators (like ATR) to dynamically adjust stop-loss and take-profit levels.
  2. Add trend strength filters, such as RSI or ADX, to reduce false signals in ranging markets.
  3. Develop dynamic EMA period adjustment mechanisms based on market volatility.
  4. Include volume confirmation indicators to improve signal reliability.
  5. Implement dynamic risk adjustment mechanisms based on recent losses.

Summary

This is a complete trading system that combines classical technical analysis methods with modern risk management concepts. The strategy controls risk through dynamic position sizing and trailing stops while capturing trending opportunities using EMA crossovers. While there are some inherent limitations, the suggested optimization directions can further enhance the strategy's robustness and adaptability. The strategy is particularly suitable for long-term trend trading with controlled risk.

Source Pine Script

/*backtest
start: 2019-12-23 08:00:00
end: 2024-12-18 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy("Bitcoin Exponential Profit Strategy", overlay=true)

// User settings
fastLength = input.int(9, title="Fast EMA Length", minval=1)
slowLength = input.int(21, title="Slow EMA Length", minval=1)
riskPercent = input.float(1, title="Risk % Per Trade", step=0.1) / 100
rewardMultiplier = input.float(2, title="Reward Multiplier (R:R)", step=0.1)
trailOffsetPercent = input.float(0.5, title="Trailing Stop Offset %", step=0.1) / 100

// Calculate EMAs
fastEMA = ta.ema(close, fastLength)
slowEMA = ta.ema(close, slowLength)

// Plot EMAs
plot(fastEMA, color=color.blue, title="Fast EMA")
plot(slowEMA, color=color.red, title="Slow EMA")

// Account balance and dynamic position sizing
capital = strategy.equity
riskAmount = capital * riskPercent

// Define Stop Loss and Take Profit Levels
stopLossLevel = close * (1 - riskPercent)
takeProfitLevel = close * (1 + rewardMultiplier * riskPercent)

// Trailing stop offset
trailOffset = close * trailOffsetPercent

// Entry Condition: Bullish Crossover
if ta.crossover(fastEMA, slowEMA)
    positionSize = riskAmount / math.max(close - stopLossLevel, 0.01)  // Prevent division by zero
    strategy.entry("Long", strategy.long, qty=positionSize)
    strategy.exit("TakeProfit", from_entry="Long", stop=stopLossLevel, limit=takeProfitLevel, trail_offset=trailOffset)

// Exit Condition: Bearish Crossunder
if ta.crossunder(fastEMA, slowEMA)
    strategy.close("Long")

// Labels for Signals
if ta.crossover(fastEMA, slowEMA)
    label.new(bar_index, low, "BUY", color=color.green, textcolor=color.white, style=label.style_label_up)
if ta.crossunder(fastEMA, slowEMA)
    label.new(bar_index, high, "SELL", color=color.red, textcolor=color.white, style=label.style_label_down)

Published by ChaoZhang on the FMZ strategy square · last modified 2024-12-20. Collected in the Quant Trading Vault. Unvalidated research: re-test with your own data and costs before trusting it.

Build this with AgenKit

A spec is not a trading system. Paste this into your coding agent and AgenKit runs a specialist team — architecture, test-first build, risk gates, review — with paper trading on by default.

in Claude Code, Cursor, Codex & 4 more
/agenkit build a production-grade trading bot with a backtest engine, risk controls and paper trading by default from strategies/Dynamic-Risk-Managed-Exponential-Moving-Average-Crossover-Strategy.md
  1. npx agenkit install engineering-kit in your project
  2. Paste the command into your agent and approve each phase
  3. Get tests, backtest, risk controls and a paper-trading switch

Understand it first

Before you run this, read the lesson behind the idea and how to backtest it honestly. Specs like this one are the survivors of an unknown number of trials; deflate their results accordingly.

Related specs

esc

Try , , or .

↑↓ move↵ open