Measured by the engine 0.0.2, after costs. A record of a simulation on past data, not a forecast.
Illustration only, not a result of real trading. OrionQuant is software, not a financial service, and gives no investment advice.
The code The strategy as the app opens it.
python Copy # Trend filter. Long while the close is above its N day simple average; below it
# the strategy is flat, or short when shorts are switched on. The stop sits
# `stopAtr` average true ranges away and the size risks `riskPercent` of the
# balance to that stop.
class TrendFilter(Strategy):
PARAMETERS = [
{"key": "period", "label": "Average (days)", "default": 200, "min": 20, "max": 400},
{"key": "allowShort", "label": "Trade short too (1 yes, 0 no)", "default": 0, "min": 0, "max": 1},
{"key": "atrPeriod", "label": "ATR period", "default": 20, "min": 5, "max": 60},
{"key": "stopAtr", "label": "Stop distance (ATR)", "default": 4.0, "min": 1.0, "max": 8.0},
{"key": "riskPercent", "label": "Risk per trade (% of balance)", "default": 2.0, "min": 0.1, "max": 3.0},
]
def __init__(self, params):
self.period = max(2, int(params.get("period", 200)))
self.shorts = float(params.get("allowShort", 0)) >= 1
self.atr_period = int(params.get("atrPeriod", 20))
self.stop_atr = float(params.get("stopAtr", 4.0))
self.risk = float(params.get("riskPercent", 2.0))
def on_bar(self, ctx):
ma = ctx.indicators.sma(self.period)
atr = ctx.indicators.atr(self.atr_period)
bars = ctx.bars(1)
if ma is None or atr is None or not bars:
return
stop = atr * self.stop_atr / ctx.pip()
if bars[-1].close > ma:
ctx.signal("LONG", sl_pips=stop, risk_percent=self.risk)
elif self.shorts:
ctx.signal("SHORT", sl_pips=stop, risk_percent=self.risk)
else:
ctx.signal("EXIT")