8000 Fix Quantlib and pandas deprecations by cdcadman · Pull Request #8 · aaronsmith1234/volatilipy · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Fix Quantlib and pandas deprecations #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
=======
History
=======
0.1.4 (2023-01-17)
------------------
* Fix Quantlib deprecations in ActualActual() and UnitedStates().
* Fix pandas FutureWarning involving numeric_only default value.

0.1.3 (2022-10-11)
------------------
* Drop the 'how' parameter from _drop_sparse_columns() for coherence with Pandas 1.5.0
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pandas>=1.1.4
QuantLib>=1.20
pandas>=1.3.4
QuantLib>=1.24
2 changes: 1 addition & 1 deletion volatilipy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

__author__ = """Aaron Smith"""
__email__ = "aaronsmith1234@gmail.com"
__version__ = "0.1.3"
__version__ = "0.1.4"

# pylint: disable=unused-import

Expand Down
86 changes: 13 additions & 73 deletions volatilipy/helper_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,36 +98,14 @@ def _generate_date_df(
date_df = date_df.to_frame(index=True, name="expiryDate")
date_df["QuantlibDate"] = date_df.apply(_datetime_to_quantlib_date, axis=1)
date_df["tau"] = date_df.apply(
_calculate_tau, args=(vol_surface.referenceDate(), ql.ActualActual()), axis=1
_calculate_tau, args=(vol_surface.referenceDate(), ql.ActualActual(ql.ActualActual.ISDA)), axis=1
)
date_df["days_to_maturity"] = date_df.apply(
_calculate_dtm, args=(vol_surface.referenceDate(), ql.ActualActual()), axis=1
_calculate_dtm, args=(vol_surface.referenceDate(), ql.ActualActual(ql.ActualActual.ISDA)), axis=1
)
return date_df


def _calculate_tau(
end_date: ql.Date,
start_date: ql.Date,
day_count_convention: ql.DayCounter,
) -> float:
"""Function to calculate a tau/difference in time from Quantlib objects

Args:
end_date (ql.Date): End date
start_date (ql.Date): Start date
day_count_convention (ql.DayCounter): What basis of days to use;
ActualActual, 30/360, etc.

Returns:
float: tau in years of the difference between the two dates
"""

if isinstance(end_date, pd.core.series.Series):
end_date = end_date["QuantlibDate"]
return day_count_convention.yearFraction(start_date, end_date)


def _calculate_dtm(
end_date: ql.Date,
start_date: ql.Date,
Expand Down Expand Up @@ -196,34 +174,6 @@ def _create_ql_vol_grid(
return implied_vols


# Helper functions for the implied vol object
def _get_option_rfr(
risk_free_rates: pd.DataFrame,
position: namedtuple,
day_count_convention: ql.DayCounter,
rate_column_name: str,
) -> float:
"""Method to pull market data that is specific to one option (namely volatility
and a risk free rate)

Args:
risk_free_rates (pd.DataFrame): Dataframe containing risk free rates. Used to
pull the risk free rate corresponding to the date of maturity of the option
position (namedtuple): A named tuple that represents one option position; used to
retrieve the maturity date and strike
day_count_convention (QuantLibday_count_convention): Method to determine how to count days
between two dates
Returns:
risk_free_rate: The risk free rate
"""

rate = ql.SimpleQuote(risk_free_rates[rate_column_name][position.exercise_date])
risk_free_rate = ql.FlatForward(
0, ql.TARGET(), ql.QuoteHandle(rate), day_count_convention
)
return (risk_free_rate,)


def _setup_quantlib_economy(
valuation_date: datetime, index_values: float64, dividend_yields: float64
) -> Tuple:
Expand All @@ -241,7 +191,7 @@ def _setup_quantlib_economy(
valuation_date.day, valuation_date.month, valuation_date.year
)
ql.Settings.instance().evaluationDate = valuation_date_for_quantlib
day_count_convention = ql.ActualActual()
day_count_convention = ql.ActualActual(ql.ActualActual.ISDA)

spot = index_values
spot_quote = ql.QuoteHandle(ql.SimpleQuote(spot))
Expand Down Expand Up @@ -337,7 +287,7 @@ def _average_across_options(
option_df.groupby(
[column_name_mapping["strike"], column_name_mapping["expiration"]]
)
.mean()
.mean(numeric_only=True)
.reset_index()
)

Expand Down Expand Up @@ -405,10 +355,8 @@ def _drop_valdate_row(option_df: pd.DataFrame, valuation_date: date) -> pd.DataF
pd.Timestamp(valuation_date) in option_df.index
or valuation_date in option_df.index
):
cleaned_df = option_df.drop([valuation_date])
else:
cleaned_df = option_df
return cleaned_df
option_df = option_df.drop([valuation_date])
return option_df


def _sort_df(option_df: pd.DataFrame):
Expand All @@ -425,31 +373,23 @@ def _datetime_to_quantlib_date(
Args:
input_datetime (Union[datetime, pd.Series]): Either a datetime object or a pandas
series object that contains datetime objects
datetime_column_name (str, Optional): the index value of the datetime to convert.
This is only used if input_datetime is a Series containing more than one row.
Optional, defaults to 'exercise_date'.

Returns:
ql.Date: The same dates, represented as Quantlib objects
"""
if isinstance(input_datetime, pd.core.series.Series):
cols = input_datetime.shape[0]
if cols > 1:
return_date = ql.Date(
input_datetime.loc[datetime_column_name].day,
input_datetime.loc[datetime_column_name].month,
input_datetime.loc[datetime_column_name].year,
)
if len(input_datetime.index) > 1:
input_datetime = input_datetime.loc[datetime_column_name]
else:
return_date = ql.Date(
input_datetime[0].day,
input_datetime[0].month,
input_datetime[0].year,
)
else:
return_date = ql.Date(
input_datetime = input_datetime[0]
return ql.Date(
input_datetime.day,
input_datetime.month,
input_datetime.year,
)
return return_date


def _create_quantlib_option(dataframe_row: pd.Series) -> ql.EuropeanOption:
Expand Down
8 changes: 4 additions & 4 deletions volatilipy/volatility_surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ class VolatilitySurface(ql.BlackVarianceSurface):
Args:
options_data (OptionsData): Options data on which to fit the surface
day_count (ql.DayCounter, optional): Day counter to use with Quantlib.
Defaults to ql.ActualActual().
Defaults to ql.ActualActual(ql.ActualActual.ISDA).
calendar (ql.Calendar, optional): Calendar to use with Quantlib.
Defaults to ql.UnitedStates().
Defaults to ql.UnitedStates(ql.UnitedStates.Settlement).
allow_extrapolation (boolean, optional): Flag to enable extrapolation.
Defaults to False, consistent with Quantlib.
interpolation_method (str, optional): Define interpolation method to use.
Expand All @@ -39,8 +39,8 @@ def __init__(
self,
options_data: OptionsData = None,
volatility_grid: pd.DataFrame = None,
day_count: ql.DayCounter = ql.ActualActual(),
calendar: ql.Calendar = ql.UnitedStates(),
day_count: ql.DayCounter = ql.ActualActual(ql.ActualActual.ISDA),
calendar: ql.Calendar = ql.UnitedStates(ql.UnitedStates.Settlement),
allow_extrapolation: bool = False,
valuation_date: datetime = None,
interpolation_method: str = "Bilinear",
Expand Down
0