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 # Time series momentum. Long when the close is above the close N days ago, short
# when it is below (shorts are optional), otherwise flat. The stop sits
# `stopAtr` average true ranges away and the size risks `riskPercent` of the
# balance to that stop.
class TimeSeriesMomentum(Strategy):
PARAMETERS = [
{"key": "lookback", "label": "Look back (days)", "default": 120, "min": 20, "max": 400},
{"key": "allowShort", "label": "Trade short too (1 yes, 0 no)", "default": 1, "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.lookback = max(5, int(params.get("lookback", 120)))
self.shorts = float(params.get("allowShort", 1)) >= 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):
bars = ctx.bars(self.lookback + 1)
atr = ctx.indicators.atr(self.atr_period)
if len(bars) < self.lookback + 1 or atr is None:
return
stop = atr * self.stop_atr / ctx.pip()
change = bars[-1].close - bars[0].close
if change > 0:
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")