API Reference

Cheat Sheet

Every function of the library on one page, grouped by what you want to do. Follow a link for the arguments, return values and examples.

On this page
  1. A typical backtest
  2. A typical rebalancing backtest
  3. Set up a run
  4. Move through time
  5. Read market data
  6. Trade
  7. Rank and rebalance
  8. Inspect the portfolio
  9. Measure performance
  10. Technical indicators
  11. Yahoo Finance data
  12. Fundamentals
  13. Automate rules
  14. Change settings

In lein repl all of these are available right away. In your own namespace, require them as shown in Get Started. Arguments in square brackets are optional.

A typical backtest

(load-dataset "resources/sample-data/main" "main" add-aprc) ; 1. load the data
(init-portfolio "1990-01-02" 10000)                          ; 2. start a portfolio

(while (< (compare (get-date) "1990-03-29") 0)               ; 3. every trading day:
  (let [price (get-permno-price "10001")
        ma20  (moving-avg "10001" 20)]
    (when (and price ma20)
      ;; hold 50 shares while the price is below its 20-day average
      (order "10001" (if (< price ma20) 50 0) :remaining true)))
  (update-eval-report)
  (next-date))

(end-order)                                                  ; 4. close positions
(print-eval-report)                                          ; 5. review

A typical rebalancing backtest

(build-yahoo-dataset! "resources/sample-yahoo" :out-dir "target/sample-yahoo")
(load-yahoo-dataset "target/sample-yahoo")                  ; 1. prices and fundamentals
(init-portfolio "2023-01-03" 100000)                        ; 2. start a portfolio

(while (neg? (compare (get-date) "2024-12-31"))            ; 3. every trading day:
  (when (new-period? :month)                                ;    on the first of the month,
    (rebalance (equal-weights (top-n earnings-yield 2))))   ;    hold the two cheapest
  (next-date)
  (update-eval-report))

(end-order)                                                 ; 4. close positions
(benchmark-stats "IDX")                                     ; 5. compare with the index

Set up a run

FunctionWhat it does
(load-dataset dir role [add-aprc])Load the "main" price dataset or a "compustat" fundamentals dataset
(load-yahoo-dataset dir)Load a dataset built from Yahoo Finance: prices and fundamentals
(init-portfolio date capital)Start (or restart) with capital in cash on date
(update-output-dir dir)Also write the records as CSV files; call before init-portfolio
(CHANGE-CACHE-SIZE n)Keep n days of data in memory (60 by default)

Move through time

FunctionWhat it does
(get-date)Today's date, as "YYYY-MM-DD"
(next-date)Move to the next trading day, fill pending orders, run automations. nil once the run has ended
(get-next-date)The next trading day, without moving
(get-prev-n-date n)The date n trading days ago
(date-after-n-trading-days date n)The date n trading days after date

Read market data

FunctionWhat it does
(available-permnos)The securities that trade today
(get-info)Today's rows, one map per security
(get-info-map)Today's rows, as a map from permno to row
(get-permno-info [date] permno)One security's row
(get-permno-price [date] permno)One security's trading price
(get-permno-by-key [date] permno key)One column of one security's row, such as :TICKER
(get-prev-n-days [n])The rows of the previous n trading days, most recent first
(get-prev-n-days-map [n])The same, one permno-keyed map per day
(get-permno-prev-n-days permno n)One security's rows over the previous n trading days
(permno-tic permno), (tic-permno ticker)Translate between permnos and tickers
(->double x)Convert a Compustat value (a string) to a number; see the Fundamental Analysis example

Trade

FunctionWhat it does
(order permno quantity & options)Buy (positive) or sell (negative) shares; fills at the next close
(order permno n :remaining true)Trade until you hold n shares; 0 closes the position
(order ... :leverage false)Fail instead of borrowing cash or shares
(order ... :expiration n)Keep the order pending for up to n trading days
(order ... :print true)Print the order when it fills
(end-order)Close every position at today's close and end the run
@pending-orderOrders that have not filled yet

Rank and rebalance

FunctionWhat it does
(new-period? unit)True on the first trading day of a :week, :month, :quarter or :year, and on the first day of the run
(rank-by f & options)[[permno value] ...], highest (f permno) first; :universe, :ascending
(top-n f n & options)The n permnos with the highest (f permno)
(equal-weights permnos){permno 1/n}
(order-target-percent permno weight)Order so the holding becomes weight of equity; :whole-shares? true
(rebalance weights)Target {permno weight} for the whole portfolio, closing everything else
(portfolio-equity)Equity as last valued

