DiscreteAllocation¶
- class amplpyfinance.DiscreteAllocation(weights, latest_prices, total_portfolio_value=10000, short_ratio=None)[source]¶
Generate a discrete portfolio allocation from continuous weights.
AMPL version of
pypfopt.DiscreteAllocation
with similar interface. This class is also available under the aliasamplpyfinance.DiscreteAllocationWithAMPL
in order to distinguish frompypfopt.DiscreteAllocation
if used together.Instance variables:
Inputs:
weights
- dictlatest_prices
- pd.Series or dicttotal_portfolio_value
- int/floatshort_ratio
- float
Output:
allocation
- dict
Public methods:
greedy_portfolio()
- uses a greedy algorithmlp_portfolio()
- uses linear programming
- __init__(weights, latest_prices, total_portfolio_value=10000, short_ratio=None)[source]¶
- Parameters
weights (dict) – continuous weights generated from the
efficient_frontier
modulelatest_prices (pd.Series) – the most recent price for each asset
total_portfolio_value (int/float, optional) – the desired total value of the portfolio, defaults to 10000
short_ratio (float, defaults to None.) – the short ratio, e.g 0.3 corresponds to 130/30. If None, defaults to the input weights.
- Raises
TypeError – if
weights
is not a dictTypeError – if
latest_prices
isn’t a seriesValueError – if
short_ratio < 0
- lp_portfolio(reinvest=False, verbose=False, solver='gurobi', solver_options=None)[source]¶
Convert continuous weights into a discrete portfolio allocation using integer programming.
Model from pypfopt:
\(T \in \mathbb{R}\) is the total dollar value to be allocated
\(p \in \mathbb{R}^n\) is the array of latest prices
\(w \in \mathbb{R}^n\) is the set of target weights
\(x \in \mathbb{Z}^n\) is the integer allocation (i.e the result)
\(r \in \mathbb{R}\) is the remaining unallocated value, i.e \(r = T - x \cdot p\).
The optimization problem is then given by:
\[\begin{split}\begin{equation*} \begin{aligned} & \underset{x \in \mathbb{Z}^n}{\text{minimize}} & & r + \lVert wT - x \odot p \rVert_1 \\ & \text{subject to} & & r + x \cdot p = T\\ \end{aligned} \end{equation*}\end{split}\]Corresponding AMPL code:
param n; param p{1..n}; param w{1..n}; param total_portfolio_value; var x{1..n} >= 0 integer; var u{1..n} >= 0; var r >= 0; minimize objective: r + sum{i in 1..n} u[i]; s.t. norm1{i in 1..n}: u[i] >= w[i] * total_portfolio_value - x[i] * p[i]; s.t. norm2{i in 1..n}: -u[i] <= w[i] * total_portfolio_value - x[i] * p[i]; s.t. total_value: r + sum{i in 1..n} x[i] * p[i] = total_portfolio_value;
ampl.param["n"] = len(latest_prices) ampl.param["p"] = latest_prices ampl.param["w"] = weights ampl.param["total_portfolio_value"] = total_portfolio_value ampl.solve()
AMPL version of
pypfopt.DiscreteAllocation.lp_portfolio()
with similar interface:- Parameters
reinvest (bool, defaults to False) – whether or not to reinvest cash gained from shorting
verbose (bool) – print error analysis?
solver (str) – name of the AMPL solver to use.
solver_options (str) – options for the given solver
- Returns
the number of shares of each ticker that should be purchased, along with the amount of funds leftover.
- Return type
(dict, float)
- __module__ = 'amplpyfinance.discrete_allocation'¶