Module scrilla.analysis.markets
A module of functions that calculate financial statistics.
Expand source code
# This file is part of scrilla: https://github.com/chinchalinchin/scrilla.
# scrilla is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3
# as published by the Free Software Foundation.
# scrilla is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with scrilla. If not, see <https://www.gnu.org/licenses/>
# or <https://github.com/chinchalinchin/scrilla/blob/develop/main/LICENSE>.
"""
A module of functions that calculate financial statistics.
"""
import datetime
from typing import Dict, Union
from datetime import date
from scrilla import settings, services, files, cache, errors
from scrilla.static import keys
from scrilla.analysis.objects.cashflow import Cashflow
import scrilla.analysis.models.geometric.statistics as statistics
import scrilla.util.outputter as outputter
logger = outputter.Logger('scrilla.analysis.markets', settings.LOG_LEVEL)
profile_cache = cache.ProfileCache()
def sharpe_ratio(ticker: str, start_date: Union[date, None] = None, end_date: Union[date, None] = None, risk_free_rate: Union[float, None] = None, ticker_profile: Union[dict, None] = None, method: str = settings.ESTIMATION_METHOD) -> float:
"""
Calculates the sharpe ratio for the supplied ticker over the specified time range. If no start and end date are supplied, calculation will default to the last 100 days of prices. The risk free rate and ticker risk profile can be passed in to force calculations without historical data.
Parameters
----------
1. **ticker**: ``str``
A string of the ticker symbol whose sharpe ratio will be computed.
2. **start_date**: ``datetime.date``
Start date of the time period for which the sharpe ratio will be computed.
3. **end_date**: ``datetime.date``
End_date of the time period for which the sharpe ratio will be computed.
4. **risk_free_rate**: ``float``
Risk free rate used to evaluate excess return. Defaults to settings.RISK_FREE_RATE.
5. **ticker_profile**: ``dict``
Risk-return profile for the supplied ticker. Formatted as follows: `{ 'annual_return': float, 'annual_volatility': float } `
6. **method** : ``str``
Estimation method used to calculate financial statistics. Defaults to the value set by `scrilla.settings.ESTIMATION_METHOD`. Allowable value are accessible through the `scrilla.keys.keys` dictionary.
.. notes::
* if ``ticker_profile`` is provided, this function will skip both an external data service call and the calculation of the ticker's risk profile. The calculation will proceed as if the supplied profile were the true profile. If ``ticker_profile`` is not provided, all statistics will be estimated from historical data.
"""
start_date, end_date = errors.validate_dates(start_date=start_date, end_date=end_date,
asset_type=keys.keys['ASSETS']['EQUITY'])
if ticker_profile is None:
result = profile_cache.filter_profile_cache(
ticker=ticker, start_date=start_date, end_date=end_date, method=method)
if result is not None and result[keys.keys['STATISTICS']['SHARPE']] is not None:
return result[keys.keys['STATISTICS']['SHARPE']]
ticker_profile = statistics.calculate_risk_return(
ticker=ticker, start_date=start_date, end_date=end_date, method=method)
if risk_free_rate is None:
risk_free_rate = services.get_risk_free_rate()
sh_ratio = (ticker_profile['annual_return'] -
risk_free_rate)/ticker_profile['annual_volatility']
profile_cache.save_or_update_row(ticker=ticker, start_date=start_date,
end_date=end_date, sharpe_ratio=sh_ratio, method=method)
return sh_ratio
# if no dates are specified, defaults to last 100 days
def market_premium(start_date: Union[date, None] = None, end_date: Union[date, None] = None, market_profile: Union[dict, None] = None, method: str = settings.ESTIMATION_METHOD) -> float:
"""
Returns the excess of the market return defined by the environment variable `MARKET_PROXY` over the risk free rate defined by the `RISK_FREE` environment variable.
Parameters
----------
1. **start_date**: ``datetime.date``
*Optional*. Start date of the time period for which the market premium will be computed. Defaults to 100 days ago.
2. **end_date**: ``datetime.date``
*Optional*. End_date of the time period for which the market premium will be computed. Defaults to today.
3. **market_profile**: ``dict``
*Optional*. Manually inputted market risk profile. Will override call to `scrilla.analysis.models.geometric.statistics.calculate_risk_return`.
4. **method** : ``str``
*Optional*. Estimation method used to calculate financial statistics. Defaults to the value set by `scrilla.settings.ESTIMATION_METHOD`. Allowable value are accessible through the `scrilla.keys.keys` dictionary.
"""
start_date, end_date = errors.validate_dates(start_date=start_date, end_date=end_date,
asset_type=keys.keys['ASSETS']['EQUITY'])
if market_profile is None:
market_profile = statistics.calculate_risk_return(
ticker=settings.MARKET_PROXY, start_date=start_date, end_date=end_date, method=method)
market_prem = (
market_profile['annual_return'] - services.get_risk_free_rate())
return market_prem
def market_beta(ticker: str, start_date: Union[date, None] = None, end_date: Union[date, None] = None, market_profile: Union[dict, None] = None, market_correlation: Union[dict, None] = None, ticker_profile: Union[dict, None] = None, sample_prices: Union[dict, None] = None, method: str = settings.ESTIMATION_METHOD) -> float:
"""
Returns the beta of an asset against the market return defined by the ticker symbol set `scrilla.settings.MARKET_PROXY`, which in turn is configured through the environment variable of the same name, `MARKET_PROXY`.
Parameters
----------
1. **ticker**: ``str``
A string of the ticker symbol whose asset beta will be computed.
2. **start_date**: ``datetime.date``
Start date of the time period for which the asset beta will be computed.
3. **end_date**: ``datetime.date``
End_date of the time period for which the asset beta will be computed.
4. **method** : ``str``
Estimation method used to calculate financial statistics. Defaults to the value set by `scrilla.settings.ESTIMATION_METHOD`. Allowable value are accessible through the `scrilla.keys.keys` dictionary.
.. notes::
* If not configured by an environment variable, `scrilla.settings.MARKET_PROXY` defaults to ``SPY``, the ETF tracking the *S&P500*.
"""
start_date, end_date = errors.validate_dates(start_date=start_date, end_date=end_date,
asset_type=keys.keys['ASSETS']['EQUITY'])
result = profile_cache.filter_profile_cache(
ticker=ticker, start_date=start_date, end_date=end_date, method=method)
if result is not None and result[keys.keys['STATISTICS']['BETA']] is not None:
return result[keys.keys['STATISTICS']['BETA']]
if market_profile is None:
if sample_prices is None:
market_profile = statistics.calculate_risk_return(ticker=settings.MARKET_PROXY, start_date=start_date,
end_date=end_date, method=method)
else:
market_profile = statistics.calculate_risk_return(ticker=settings.MARKET_PROXY, method=method,
sample_prices=sample_prices[settings.MARKET_PROXY])
if ticker_profile is None:
if sample_prices is None:
ticker_profile = statistics.calculate_risk_return(ticker=ticker, start_date=start_date,
end_date=end_date, method=method)
else:
ticker_profile = statistics.calculate_risk_return(ticker=ticker, method=method,
sample_prices=sample_prices[ticker])
market_covariance = statistics.calculate_return_covariance(ticker_1=ticker, ticker_2=settings.MARKET_PROXY,
profile_1=ticker_profile, profile_2=market_profile,
correlation=market_correlation,
sample_prices=sample_prices,
start_date=start_date, end_date=end_date)
beta = market_covariance / (market_profile['annual_volatility']**2)
profile_cache.save_or_update_row(
ticker=ticker, start_date=start_date, end_date=end_date, asset_beta=beta, method=method)
return beta
def cost_of_equity(ticker: str, start_date: Union[datetime.date, None] = None, end_date: Union[datetime.date, None] = None, market_profile: Union[Dict[str, float], None] = None, market_correlation: Union[Dict[str, float], None] = None, method=settings.ESTIMATION_METHOD) -> float:
"""
Returns the cost of equity of an asset as estimated by the Capital Asset Pricing Model, i.e. the product of the market premium and asset beta increased by the risk free rate.
Parameters
----------
1. **ticker**: ``str``
A string of the ticker symbol whose cost of equity ratio will be computed.
2. **start_date**: ``Union[datetime.date, None]``
*Optional*. Start date of the time period for which the cost of equity ratio will be computed
3. **end_date**: ``Union[datetime.date, None]``
*Optional.* End_date of the time period for which the cost of equity ratio will be computed.
4. **market_profile**: ``Union[Dict[str, float], None]``
*Optional*. Dictionary containing the assumed risk profile for the market proxy. Overrides calls to services and staistical methods, forcing the calculation fo the cost of equity with the inputted market profile. Format: ``{ 'annual_return': value, 'annual_volatility': value}``
5. **market_correlation**: ``Union[Dict[str, float], None]``
*Optional*. Dictionary containing the assumed correlation for the calculation. Overrides calls to services and statistical methods, forcing the calculation of the cost of equity with the inputted correlation. Format: ``{ 'correlation' : value }``
6. **method** : ``str``
*Optional*. Estimation method used to calculate financial statistics. Defaults to the value set by `scrilla.settings.ESTIMATION_METHOD`. Allowable value are accessible through the `scrilla.keys.keys` dictionary.
"""
start_date, end_date = errors.validate_dates(start_date=start_date, end_date=end_date,
asset_type=keys.keys['ASSETS']['EQUITY'])
result = profile_cache.filter_profile_cache(
ticker=ticker, start_date=start_date, end_date=end_date, method=method)
if result is not None and result[keys.keys['STATISTICS']['EQUITY']] is not None:
return result[keys.keys['STATISTICS']['EQUITY']]
beta = market_beta(ticker=ticker, start_date=start_date, end_date=end_date,
market_profile=market_profile, market_correlation=market_correlation,
method=method)
premium = market_premium(start_date=start_date, end_date=end_date,
market_profile=market_profile, method=method)
equity_cost = (premium*beta + services.get_risk_free_rate())
profile_cache.save_or_update_row(
ticker=ticker, start_date=start_date, end_date=end_date, equity_cost=equity_cost, method=method)
return equity_cost
def screen_for_discount(model: str = keys.keys['MODELS']['DDM'], discount_rate: float = None) -> Dict[str, Dict[str, float]]:
"""
Screens the stocks saved under the user watchlist in the `scrilla.settings.COMMON_DIR` directory for discounts relative to the model inputted into the function.
Parameters
----------
1. **model** : ``str``
*Optional*. Model used to evaluated the equities saved in the watchlist. If no model is specified, the function will default to the discount dividend model. Model constants are accessible through the the `scrilla.keys.keys` dictionary.
2. **discount_rate** : ``float``
*Optional*. Rate used to discount future cashflows to present. Defaults to an equity's CAPM cost of equity, as calculated by `scrilla.analysis.markets.cost_of_equity`.
Returns
-------
``dict``
A list of tickers that trade at a discount relative to the model price, formatted as follows: `{ 'ticker' : { 'spot_price': value, 'model_price': value,'discount': value }, ... }`
"""
equities = list(files.get_watchlist())
discounts = {}
user_discount_rate = discount_rate
for equity in equities:
spot_price = services.get_daily_price_latest(ticker=equity)
if user_discount_rate is None:
discount_rate = cost_of_equity(ticker=equity)
else:
discount_rate = user_discount_rate
if model == keys.keys['MODELS']['DDM']:
logger.debug(
'Using Discount Dividend Model to screen watchlisted equities for discounts.')
dividends = services.get_dividend_history(equity)
model_price = Cashflow(
sample=dividends, discount_rate=discount_rate).calculate_net_present_value()
discount = float(model_price) - float(spot_price)
if discount > 0:
discount_result = {'spot_price': spot_price,
'model_price': model_price, 'discount': discount}
discounts[equity] = discount_result
logger.debug(f'Discount of {discount} found for {equity}')
return discounts
Functions
def cost_of_equity(ticker: str, start_date: Optional[datetime.date] = None, end_date: Optional[datetime.date] = None, market_profile: Optional[Dict[str, float]] = None, market_correlation: Optional[Dict[str, float]] = None, method='moments') ‑> float
-
Returns the cost of equity of an asset as estimated by the Capital Asset Pricing Model, i.e. the product of the market premium and asset beta increased by the risk free rate.
Parameters
- ticker:
str
A string of the ticker symbol whose cost of equity ratio will be computed. - start_date:
Union[datetime.date, None]
Optional. Start date of the time period for which the cost of equity ratio will be computed - end_date:
Union[datetime.date, None]
Optional. End_date of the time period for which the cost of equity ratio will be computed. - market_profile:
Union[Dict[str, float], None]
Optional. Dictionary containing the assumed risk profile for the market proxy. Overrides calls to services and staistical methods, forcing the calculation fo the cost of equity with the inputted market profile. Format:{ 'annual_return': value, 'annual_volatility': value}
- market_correlation:
Union[Dict[str, float], None]
Optional. Dictionary containing the assumed correlation for the calculation. Overrides calls to services and statistical methods, forcing the calculation of the cost of equity with the inputted correlation. Format:{ 'correlation' : value }
- method :
str
Optional. Estimation method used to calculate financial statistics. Defaults to the value set byESTIMATION_METHOD
. Allowable value are accessible through thescrilla.keys.keys
dictionary.
Expand source code
def cost_of_equity(ticker: str, start_date: Union[datetime.date, None] = None, end_date: Union[datetime.date, None] = None, market_profile: Union[Dict[str, float], None] = None, market_correlation: Union[Dict[str, float], None] = None, method=settings.ESTIMATION_METHOD) -> float: """ Returns the cost of equity of an asset as estimated by the Capital Asset Pricing Model, i.e. the product of the market premium and asset beta increased by the risk free rate. Parameters ---------- 1. **ticker**: ``str`` A string of the ticker symbol whose cost of equity ratio will be computed. 2. **start_date**: ``Union[datetime.date, None]`` *Optional*. Start date of the time period for which the cost of equity ratio will be computed 3. **end_date**: ``Union[datetime.date, None]`` *Optional.* End_date of the time period for which the cost of equity ratio will be computed. 4. **market_profile**: ``Union[Dict[str, float], None]`` *Optional*. Dictionary containing the assumed risk profile for the market proxy. Overrides calls to services and staistical methods, forcing the calculation fo the cost of equity with the inputted market profile. Format: ``{ 'annual_return': value, 'annual_volatility': value}`` 5. **market_correlation**: ``Union[Dict[str, float], None]`` *Optional*. Dictionary containing the assumed correlation for the calculation. Overrides calls to services and statistical methods, forcing the calculation of the cost of equity with the inputted correlation. Format: ``{ 'correlation' : value }`` 6. **method** : ``str`` *Optional*. Estimation method used to calculate financial statistics. Defaults to the value set by `scrilla.settings.ESTIMATION_METHOD`. Allowable value are accessible through the `scrilla.keys.keys` dictionary. """ start_date, end_date = errors.validate_dates(start_date=start_date, end_date=end_date, asset_type=keys.keys['ASSETS']['EQUITY']) result = profile_cache.filter_profile_cache( ticker=ticker, start_date=start_date, end_date=end_date, method=method) if result is not None and result[keys.keys['STATISTICS']['EQUITY']] is not None: return result[keys.keys['STATISTICS']['EQUITY']] beta = market_beta(ticker=ticker, start_date=start_date, end_date=end_date, market_profile=market_profile, market_correlation=market_correlation, method=method) premium = market_premium(start_date=start_date, end_date=end_date, market_profile=market_profile, method=method) equity_cost = (premium*beta + services.get_risk_free_rate()) profile_cache.save_or_update_row( ticker=ticker, start_date=start_date, end_date=end_date, equity_cost=equity_cost, method=method) return equity_cost
- ticker:
def market_beta(ticker: str, start_date: Optional[datetime.date] = None, end_date: Optional[datetime.date] = None, market_profile: Optional[dict] = None, market_correlation: Optional[dict] = None, ticker_profile: Optional[dict] = None, sample_prices: Optional[dict] = None, method: str = 'moments') ‑> float
-
Returns the beta of an asset against the market return defined by the ticker symbol set
MARKET_PROXY
, which in turn is configured through the environment variable of the same name,MARKET_PROXY
.Parameters
- ticker:
str
A string of the ticker symbol whose asset beta will be computed. - start_date:
datetime.date
Start date of the time period for which the asset beta will be computed. - end_date:
datetime.date
End_date of the time period for which the asset beta will be computed. - method :
str
Estimation method used to calculate financial statistics. Defaults to the value set byESTIMATION_METHOD
. Allowable value are accessible through thescrilla.keys.keys
dictionary.
Notes
- If not configured by an environment variable,
MARKET_PROXY
defaults toSPY
, the ETF tracking the S&P500.
Expand source code
def market_beta(ticker: str, start_date: Union[date, None] = None, end_date: Union[date, None] = None, market_profile: Union[dict, None] = None, market_correlation: Union[dict, None] = None, ticker_profile: Union[dict, None] = None, sample_prices: Union[dict, None] = None, method: str = settings.ESTIMATION_METHOD) -> float: """ Returns the beta of an asset against the market return defined by the ticker symbol set `scrilla.settings.MARKET_PROXY`, which in turn is configured through the environment variable of the same name, `MARKET_PROXY`. Parameters ---------- 1. **ticker**: ``str`` A string of the ticker symbol whose asset beta will be computed. 2. **start_date**: ``datetime.date`` Start date of the time period for which the asset beta will be computed. 3. **end_date**: ``datetime.date`` End_date of the time period for which the asset beta will be computed. 4. **method** : ``str`` Estimation method used to calculate financial statistics. Defaults to the value set by `scrilla.settings.ESTIMATION_METHOD`. Allowable value are accessible through the `scrilla.keys.keys` dictionary. .. notes:: * If not configured by an environment variable, `scrilla.settings.MARKET_PROXY` defaults to ``SPY``, the ETF tracking the *S&P500*. """ start_date, end_date = errors.validate_dates(start_date=start_date, end_date=end_date, asset_type=keys.keys['ASSETS']['EQUITY']) result = profile_cache.filter_profile_cache( ticker=ticker, start_date=start_date, end_date=end_date, method=method) if result is not None and result[keys.keys['STATISTICS']['BETA']] is not None: return result[keys.keys['STATISTICS']['BETA']] if market_profile is None: if sample_prices is None: market_profile = statistics.calculate_risk_return(ticker=settings.MARKET_PROXY, start_date=start_date, end_date=end_date, method=method) else: market_profile = statistics.calculate_risk_return(ticker=settings.MARKET_PROXY, method=method, sample_prices=sample_prices[settings.MARKET_PROXY]) if ticker_profile is None: if sample_prices is None: ticker_profile = statistics.calculate_risk_return(ticker=ticker, start_date=start_date, end_date=end_date, method=method) else: ticker_profile = statistics.calculate_risk_return(ticker=ticker, method=method, sample_prices=sample_prices[ticker]) market_covariance = statistics.calculate_return_covariance(ticker_1=ticker, ticker_2=settings.MARKET_PROXY, profile_1=ticker_profile, profile_2=market_profile, correlation=market_correlation, sample_prices=sample_prices, start_date=start_date, end_date=end_date) beta = market_covariance / (market_profile['annual_volatility']**2) profile_cache.save_or_update_row( ticker=ticker, start_date=start_date, end_date=end_date, asset_beta=beta, method=method) return beta
- ticker:
-
Returns the excess of the market return defined by the environment variable
MARKET_PROXY
over the risk free rate defined by theRISK_FREE
environment variable.Parameters
- start_date:
datetime.date
Optional. Start date of the time period for which the market premium will be computed. Defaults to 100 days ago. - end_date:
datetime.date
Optional. End_date of the time period for which the market premium will be computed. Defaults to today. - market_profile:
dict
Optional. Manually inputted market risk profile. Will override call tocalculate_risk_return()
. - method :
str
Optional. Estimation method used to calculate financial statistics. Defaults to the value set byESTIMATION_METHOD
. Allowable value are accessible through thescrilla.keys.keys
dictionary.
Expand source code
def market_premium(start_date: Union[date, None] = None, end_date: Union[date, None] = None, market_profile: Union[dict, None] = None, method: str = settings.ESTIMATION_METHOD) -> float: """ Returns the excess of the market return defined by the environment variable `MARKET_PROXY` over the risk free rate defined by the `RISK_FREE` environment variable. Parameters ---------- 1. **start_date**: ``datetime.date`` *Optional*. Start date of the time period for which the market premium will be computed. Defaults to 100 days ago. 2. **end_date**: ``datetime.date`` *Optional*. End_date of the time period for which the market premium will be computed. Defaults to today. 3. **market_profile**: ``dict`` *Optional*. Manually inputted market risk profile. Will override call to `scrilla.analysis.models.geometric.statistics.calculate_risk_return`. 4. **method** : ``str`` *Optional*. Estimation method used to calculate financial statistics. Defaults to the value set by `scrilla.settings.ESTIMATION_METHOD`. Allowable value are accessible through the `scrilla.keys.keys` dictionary. """ start_date, end_date = errors.validate_dates(start_date=start_date, end_date=end_date, asset_type=keys.keys['ASSETS']['EQUITY']) if market_profile is None: market_profile = statistics.calculate_risk_return( ticker=settings.MARKET_PROXY, start_date=start_date, end_date=end_date, method=method) market_prem = ( market_profile['annual_return'] - services.get_risk_free_rate()) return market_prem
- start_date:
def screen_for_discount(model: str = 'discount_dividend', discount_rate: float = None) ‑> Dict[str, Dict[str, float]]
-
Screens the stocks saved under the user watchlist in the
COMMON_DIR
directory for discounts relative to the model inputted into the function.Parameters
- model :
str
Optional. Model used to evaluated the equities saved in the watchlist. If no model is specified, the function will default to the discount dividend model. Model constants are accessible through the thescrilla.keys.keys
dictionary. - discount_rate :
float
Optional. Rate used to discount future cashflows to present. Defaults to an equity's CAPM cost of equity, as calculated bycost_of_equity()
.
Returns
dict
A list of tickers that trade at a discount relative to the model price, formatted as follows:{ 'ticker' : { 'spot_price': value, 'model_price': value,'discount': value }, ... }
Expand source code
def screen_for_discount(model: str = keys.keys['MODELS']['DDM'], discount_rate: float = None) -> Dict[str, Dict[str, float]]: """ Screens the stocks saved under the user watchlist in the `scrilla.settings.COMMON_DIR` directory for discounts relative to the model inputted into the function. Parameters ---------- 1. **model** : ``str`` *Optional*. Model used to evaluated the equities saved in the watchlist. If no model is specified, the function will default to the discount dividend model. Model constants are accessible through the the `scrilla.keys.keys` dictionary. 2. **discount_rate** : ``float`` *Optional*. Rate used to discount future cashflows to present. Defaults to an equity's CAPM cost of equity, as calculated by `scrilla.analysis.markets.cost_of_equity`. Returns ------- ``dict`` A list of tickers that trade at a discount relative to the model price, formatted as follows: `{ 'ticker' : { 'spot_price': value, 'model_price': value,'discount': value }, ... }` """ equities = list(files.get_watchlist()) discounts = {} user_discount_rate = discount_rate for equity in equities: spot_price = services.get_daily_price_latest(ticker=equity) if user_discount_rate is None: discount_rate = cost_of_equity(ticker=equity) else: discount_rate = user_discount_rate if model == keys.keys['MODELS']['DDM']: logger.debug( 'Using Discount Dividend Model to screen watchlisted equities for discounts.') dividends = services.get_dividend_history(equity) model_price = Cashflow( sample=dividends, discount_rate=discount_rate).calculate_net_present_value() discount = float(model_price) - float(spot_price) if discount > 0: discount_result = {'spot_price': spot_price, 'model_price': model_price, 'discount': discount} discounts[equity] = discount_result logger.debug(f'Discount of {discount} found for {equity}') return discounts
- model :
def sharpe_ratio(ticker: str, start_date: Optional[datetime.date] = None, end_date: Optional[datetime.date] = None, risk_free_rate: Optional[float] = None, ticker_profile: Optional[dict] = None, method: str = 'moments') ‑> float
-
Calculates the sharpe ratio for the supplied ticker over the specified time range. If no start and end date are supplied, calculation will default to the last 100 days of prices. The risk free rate and ticker risk profile can be passed in to force calculations without historical data.
Parameters
- ticker:
str
A string of the ticker symbol whose sharpe ratio will be computed. - start_date:
datetime.date
Start date of the time period for which the sharpe ratio will be computed. - end_date:
datetime.date
End_date of the time period for which the sharpe ratio will be computed. - risk_free_rate:
float
Risk free rate used to evaluate excess return. Defaults to settings.RISK_FREE_RATE. - ticker_profile:
dict
Risk-return profile for the supplied ticker. Formatted as follows:{ 'annual_return': float, 'annual_volatility': float }
- method :
str
Estimation method used to calculate financial statistics. Defaults to the value set byESTIMATION_METHOD
. Allowable value are accessible through thescrilla.keys.keys
dictionary.
Notes
- if
ticker_profile
is provided, this function will skip both an external data service call and the calculation of the ticker's risk profile. The calculation will proceed as if the supplied profile were the true profile. Ifticker_profile
is not provided, all statistics will be estimated from historical data.
Expand source code
def sharpe_ratio(ticker: str, start_date: Union[date, None] = None, end_date: Union[date, None] = None, risk_free_rate: Union[float, None] = None, ticker_profile: Union[dict, None] = None, method: str = settings.ESTIMATION_METHOD) -> float: """ Calculates the sharpe ratio for the supplied ticker over the specified time range. If no start and end date are supplied, calculation will default to the last 100 days of prices. The risk free rate and ticker risk profile can be passed in to force calculations without historical data. Parameters ---------- 1. **ticker**: ``str`` A string of the ticker symbol whose sharpe ratio will be computed. 2. **start_date**: ``datetime.date`` Start date of the time period for which the sharpe ratio will be computed. 3. **end_date**: ``datetime.date`` End_date of the time period for which the sharpe ratio will be computed. 4. **risk_free_rate**: ``float`` Risk free rate used to evaluate excess return. Defaults to settings.RISK_FREE_RATE. 5. **ticker_profile**: ``dict`` Risk-return profile for the supplied ticker. Formatted as follows: `{ 'annual_return': float, 'annual_volatility': float } ` 6. **method** : ``str`` Estimation method used to calculate financial statistics. Defaults to the value set by `scrilla.settings.ESTIMATION_METHOD`. Allowable value are accessible through the `scrilla.keys.keys` dictionary. .. notes:: * if ``ticker_profile`` is provided, this function will skip both an external data service call and the calculation of the ticker's risk profile. The calculation will proceed as if the supplied profile were the true profile. If ``ticker_profile`` is not provided, all statistics will be estimated from historical data. """ start_date, end_date = errors.validate_dates(start_date=start_date, end_date=end_date, asset_type=keys.keys['ASSETS']['EQUITY']) if ticker_profile is None: result = profile_cache.filter_profile_cache( ticker=ticker, start_date=start_date, end_date=end_date, method=method) if result is not None and result[keys.keys['STATISTICS']['SHARPE']] is not None: return result[keys.keys['STATISTICS']['SHARPE']] ticker_profile = statistics.calculate_risk_return( ticker=ticker, start_date=start_date, end_date=end_date, method=method) if risk_free_rate is None: risk_free_rate = services.get_risk_free_rate() sh_ratio = (ticker_profile['annual_return'] - risk_free_rate)/ticker_profile['annual_volatility'] profile_cache.save_or_update_row(ticker=ticker, start_date=start_date, end_date=end_date, sharpe_ratio=sh_ratio, method=method) return sh_ratio
- ticker: