Calculate the weights of the portfolio with the highest Omega ratio over the historical returns: the gains above a minimum acceptable return divided by the losses below it. The Omega ratio uses the whole return distribution instead of its mean and variance, so it rewards positive skew and penalizes fat left tails that a Sharpe ratio overlooks.

With τ the minimum acceptable return, Ω(w) = 1 + (r̄’w - τ) / E[max(0, τ - r_t’w)]. This ratio is maximized exactly as a linear programme with the Charnes-Cooper transformation: with y = κw and κ > 0, maximize r̄’y - τκ subject to Σ max(0, τκ - r_t’y) / T = 1 and the weight constraints, then w = y / κ.

For more information, see the following papers:

  • Keating, C. and Shadwick, W. F. (2002). “A Universal Performance Measure.” Journal of Performance Measurement, 6(3), 59-84.
  • Kapsos, M., Christofides, N. and Rustem, B. (2014). “Worst-Case Robust Omega Ratio.” European Journal of Operational Research, 234(2), 499-507.

Also known as: Omega optimization, maximum gain-loss ratio.

Maximum Omega Ratio in Python or via the MCP

Install the Finance Toolkit with:

pip install financetoolkit -U

Then call get_maximum_omega_weights as shown below.

from financetoolkit import Toolkit

toolkit = Toolkit(
    ["AAPL", "MSFT", "JNJ", "XOM"],
    api_key="FINANCIAL_MODELING_PREP_KEY",
    start_date="2021-01-01",
    end_date="2025-12-31",
)

toolkit.portfolio.get_maximum_omega_weights()[
    ["Weight", "Expected Return", "Volatility", "Risk Contribution", "Omega Ratio"]
]

Or, after setting up the Finance Toolkit MCP, ask:

Which weights in Apple, Microsoft, Johnson & Johnson and ExxonMobil maximized the Omega ratio, based on 2021 to 2025?

Which returns:

  Weight Expected Return Volatility Risk Contribution Omega Ratio
AAPL 0.0594 0.1932 0.2786 0.0615 1.1306
MSFT 0.2822 0.2017 0.2571 0.2875 1.1459
JNJ 0.2697 0.0987 0.1673 0.1258 1.1083
XOM 0.3887 0.2911 0.2702 0.5251 1.1954
Portfolio 1 0.2082 0.1551 1 1.2567

Parameters

get_maximum_omega_weights accepts the following parameters.

ParameterTypeDescriptionExample
minimum_acceptable_returnfloatThe threshold between gains and losses, as a return per period of the chosen frequency (e.g. 0.0002 a day). Defaults to 0.0.001
periodstrThe frequency of the returns (daily, weekly, monthly, quarterly or yearly). Defaults to “daily”."weekly"
expected_returnsstrThe estimator of the expected returns: “mean” (the historical average), “exponential” (the exponentially weighted average, recent periods weigh most), “capm” (the returns the Capital Asset Pricing Model implies from each asset’s beta to the benchmark, Sharpe, 1964) or “james_stein” (the averages shrunk towards that of the minimum variance portfolio, Jorion, 1986). Defaults to “mean”."mean"
expected_returns_spanintThe span in periods of the “exponential” expected returns. Defaults to 180.180
minimum_weightfloat | dict[str, float]The lowest weight of every asset, or per asset, e.g. {“AAPL”: 0.05} (the others keep 0); a negative value allows short positions. Defaults to 0.0
maximum_weightfloat | dict[str, float]The highest weight of every asset, or per asset, e.g. {“AAPL”: 0.3} (the others keep 1). Defaults to 1.1
sector_boundsdict[str, tuple[float, float]] | NoneThe minimum and maximum total weight per sector, e.g. {“Technology”: (0, 0.4)}, with the sector of each asset from its company profile. Defaults to None.None
country_boundsdict[str, tuple[float, float]] | NoneThe minimum and maximum total weight per country, named in full or by its two-letter code, e.g. {“United States”: (0, 0.6)}, with the country of each asset from its company profile. Defaults to None.None
net_exposurefloatThe sum of the weights: 1 for a fully invested portfolio, 0 for a market neutral one. Defaults to 1.1
gross_exposurefloat | NoneThe highest sum of the absolute weights, which limits the leverage of a long-short portfolio, e.g. 1.6 for a 130/30 portfolio. Defaults to None, no limit.None, no limit
current_weightsdict[str, float] | NoneThe weights held now, e.g. {“AAPL”: 0.5, “MSFT”: 0.5} (an asset left out is not held), which the turnover is measured from; they add a Turnover column, |w_i - w0_i| per asset and its sum for the portfolio. Defaults to None, which uses the latest weights of the Portfolio the Toolkit came from when a maximum turnover needs them.None, which uses the latest weights of the Portfolio the Toolkit came from when a maximum turnover needs them
maximum_turnoverfloat | NoneThe highest turnover Σ |w_i - w0_i| from the current weights, e.g. 0.2 to trade at most 10% of the portfolio each way. Defaults to None, no limit.None, no limit
include_benchmarkboolWhether to include the benchmark as an asset. Defaults to False.True
roundingint | NoneThe number of decimals to round the results to. Defaults to None, which uses the Toolkit’s rounding.2
Share