Another week, another reader request. Well actually, that is not quite true… This particular request has been sitting in the comments section of the Tradingview: First Script post gathering cobwebs since December.
As the saying goes better late than never! So let’s take a look at Igor’s request and see what we can do:
Ignore the performance for now. It would be more helpful to focus on how these techniques can be adapted and used in your own strategies. I doubt this was the complete strategy Igor envisioned but rather a part of something he is working on.
I want to build up a strategy like “if the price stays 10% away from a moving average I’ll long, or I’ll short, and I’ll close the position when the price hits the moving average again or with a 10% stop loss. How would you do that? I’m trying to figure out, but I can’t do it. Thanks
Scope
So breaking down the request, the following requirements can be seen:- Long Criteria:
Close
must be > x% away from a moving averageClose
must have have been > x% for x bars (stays 10% away)
- Short Criteria:
- As above be <x%
- Exit Criteria
- First Exit Strategy: When price touches the moving average
- Second Exit Strategy: Fixed stop-loss at x% from entry
Example Code
//@version=3 strategy("Reader Request: x% MA Strat", overlay=true) lkb = input(200, minval=2, title='SMA Lookback Period') delta = input(10, step=0.25, title='Entry Delta from MA')/100 bars = input(4, minval=0, title='Min Bars Above/Below Delta') sl = input(10, step=0.25, title='Stop-Loss Percent')/100 // Create Moving Averages ma = sma(close, lkb) ma_upper = ma * (1 + delta) ma_lower = ma * (1 - delta) // ----------------- // ENTRY CONDITIONS // ----------------- // Since break above long_break = crossover(close, ma) since_long_break = barssince(long_break) short_break = crossunder(close, ma) since_short_break = barssince(short_break) long_entry = close >= ma_upper and since_long_break >= bars short_entry = close <= ma_lower and since_long_break >= bars strategy.entry("Long", strategy.long, when=long_entry) strategy.entry("Short", strategy.short, when=short_entry) // ----------------- // EXIT CONDITIONS // ----------------- // Create stop losses long_stop = strategy.position_avg_price * (1 - sl) short_stop = strategy.position_avg_price * (1 + sl) // Detect whether the stop loss or MA is closer to price long_exit = long_stop > ma ? long_stop : ma short_exit = short_stop < ma ? short_stop : ma strategy.exit("Long SL", "Long", stop=long_exit) strategy.exit("Short SL", "Short", stop=short_exit) ma_plot = plot(ma, color=maroon, linewidth=2, title='Moving Average') ma_upper_plot = plot(ma_upper, color=red, linewidth=1, title='MA Upper Boundary') ma_lower_plot = plot(ma_lower, color=red, linewidth=1, title='MA Lower Boundary') fill(ma_lower_plot, ma_upper_plot, color=silver, transp=70)
Code Commentary
The first part to the challenge is to detect whether we are more than 10% above or below price. We can easily do this by working out 10% of the latestclose
price. Then we simply use that figure to add upper and lower bands to the SMA. These bands are not only handy for plotting, but they also make it easy to check if we are above the threshold at any given time.
The second requirement was to ensure we stay above the band. This is achieved using barssince()
and a simple crossover()
and crossover()
checks. Once we crossover the upper band (for longs) or crossunder the lower band (for shorts), the we start counting the bars we stay above it. If we break back down in the opposite direction, there is no need to reset since_long_break
and since_short_break
because once that happens, we won’t be above/below 10% anymore and cannot enter a position. As such, it won’t interfere with the results.
Moving onto the exits, we have two possible scenarios and they both use the same stop loss. As a recap, the first exit strategy is to exit when price hits the moving average. The second is to exit at fixed stop loss. Ideally, we do not want to have two separate stop loss orders in the market. This is because if we have a volatile move, both could get hit on the same bar and send us into an unintended position in the opposite direction. Therefore, in the code example above, we use a ternary conditional operator to work out which stop is closer to price and then we just send a single exit order at the closest level. That means if the fixed (10%) stop loss is closer, we use the fixed stop loss level. Conversely, if the moving average is closer, we set a stop at the current moving average level.
On The Charts
Running the strategy will result in a chart that looks like this:
Find This Post Useful?
If this post saved you time and effort, please consider support the site! There are many ways to support us and some won’t even cost you a penny.
Brave
Backtest Rookies is a registered with Brave publisher!
Brave users can drop us a tip.
Alternatively, support us by switching to Brave using this referral link and we will receive some BAT!
Tradingview
Referral Link
Enjoying the content and thinking of subscribing to Tradingview? Support this site by clicking the referral link before you sign up!
PayPal
BTC
3HxNVyh5729ieTfPnTybrtK7J7QxJD9gjD
ETH
0x9a2f88198224d59e5749bacfc23d79507da3d431
LTC
M8iUBnb8KamHR18gpgi2sSG7jopddFJi8S