Warning: Declaration of ElementorPro\Modules\Posts\Skins\Skin_Content_Base::register_controls(Elementor\Widget_Base $widget) should be compatible with Elementor\Controls_Stack::register_controls() in /home/customer/www/backtest-rookies.com/public_html/wp-content/plugins/elementor-pro/modules/theme-builder/widgets/post-content.php on line 17
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:
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
ScopeSo breaking down the request, the following requirements can be seen:
- Long Criteria:
Closemust be > x% away from a moving average
Closemust 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
//@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 CommentaryThe 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 latest
closeprice. 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()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_short_breakbecause 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 ChartsRunning the strategy will result in a chart that looks like this: 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.
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.