Skip to content

Analysis

Every instrument object can analyse its own price history. A share, an index or a commodity future has 209 analysis methods: moving averages, oscillators, candlestick pattern detectors, summary statistics, crossover signals, a backtest runner and performance measures such as the Sharpe ratio. You call one on the instrument, such as reliance.relative_strength_index(window=14, days=90), and it fetches the candles from UBI, runs the calculation and hands back the candles with the result added as a new column.

The methods are not written on Instrument itself. They live in fourteen small classes under src/tradingmachine/assets/analysis/, one per group of related calculations, and Instrument inherits all fourteen. Most of the calculations come from TA-Lib, a widely used C library of technical indicators, and follow its function groups; the statistics, the signals, the backtest and the performance measures are this library's own. Every asset basket inherits the same fourteen classes, because a basket supplies prices too.

How a method works

Every analysis method that works on candles follows the same four steps, which the sequence diagram below traces for relative_strength_index.

sequenceDiagram
    autonumber
    participant Y as Your code
    participant M as relative_strength_index
    participant P as prices()
    participant U as UBI
    participant T as TA-Lib
    Y->>M: window=14, days=90
    M->>P: interval, from_date, to_date, days, adjusted
    P->>U: GET /api/instruments/prices
    U-->>P: candles, or none
    P-->>M: DataFrame, or None
    alt no candles
        M-->>Y: None
    else candles
        M->>T: RSI(close, timeperiod=14)
        T-->>M: one value per candle
        M-->>Y: the candles with an rsi_14 column added
    end

Three things follow from this design, and each is worth knowing before you call the methods in a loop.

  1. Each call fetches its own candles. Two indicators on the same instrument send two requests. That is deliberate: UBI runs on the same machine and keeps its own copy of the candles in Redis, so a repeated request is cheap, and the library keeps no cache of its own.
  2. No candles means None, not an error. When UBI has no candles for the range, prices returns None, and so does every method built on it. That is what happens for every instrument in a family UBI stores no candles for, as the table below shows.
  3. The early rows are empty. An indicator needs a run of candles before it has a value, so the first rows of its column are NaN. A 14-candle RSI has nothing for its first 14 rows, and the Hilbert transform indicators need 32 to 63 candles before their first value. Ask for a longer range than the window you want to look at.

The common arguments

Every method that fetches candles takes the same five arguments as prices, after its own. The table below lists them. Give either days, or from_date and to_date, but not both.

Name Type Default Description
interval str "day" The candle length, such as day or 5minute
from_date datetime.date or str None The first day of the range, as a date or YYYY-MM-DD
to_date datetime.date or str None The last day of the range
days int None The number of days to count back from today
adjusted bool True Whether prices are adjusted for splits and bonuses, for the segments UBI adjusts

Each method's own arguments use the library's spelled-out names rather than TA-Lib's. The window length is window, not TA-Lib's timeperiod and not period, and the candle column to work on is column, which defaults to close.

The window argument is window

Passing a name the method does not have fails in Python before any request is sent. The error below was captured on 2026-09-26 from reliance.simple_moving_average(period=5).

TypeError: OverlapStudies.simple_moving_average() got an unexpected keyword argument 'period'

The correct call is reliance.simple_moving_average(window=5, days=90).

The fourteen classes

The table below lists the fourteen analysis classes in the order Instrument inherits them, with the number of public methods in each. The counts were taken from the code with a short script on 2026-09-29 and add up to 209. The thirteen older classes add up to 192, and PerformanceMeasures was added as the fourteenth on 2026-09-28.

Class Module Methods What it holds Each method returns Page
PriceStatistics price_statistics 39 Highs, lows, means, spreads and quantiles of prices, volumes and returns A number, a summary, a histogram or a narrowed frame Statistics
OverlapStudies overlap_studies 12 Moving averages, Bollinger bands, parabolic SAR The candles with columns added Indicators
MomentumIndicators momentum_indicators 28 MACD, RSI, ADX, stochastics and other oscillators The candles with columns added Indicators
VolumeIndicators volume_indicators 3 Chaikin accumulation distribution, on balance volume The candles with a column added Indicators
CycleIndicators cycle_indicators 6 The Hilbert transform family The candles with columns added Indicators
PriceTransforms price_transforms 4 Average, median and typical price, weighted close The candles with a column added Statistics
VolatilityIndicators volatility_indicators 3 True range and average true range The candles with a column added Indicators
StatisticFunctions statistic_functions 8 Beta, correlation, linear regression, standard deviation The candles with columns added Statistics
MathTransforms math_transforms 15 Trigonometric, logarithmic and rounding functions The candles with a column added Statistics
MathOperators math_operators 10 Adding, dividing, rolling highs and lows The candles with columns added Statistics
CandlestickPatterns candlestick_patterns 61 TA-Lib's candlestick pattern recognisers The candles with a column of 100, -100 or 0 Patterns
Signals signals 2 Crossovers and crossunders between two columns A copy of your frame with a bool column Signals and backtests
StrategyBacktests strategy_backtests 1 A backtest of a backtesting strategy A pandas Series of statistics Signals and backtests
PerformanceMeasures performance_measures 17 Returns, volatility, Sharpe, Sortino and Calmar ratios, drawdowns, value at risk and measures against a benchmark A number, a DataFrame of drawdowns or a pandas Series summary Performance measures

