Beta coefficient (β)
Beta shows how strongly one asset's price responds to systemic volatility of the entire market. Beta measures an asset's non-diversifiable systematic risk — its market exposure — not its idiosyncratic, asset-specific risk. Upside Beta (Beta+) and Downside Beta (Beta-), popularized by Harry M. Markowitz, are also included. Beta+ and Beta- capture asymmetric sensitivity during rising and falling markets. [Discuss] 💬
// C# usage syntax
IReadOnlyList<BetaResult> results = barsEval
.ToBeta(barsMarket, lookbackPeriods, type);Parameters
| param | description |
|---|---|
sourceEvalIReadOnlyList<IReusable> | Historical price bars used as the evaluation subject. You must have the same number of periods as sourceMrkt. |
sourceMrktIReadOnlyList<IReusable> | Historical price bars used as the benchmark basis for comparison. This is usually market index data. You must have the same number of periods as sourceEval. |
lookbackPeriodsint | Number of periods (N) in the lookback window. Must be greater than 0 to calculate; however we suggest a larger period for statistically appropriate sample size and especially when using Beta +/-. |
typeBetaType | Type of Beta to calculate. Default is BetaType.Standard. See BetaType options below. |
Historical price bars requirements
You must have at least N periods of sourceEval and sourceMrkt to cover the warmup periods. More than the minimum is typically provided, since a larger sample improves statistical quality — especially when using Beta +/-.
sourceEval and sourceMrkt must have consistent frequency (day, hour, minute, etc). Mismatch histories will throw InvalidBarsException. See the Guide for more information.
BetaType options
| type | description |
|---|---|
BetaType.Standard | Standard Beta only. Uses all historical price bars. (default) |
BetaType.Up | Upside Beta only. Uses market up bars only. |
BetaType.Down | Downside Beta only. Uses market down bars only. |
BetaType.All | Returns all of the above. Required for Ratio and Convexity values. Note: 3× slower. |
✨ Pro tip
Financial institutions often depict a single number for Beta on their sites. To get that same long-term Beta value, use 5 years of monthly bars for bars and a value of 60 for lookbackPeriods. If you only have smaller bars, use the Aggregate() utility to convert it.
Alpha is calculated as R – Rf – Beta (Rm - Rf), where Rf is the risk-free rate.
Response
IReadOnlyList<BetaResult>- This method returns a time series of all available indicator values for the
barsprovided. - It always returns the same number of elements as there are in the historical price bars.
- It does not return a single incremental indicator value.
- The first
N-1periods will havenullvalues since there's not enough data to calculate.
BetaResult
| property | description |
|---|---|
TimestampDateTime | Date from evaluated TBar |
Betadouble? | Beta coefficient based |
BetaUpdouble? | Beta+ (Up Beta) |
BetaDowndouble? | Beta- (Down Beta) |
Ratiodouble? | Beta ratio is BetaUp/BetaDown |
Convexitydouble? | Beta convexity is (BetaUp-BetaDown)2 |
ReturnsEvaldouble? | Returns of evaluated bars (R) |
ReturnsMrktdouble? | Returns of market bars (Rm) |
Utilities
See Utilities and helpers for more information.
Chaining
This indicator may be generated from any chain-enabled indicator or method.
// example
var results = barsEval
.Use(CandlePart.HL2)
.ToBeta(barsMarket.Use(CandlePart.HL2), ..);🚩 Matching inputs required
Both eval and market arguments must contain the same number of elements and be the results of a chainable indicator or .Use() method.
Results can be further processed on Beta with additional chain-enabled indicators.
// example
var results = barsEval
.ToBeta(barsMarket, ..)
.ToSlope(..);See Chaining indicators for more.
Streaming
Use the buffer-style List<T> when you need incremental calculations without a hub. Add each series separately as its values arrive; either one may run ahead, and a result is added once both hold the same timestamp:
BetaList betaList = new(lookbackPeriods, type);
// call from each series' message handler
void OnEvalReceived(IReusable value) => betaList.AddSource(value);
void OnMarketReceived(IReusable value) => betaList.AddOther(value);
// the list itself holds the results; fills as the handlers run
IReadOnlyList<BetaResult> results = betaList;A timestamp that only one series holds produces no result, where the Series method throws. Each series must arrive in strictly increasing order: an older or equal timestamp on a side throws an InvalidOperationException. Each side stages at most MaxListSize values, so a side that falls further behind than that loses the pairs the leading side has dropped.
Subscribe to a BarHub for each series for advanced streaming scenarios:
BarHub evalHub = new();
BarHub marketHub = new();
BetaHub observer = evalHub.ToBetaHub(marketHub, lookbackPeriods, type);
// call from each series' message handler
void OnEvalReceived(IBar bar) => evalHub.Add(bar);
void OnMarketReceived(IBar bar) => marketHub.Add(bar);
// results fill as the handlers run
IReadOnlyList<BetaResult> results = observer.Results;A result is added once both providers hold the same timestamp. A value that arrives late, or is revised or removed, on either side is handled by the usual rebuild. Timestamps match exactly: each return is measured from the previous matched timestamp, and the lookback window spans N matched returns. Drive both providers from one thread at a time.
See Buffer lists and Stream hubs for full usage guides.