OLS/beta helpers: single-factor regression, conditional (up/down) beta, and the marginal-beta decomposition (sum of marginal betas = portfolio beta).
OLS/beta helpers: single-factor regression, conditional (up/down) beta, and the marginal-beta decomposition (sum of marginal betas = portfolio beta).
(conditional-beta dts pred)Beta over just the rows where the benchmark return satisfies pred.
Beta over just the rows where the benchmark return satisfies pred.
(linear-regression-tmd dx dy)Same speed as matrix and you lose the alpha - but easier to read and easier inputs will return [beta r2]
Same speed as matrix and you lose the alpha - but easier to read and easier inputs will return [beta r2]
(linear-regression-tmd-ex-tails dx dy)5x slower with tails
5x slower with tails
(nd-beta-breakdown bonds
nominals
adjusted-history-prices
portfolio-value
benchmark-return)Marginal beta calculation - this is tricky. In particular we define a new series of returns such that all weights are constant at 1: S(i,t) = N(i) * r(i,t) * p(i, t-1) / sum(N(i) * p(i, t-1) this avoids gamma effects where weights change over time because of the bond price changes By linearity of covariance: sum(marginal_betas) = portfolio_beta
Marginal beta calculation - this is tricky. In particular we define a new series of returns such that all weights are constant at 1: S(i,t) = N(i) * r(i,t) * p(i, t-1) / sum(N(i) * p(i, t-1) this avoids gamma effects where weights change over time because of the bond price changes By linearity of covariance: sum(marginal_betas) = portfolio_beta
(nd-beta-vector A b)beta = covariance(asset, benchmark) / variance(benchmark) A is a matrix [[asset-1-returns-over-time] [] []], b is a vector [benchmark-returns-over-time] Equivalent Python where A is a DataFrame and b a series: pandas.np.dot(b.T - b.mean (), A - A.mean (axis=0)) / (b.shape [0] - 1) / pandas.np.var(b, axis=0, ddof=1)
beta = covariance(asset, benchmark) / variance(benchmark) A is a matrix [[asset-1-returns-over-time] [] []], b is a vector [benchmark-returns-over-time] Equivalent Python where A is a DataFrame and b a series: pandas.np.dot(b.T - b.mean (), A - A.mean (axis=0)) / (b.shape [0] - 1) / pandas.np.var(b, axis=0, ddof=1)
(simple-ols xs ys)Single-factor OLS of ys on xs -> {:beta :alpha :rsq}.
beta is the textbook slope cov(x,y)/var(x), NOT the algebraically equal r*sd(y)/sd(x): a flat portfolio (sd(y) = 0, e.g. a shell fund whose value never moves) makes r itself 0/0 = NaN, which then poisons beta and alpha. Dividing by var(x) gives beta 0.0 and alpha mean(y) there.
Single pass over xs/ys accumulating raw sums (no intermediate dtype-next arrays for centered deviations) - ~4x faster than the dfn/-, dfn/* chain this replaced, verified to agree with it to ~1e-10 relative error.
rsq stays r^2, hence still NaN when y has no variance to explain.
Single-factor OLS of ys on xs -> {:beta :alpha :rsq}.
beta is the textbook slope cov(x,y)/var(x), NOT the algebraically equal
r*sd(y)/sd(x): a flat portfolio (sd(y) = 0, e.g. a shell fund whose value
never moves) makes r itself 0/0 = NaN, which then poisons beta and alpha.
Dividing by var(x) gives beta 0.0 and alpha mean(y) there.
Single pass over xs/ys accumulating raw sums (no intermediate dtype-next
arrays for centered deviations) - ~4x faster than the dfn/-, dfn/* chain
this replaced, verified to agree with it to ~1e-10 relative error.
rsq stays r^2, hence still NaN when y has no variance to explain.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |