1UNIVERSE = 7 equity indices + 7 FX pairs # no futures
2LOOKBACK = 12 months
4function positions(bar):
5 # identical rule to the previous experiment; only the universe
6 # differs, and it holds only instruments whose price history can
7 # be trusted
8 for symbol in UNIVERSE:
9 direction = sign(sum(returns(symbol, LOOKBACK, ending bar)))
10 vol = stdev(returns(symbol, 36 months, ending bar.prev))
11 w[symbol] = direction / vol
13 return w
15# ── execution ────────────────────────────────────────────────────────
17COST_PER_TRADE = 15 bps of the notional that changes hands
19function on_bar(bar, book):
20 if not bar.is_month_end:
21 return # decisions are made monthly only
23 target = positions(bar) # the rule above
24 target = scale_to_gross(target, 1.0)
26 rebalance(book, target, bar)
28function scale_to_gross(w, limit):
29 gross = sum(abs(w)) # total capital at work
31 if gross == 0:
32 return w # flat is a valid target
34 return w * limit / gross # leverage fixed, never implicit
36function rebalance(book, target, bar):
37 for symbol in union(book.symbols, target.symbols):
38 delta = target[symbol] - book.weight(symbol)
40 if delta > 0:
41 buy(symbol, delta, fill = next_bar.close)
42 else if delta < 0:
43 sell(symbol, -delta, fill = next_bar.close)
45 book.charge(COST_PER_TRADE * abs(delta))
47# Orders are filled at the next month's close, never the one the decision
48# was made on. There is no stop_loss(), take_profit(), limit order or
49# position cap: a holding changes only when positions() returns a
50# different target at the next month end.