All fourteen inherit a small base class, PriceAnalysis, which declares prices and raises NotImplementedError from it. That lets each module be written and read on its own, without importing the instrument classes. Instrument supplies the real prices, which reads UBI.

The chart below shows the same counts. Candlestick patterns and price statistics make up almost half of the total.

{ "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "description": "Number of public methods in each of the fourteen analysis classes.", "width": "container", "height": 360, "data": { "values": [ {"class": "CandlestickPatterns", "methods": 61, "source": "TA-Lib"}, {"class": "PriceStatistics", "methods": 39, "source": "pandas"}, {"class": "MomentumIndicators", "methods": 28, "source": "TA-Lib"}, {"class": "PerformanceMeasures", "methods": 17, "source": "pandas"}, {"class": "MathTransforms", "methods": 15, "source": "TA-Lib"}, {"class": "OverlapStudies", "methods": 12, "source": "TA-Lib"}, {"class": "MathOperators", "methods": 10, "source": "TA-Lib"}, {"class": "StatisticFunctions", "methods": 8, "source": "TA-Lib"}, {"class": "CycleIndicators", "methods": 6, "source": "TA-Lib"}, {"class": "PriceTransforms", "methods": 4, "source": "TA-Lib"}, {"class": "VolumeIndicators", "methods": 3, "source": "TA-Lib"}, {"class": "VolatilityIndicators", "methods": 3, "source": "TA-Lib"}, {"class": "Signals", "methods": 2, "source": "pandas"}, {"class": "StrategyBacktests", "methods": 1, "source": "backtesting"} ] }, "mark": {"type": "bar", "tooltip": true}, "encoding": { "y": {"field": "class", "type": "nominal", "sort": "-x", "title": null}, "x": {"field": "methods", "type": "quantitative", "title": "Public methods"}, "color": {"field": "source", "type": "nominal", "title": "Calculated with", "legend": {"orient": "bottom"}} } }

Which instruments have candles

An analysis method can only work where UBI stores candles, and it stores them for a minority of segments. The table below lists what is known, family by family. Asset classes has the full matrix.

Family Classes with candles Classes without
Equities Equity (adjusted, with price_factor), EquityIndex The four derivative classes have not been checked
Fixed income none all six
Commodities the four derivative classes Commodity, CommodityIndex
Currencies none all six
Funds and trusts ExchangeTradedFund (adjusted, with price_factor) InvestmentTrust
Mutual funds none MutualFund

UBI's daily job loads only day candles. Intraday intervals such as 5minute are loaded into UBI by hand, so an intraday call usually returns None unless someone has loaded that instrument; on 2026-09-26, prices(interval="5minute", days=1) on RELIANCE returned None. UBI's page on price history explains what is loaded and from which broker.

A first example

The example below adds a 20-day simple moving average to RELIANCE's candles and marks the days its close crossed above it. It was not run for this page, because it needs a live UBI; the calls are taken from the method signatures.

from tradingmachine.assets import equities

reliance = equities.Equity(exchange="nse", symbol="RELIANCE")

frame = reliance.simple_moving_average(window=20, days=365)
crossings = reliance.is_cross_over(frame, "close", "sma_20")
print(crossings[crossings["cross_over"]][["datetime", "close", "sma_20"]])

The first call returns the candles with an sma_20 column. The second marks, in a new cross_over column, each row where the close was at or below the average on the previous row and above it on this one.

The pages in this section

Each page lists every method in its groups, with the method's own arguments and the column it adds.

  • Indicators


    Overlap studies, momentum, volume, volatility and cycle indicators: 52 methods.

    Indicators

  • Candlestick patterns


    The 61 pattern recognisers and what their 100, -100 and 0 values mean.

    Candlestick patterns

  • Statistics and transforms


    Price statistics, statistic functions, math operators and transforms, and price transforms: 76 methods.

    Statistics and transforms

  • Signals and backtests


    Crossover detection and running a backtesting strategy over an instrument's candles.

    Signals and backtests

  • Performance measures


    Returns, risk, drawdowns and comparison with a benchmark: 17 methods.

    Performance measures