Inspect the portfolio

FunctionWhat it does
(print-portfolio)Current holdings and cash
(print-portfolio-record [n])Daily value, return, loan, leverage and margin; -1 prints every row
(print-order-record [n])Filled orders
(portfolio-exposure)Cash, long, short, equity, gross and loan, in dollars
@portfolio, @portfolio-value, @order-recordThe same data as Clojure values, for your own analysis

Measure performance

FunctionWhat it does
(update-eval-report)Add today's metrics to the evaluation report
(print-eval-report [n])Value, volatility, Sharpe ratio, profit per trade and drawdown, per day
@eval-recordThe report as numbers
(portfolio-total), (portfolio-total-ret), (portfolio-daily-ret)Current total value and returns
(volatility), (sharpe-ratio), (max-drawdown), (pnl-per-trade)One metric for the run so far
(rolling-volatility), (rolling-sharpe-ratio)The same over the rolling window
(update-rolling-window n)Set the rolling window (30 trading days by default)
(benchmark-stats permno)Returns, beta, alpha, correlation, tracking error and information ratio against a security
(plot data series x y full-date)Line chart in the browser

Technical indicators

FunctionWhat it does
(moving-avg permno n)Simple moving average over n days including today
(moving-sd permno n)Moving standard deviation, for Bollinger Bands
(EMA permno), (EMA-generator n)Exponential moving average (20 days, or n)
(MACD permno), (MACD-generator signal short long)[macd signal short-ema long-ema]
(RSI permno), (RSI-generator n)Relative Strength Index, 0 to 100
(ROC permno n)Rate of change over n days
(parabolic-SAR permno state)Stop-and-reverse level; pass yesterday's result back in
(ATR permno n prev-atr)Average true range
(keltner-channel permno n prev-atr)[middle upper lower]

Indicators return nil until they have enough history.

Yahoo Finance data

FunctionWhat it does
(download-yahoo! dir tickers & options)Download prices, statements and earnings dates into <dir>/raw; :start, :fundamentals?, :force?
(build-yahoo-dataset! dir & options)Build the dataset from the downloads, offline; :out-dir, :start, :end, :report-lag-days
(load-yahoo-dataset dir)Load the built prices and fundamentals
(yahoo-dataset! dir tickers & options)All three in one call
(dataset-info dir)Coverage, options and warnings of a built dataset

Fundamentals

Values as they were known on the backtest date, per share of the day and in the trading currency. nil when not known yet.

FunctionWhat it does
(fundamental permno field [frequency])A value, such as :net-income; frequency :quarterly, :annual, :trailing, :ttm or :latest
(fundamental-info permno field [frequency])The value with its period end, public date and source
(fundamental-history permno field frequency n)The last n public values, newest first
(fundamental-as-of date permno field)A value on another date
(available-fields permno)The fields a security has
(pe-ratio p), (earnings-yield p), (book-to-market p), ...Valuation ratios on today's price
(return-on-equity p), (gross-margin p), (debt-to-equity p), ...Quality ratios
(market-cap p), (enterprise-value p), (shares-outstanding p)Size
(growth p field [frequency])Year-on-year growth
(piotroski-f-score p), (piotroski-signals p)Piotroski's 0-to-9 health score and its nine signals
(latest-earnings p), (days-since-earnings p)The latest earnings announcement and its surprise

Automate rules

FunctionWhat it does
(set-automation (condition f) (action g) & options)Run g on every trading day on which f returns true; returns an id
:max-dispatch n, :expiration nRun at most n times; stay active for n trading days
(cancel-automation id)Remove an automation
(print-automation-list)Active automations
(print-automation-history [n])The days automations ran

Change settings

Call these before init-portfolio. See Parameters for all of them.

FunctionDefaultWhat it sets
(update-initial-margin x)0.5Margin required for new borrowing; nil for none
(update-maintenance-margin x)0.25Margin below which every position is closed
(update-transaction-cost x)0.0Commission, as a fraction of the trade value
(update-interest-rate x)0.0Annual interest on loans
(update-reinvest-dividends flag)trueReinvest dividends, or pay them into cash
(update-fundamentals-max-age months)18Months after its period end a fundamental stays usable
(CHANGE-EMA-CYCLE n), (CHANGE-RSI-CYCLE n), ...20, 14Indicator periods
(alter-var-root #'PRICE-KEY (constantly :OPENPRC)):PRCTrade at the open instead of the close