//**********************************************
//Code:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//
// System Rules:
// Indicators: MACD indicator (default values), ATR (14), EMA (200)
// 1. Price must be trading above/below the 200 EMA
// 2. Only 1 bar can close above/below the 200 EMA over the past 5 bars
// 3. We take the FIRST MACD cross and ignore subsequent signals until TP/SL is hit
// 4. Stop Loss = 0.5 ATR above/below the recent swing high/low (7 bars lookback)
// 5. First take profit = 1:1 (25%)
// 6. Second take profit = 2:1 (100%)
// 7. Move stop loss to break-even after 1st target is hit
//
// @version=5
strategy("[2022] MACD Cross Strategy", overlay=true,
currency="USD",
calc_on_order_fills=true,
use_bar_magnifier=true,
initial_capital=10000,
default_qty_type=strategy.percent_of_equity,
default_qty_value=100, // 100% of balance invested on each trade
commission_type=strategy.commission.cash_per_contract)
//commission_value=0.005) // Interactive Brokers rate
// Get user input
var g_system = "System Entry Settings"
i_ema_filter = input.int(title="EMA Filter Length", defval=200, group=g_system)
i_ema_filter2 = input.int(title="EMA Max Bars Above/Below", defval=1, group=g_system)
i_stop_multi = input.float(title="Stop Loss Multiplier", defval=0.5, step=0.5, group=g_system)
i_stop_lookback = input.int(title="Stop Loss Lookback", defval=7, group=g_system)
var g_risk = "System Risk Settings"
i_rr1 = input.float(title="Risk:Reward Target 1", defval=1.0, group=g_risk)
i_rr2 = input.float(title="Risk:Reward Target 2", defval=2.0, group=g_risk)
i_target1 = input.float(title="Profit % Target 1", defval=25, group=g_risk)
i_riskPerTrade = input.float(title="Forex Risk Per Trade %", defval=1.0)
i_useLots = input.bool(title="Use Lots Instead Of Units", defval=false)
var g_macd = "MACD Settings"
i_price_src = input.source(title="Price Source", defval=close, group=g_macd)
i_fast_length = input.int(title="Fast Length", defval=12, group=g_macd)
i_slow_length = input.int(title="Slow Length", defval=26, group=g_macd)
i_signal_length = input.int(title="Signal Smoothing", minval=1, maxval=50, defval=9, group=g_macd)
i_sma_source = input.string(title="Oscillator MA Type", defval="EMA", options=["SMA", "EMA"], group=g_macd)
i_sma_signal = input.string(title="Signal Line MA Type", defval="EMA", options=["SMA", "EMA"], group=g_macd)
//------------- DETERMINE CURRENCY CONVERSION RATE ------------- { //
// Import ZenLibrary
import ZenAndTheArtOfTrading/ZenLibrary/5 as zen
// Custom function for converting units into lot sizes
unitsToLots(units) =>
float lots = units / 100000
lots := math.round(lots, 2)
_return = lots * 100000
// Check if our account currency is the same as the base or quote currency or neither (for risk $ conversion purposes)
accountSameAsCounterCurrency = strategy.account_currency == syminfo.currency
accountSameAsBaseCurrency = strategy.account_currency == syminfo.basecurrency
accountNeitherCurrency = not accountSameAsCounterCurrency and not accountSameAsBaseCurrency
// Get currency conversion rates if applicable
conversionCurrencyPair = accountSameAsCounterCurrency ? syminfo.tickerid : strategy.account_currency + syminfo.currency
conversionCurrencyRate = accountSameAsBaseCurrency or accountNeitherCurrency ? request.security(conversionCurrencyPair, "D", close, ignore_invalid_symbol=true) : 1.0
// Display the current conversion currency ticker (for debug purposes)
if barstate.islastconfirmedhistory
table t = table.new(position.top_right, 1, 2, color.black)
table.cell(t, 0, 0, "Conversion: " + conversionCurrencyPair + " (" + str.tostring(conversionCurrencyRate) + ")", text_color=color.white, text_size=size.small)
table.cell(t, 0, 1, "Account: $" + str.tostring(zen.truncate(strategy.equity)), text_color=color.white, text_size=size.small)
//------------- END CURRENCY CONVERSION RATE CODE ------------- }//
// Calculate MACD
[macdLine, signalLine, histLine] = ta.macd(i_price_src, i_fast_length, i_slow_length, i_signal_length)
// Get indicator values
ema = ta.ema(close, i_ema_filter)
atr = ta.atr(14)
// Check for zero-point crosses
crossUp = ta.crossover(signalLine, macdLine)
crossDown = ta.crossunder(signalLine, macdLine)
// Check general system filters
tradeFilters = not na(ema) and not na(atr)
// Check trend conditions
upTrend = close > ema
downTrend = close < ema
// Check trade conditions
longConditions = tradeFilters and macdLine[1] < 0 and signalLine[1] < 0
shortConditions = tradeFilters and macdLine[1] > 0 and signalLine[1] > 0
// Confirm long & short setups
longSignal = longConditions and upTrend and crossDown
shortSignal = shortConditions and downTrend and crossUp
// Calculate stop loss
longStop = ta.lowest(low, i_stop_lookback) - (atr * i_stop_multi)
shortStop = ta.highest(high, i_stop_lookback) + (atr * i_stop_multi)
// Save stops & targets
var float tradeStop = na
var float tradeTarget1 = na
var float tradeTarget2 = na
var float tradeSize = na
// Count bars above/below MA
int barsAboveMA = 0
int barsBelowMA = 0
for i = 1 to 5
if close[i] < ema[i]
barsBelowMA += 1
if close[i] > ema[i]
barsAboveMA += 1
// Combine signal filters
longTrade = longSignal and barsBelowMA <= i_ema_filter2 and strategy.position_size == 0
shortTrade = shortSignal and barsAboveMA <= i_ema_filter2 and strategy.position_size == 0
// Handle long trade entry (enter position, reset stops & targets)
if longTrade
if syminfo.type == "forex"
tradeStop := longStop
stopDistance = close - tradeStop
tradeTarget1 := close + (stopDistance * i_rr1)
tradeTarget2 := close + (stopDistance * i_rr2)
tradeSize := na
positionSize = zen.av_getPositionSize(strategy.equity, i_riskPerTrade, zen.toWhole(stopDistance) * 10, conversionCurrencyRate)
strategy.entry(id="Long", direction=strategy.long, qty=i_useLots ? unitsToLots(positionSize) : positionSize)
else
strategy.entry(id="Long", direction=strategy.long)
tradeStop := na
tradeTarget1 := na
tradeTarget2 := na
// Handle short trade entry (enter position, reset stops & targets)
if shortTrade
if syminfo.type == "forex"
tradeStop := shortStop
stopDistance = tradeStop - close
tradeTarget1 := close - (stopDistance * i_rr1)
tradeTarget2 := close - (stopDistance * i_rr2)
tradeSize := na
positionSize = zen.av_getPositionSize(strategy.equity, i_riskPerTrade, zen.toWhole(shortStop - close) * 10, conversionCurrencyRate)
strategy.entry(id="Short", direction=strategy.short, qty=i_useLots ? unitsToLots(positionSize) : positionSize)
else
strategy.entry(id="Short", direction=strategy.short)
tradeStop := na
tradeTarget1 := na
tradeTarget2 := na
// Handle forex trade size tracking variable
if syminfo.type == "forex" and strategy.position_size != 0 and na(tradeSize)
tradeSize := strategy.position_size
// Handle long stops & target calculation
if strategy.position_size > 0 and na(tradeStop) and syminfo.type != "forex"
tradeStop := longStop
stopDistance = strategy.position_avg_price - tradeStop
tradeTarget1 := strategy.position_avg_price + (stopDistance * i_rr1)
tradeTarget2 := strategy.position_avg_price + (stopDistance * i_rr2)
tradeSize := strategy.position_size
// Handle short stops & target calculation
if strategy.position_size < 0 and na(tradeStop) and syminfo.type != "forex"
tradeStop := shortStop
stopDistance = tradeStop - strategy.position_avg_price
tradeTarget1 := strategy.position_avg_price - (stopDistance * i_rr1)
tradeTarget2 := strategy.position_avg_price - (stopDistance * i_rr2)
tradeSize := strategy.position_size
// Handle trade exits
float exitPartialUnits = math.abs(strategy.position_size / (100 / i_target1))
float exitPartialLots = unitsToLots(exitPartialUnits)
strategy.exit(id="Long Exit #1", from_entry="Long", limit=tradeTarget1, stop=tradeStop, qty=i_useLots ? exitPartialLots : exitPartialUnits)
strategy.exit(id="Long Exit #2", from_entry="Long", limit=tradeTarget2, stop=tradeStop, qty_percent=100)
strategy.exit(id="Short Exit #1", from_entry="Short", limit=tradeTarget1, stop=tradeStop, qty=i_useLots ? exitPartialLots : exitPartialUnits)
strategy.exit(id="Short Exit #2", from_entry="Short", limit=tradeTarget2, stop=tradeStop, qty_percent=100)
// Handle both long & short trade break-even stops (do this AFTER first position has exited above ^)
if strategy.position_size != tradeSize
tradeStop := strategy.position_avg_price
tradeTarget1 := na
// Draw conditional data
plot(ema, color=close > ema ? color.green : color.red, linewidth=2, title="EMA")
plotshape(longTrade, style=shape.triangleup, color=color.green, location=location.belowbar, title="Long Setup")
plotshape(shortTrade, style=shape.triangledown, color=color.red, location=location.abovebar, title="Short Setup")
// Draw stops & targets
plot(strategy.position_size != 0 ? tradeStop : na, color=color.red, style=plot.style_linebr, title="Stop Loss")
plot(strategy.position_size != 0 ? tradeTarget1 : na, color=color.green, style=plot.style_linebr, title="Profit Target 1")
plot(strategy.position_size != 0 ? tradeTarget2 : na, color=color.green, style=plot.style_linebr, title="Profit Target 2")
Overview
MACD Cross Strategy applies an EMA 200 filter requiring price to trade above or below the EMA. Only the first MACD crossover is used after the filter condition is met. Stop loss is calculated as 0.5 times ATR from the recent swing high or low. Take profits use 1:1 and 2:1 risk reward ratios with the option to move stop loss to break even after the first target. Position sizing supports percent of equity or lots for forex pairs. Settings allow customization of MACD lengths, EMA filter, stop multiplier, and risk levels.
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
EMA Filter Length
int
200
i_ema_filter
EMA Max Bars Above/Below
int
1
i_ema_filter2
Stop Loss Multiplier
float
0.5
i_stop_multi
Stop Loss Lookback
int
7
i_stop_lookback
Risk:Reward Target 1
float
1.0
i_rr1
Risk:Reward Target 2
float
2.0
i_rr2
Profit % Target 1
float
25
i_target1
Forex Risk Per Trade %
float
1.0
i_riskPerTrade
Use Lots Instead Of Units
bool
false
i_useLots
Price Source
source
close
i_price_src
Fast Length
int
12
i_fast_length
Slow Length
int
26
i_slow_length
Show all 15 settings
Setting
Type
Default
Variable
Signal Smoothing
int
9
i_signal_length
Oscillator MA Type
string
EMA
i_sma_source
Signal Line MA Type
string
EMA
i_sma_signal
Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.
This strategy overlays a trend moving average and Supertrend bands directly on the price chart while calculating Stochastic RSI values internally. Long positions trigger when price exceeds the moving average, Supertrend signals bullish momentum, and the StochR
This trading strategy combines three Exponential Moving Averages (8, 14, and 50 periods by default) with Stochastic RSI and Average True Range (ATR). It enters a long position when EMA 1 is above EMA 2, EMA 2 is above EMA 3, and the Stochastic RSI %K line cros
This strategy combines exponential moving averages (EMA 9, 21, 50), RSI, MACD, and Supertrend indicators to enter long positions. It triggers trades using six dynamic setups based on momentum breakouts, EMA crossovers, and pullbacks. Position sizing is compute
CombinedBinHAndClucV6 is a trading strategy based on the popular BinHV45 and ClucMay72018 algorithms. It calculates dual Bollinger Bands, Exponential Moving Averages, Relative Strength Index, Average True Range, and volume metrics across primary and one-hour h
This strategy calculates Bollinger Bands, a configurable moving average slope, Stochastic RSI, ATR, and ADX directly on the price chart. It evaluates trend bias and momentum conditions to generate long and short swing entries using percent-of-equity sizing. Th
This strategy trades long and short on the price chart using a multi-timeframe TradingLatino setup. It requires EMA 10 to cross or sit above or below EMA 55 on the one-hour, four-hour, and daily charts, together with a positive ADX slope, a directional monitor