Tutorial
Orcus's core functionality is the @generate_strategy macro, which lets you define a strategy as two functions: init, run once at the start of the backtest, and next, run once per bar. Let's walk through a simple SMA-crossover strategy.
First, start up Orcus and load some sample data.
using Orcus
M = market([GOOG]) # creating a market object with singular GOOG tickerNext, define two simple indicators: a 10-day and a 20-day simple moving average (SMA). The init function attaches these indicators to the market data.
function cross_init(s::Strategy)
for (_, a) in s.market.data
apply_indicator(IndicatorGenerator(simple_average, 10), a, "Close", "SMA10")
apply_indicator(IndicatorGenerator(simple_average, 20), a, "Close", "SMA20")
end
endNow define the next function, called for each bar in the backtest. It checks whether the 10-day SMA has crossed above the 20-day SMA; if it has, it closes any existing positions and places a new buy order for 5 shares of GOOG.
function cross_next(s::Strategy)
a = s.market.data["GOOG"] # Access the data for GOOG
n = length(a)
n < 2 && return # Not enough data to check for crossover
crossed_up = a["SMA10", n] > a["SMA20", n] && a["SMA10", n-1] <= a["SMA20", n-1]
if crossed_up
request_to_close_all!(s.broker)
place_order!(s.broker, Order(Buy(a, 5)))
end
endWhat's left is to register the strategy with @generate_strategy, create a Backtest, and run it.
@generate_strategy SMAcrossover cross_next cross_init
bt = Backtest(M, SMAcrossover, 10_000) # 10k starting cash
run_test(bt)From here, Examples has more strategies covering multi-asset universes, PCA factor models, and order-book mechanics, and the Core pages document the pieces used above in full: Market data, Strategy authoring, and Backtesting.