def delta_underlying(self, date, spot_price, base_date, vol_last_available=False, dvd_tax_adjust=1, last_available=True, exercise_ovrd=None): """ :param date: date-like The date. :param spot_price: float The underlying spot prices used for evaluation. :param base_date: date-like When date is a future date base_date is the last date on the "present" used to estimate future values. :param vol_last_available: bool, optional Whether to use last available data in case dates are missing in volatility values. :param dvd_tax_adjust: float, default=1 The multiplier used to adjust for dividend tax. For example, US dividend taxes are 30% so you pass 0.7. :param last_available: bool, optional Whether to use last available data in case dates are missing in ``quotes``. :param exercise_ovrd: str, optional Used to force the option model to use a specific type of option. Only working for American and European option types. :return: float The option delta based on the date and underlying spot price. """ ql.Settings.instance().evaluationDate = to_ql_date(date) if to_datetime(date) > to_datetime(base_date): option = self.option_engine(date=base_date, vol_last_available=vol_last_available, dvd_tax_adjust=dvd_tax_adjust, last_available=last_available, exercise_ovrd=exercise_ovrd) else: option = self.option_engine(date=date, vol_last_available=vol_last_available, dvd_tax_adjust=dvd_tax_adjust, last_available=last_available, exercise_ovrd=exercise_ovrd) self.ql_process.spot_price_update(date=date, underlying_name=self.underlying_instrument, spot_price=spot_price) self.option.setPricingEngine(ql_option_engine(self.ql_process.bsm_process)) return option.delta()
def underlying_price(self, date, base_date, vol_last_available=False, dvd_tax_adjust=1, last_available=True, exercise_ovrd=None): """ :param date: date-like The date. :param base_date: date-like When date is a future date base_date is the last date on the "present" used to estimate future values. :param vol_last_available: bool, optional Whether to use last available data in case dates are missing in volatility values. :param dvd_tax_adjust: float, default=1 The multiplier used to adjust for dividend tax. For example, US dividend taxes are 30% so you pass 0.7. :param last_available: bool, optional Whether to use last available data in case dates are missing in ``quotes``. :param exercise_ovrd: str, optional Used to force the option model to use a specific type of option. Only working for American and European option types. :return: float The option underlying spot price. """ ql.Settings.instance().evaluationDate = to_ql_date(date) dt_maturity = to_datetime(self.option_maturity) if to_datetime(date) >= dt_maturity: return 0 else: ql.Settings.instance().evaluationDate = to_ql_date(date) if to_datetime(date) > to_datetime(base_date): self.option_engine(date=base_date, vol_last_available=vol_last_available, dvd_tax_adjust=dvd_tax_adjust, last_available=last_available, exercise_ovrd=exercise_ovrd) else: self.option_engine(date=date, vol_last_available=vol_last_available, dvd_tax_adjust=dvd_tax_adjust, last_available=last_available, exercise_ovrd=exercise_ovrd) return self.ql_process.spot_price_handle.value()
def filter_series(df, initial_date=None, final_date=None): """ Filter inplace a pandas.Series to keep its index between an initial and a final date. :param df: :py:obj:`pandas.Series` Series to be filtered. :param initial_date: date-like Initial date. :param final_date: date-like Final date. :return """ if initial_date is None and final_date is not None: final_date = to_datetime(final_date) df.drop(df[(df.index > final_date)].index, inplace=True) elif final_date is None and initial_date is not None: initial_date = to_datetime(initial_date) df.drop(df[(df.index < initial_date)].index, inplace=True) elif final_date is None and initial_date is None: pass elif initial_date == final_date: initial_date = to_datetime(initial_date) df.drop(df[(df.index != initial_date)].index, inplace=True) else: initial_date = to_datetime(initial_date) final_date = to_datetime(final_date) df.drop(df[(df.index < initial_date) | (df.index > final_date)].index, inplace=True)
def dividend_yield_update(self, date, calendar, day_counter, underlying_name, dividend_yield=None, dvd_tax_adjust=1, last_available=True, compounding=ql.Continuous): """ :param date: date-like The date. :param calendar: QuantLib.Calendar The option calendar used to evaluate the model :param day_counter: QuantLib.DayCounter The option day count used to evaluate the model :param underlying_name: str The timeseries ts_name used to query the stored timeseries in self.ts_underlying :param dividend_yield: float, optional An override of the dividend yield in case you don't wan't to use the timeseries one. :param dvd_tax_adjust: float, default=1 The multiplier used to adjust for dividend tax. For example, US dividend taxes are 30% so you pass 0.7. :param last_available: bool, optional Whether to use last available data in case dates are missing in ``quotes``. :param compounding: QuantLib.Compounding, default=Continuous The compounding used to interpolate the curve. """ dt_date = to_datetime(date) dvd_ts = self.ts_underlying.get(underlying_name).eqy_dvd_yld_12m if dividend_yield is None: dividend_yield = dvd_ts.get_values(index=dt_date, last_available=last_available) else: dividend_yield = dividend_yield dividend_yield = dividend_yield * dvd_tax_adjust dividend = ql.FlatForward(0, calendar, to_ql_quote_handle(dividend_yield), day_counter, compounding) self.dividend_handle.linkTo(dividend)
def __init__(self, timeseries, calculate_convexity=True): super().__init__(timeseries, calculate_convexity=calculate_convexity) # Database Attributes self.last_delivery = to_ql_date( to_datetime(self.ts_attributes[LAST_DELIVERY])) self._index_tenor = ql.PeriodParser.parse( self.ts_attributes[INDEX_TENOR]) self.contract_size = float(self.ts_attributes[CONTRACT_SIZE]) self.tick_size = float(self.ts_attributes[TICK_SIZE]) self.tick_value = float(self.ts_attributes[TICK_VALUE]) self.term_number = int(self.ts_attributes[TERM_NUMBER]) self.term_period = to_ql_time_unit(self.ts_attributes[TERM_PERIOD]) self.settlement_days = int(self.ts_attributes[SETTLEMENT_DAYS]) # QuantLib Objects self.index = to_ql_rate_index(self.ts_attributes[INDEX], self._index_tenor) # QuantLib Attributes self._maturity = self.interest_start_date = self.index.valueDate( self.last_delivery) self.calendar = self.index.fixingCalendar() self.day_counter = self.index.dayCounter() self.business_convention = self.index.businessDayConvention() self.fixing_days = self.index.fixingDays() self.month_end = self.index.endOfMonth() self.interest_maturity_date = self.index.maturityDate( self.interest_start_date) self.futures_type = ql.Futures.IMM # Rate Helper self.helper_rate = ql.SimpleQuote(100) self.helper_convexity = ql.SimpleQuote(0)
def value(self, date, last_available=False, dividend_adjusted=False, *args, **kwargs): """Try to deduce dirty value for a unit of the time series (as a financial instrument). :param date: date-like, optional The date. :param last_available: bool, optional Whether to use last available data in case dates are missing in ``quotes``. :param dividend_adjusted: bool If true it will use the adjusted price for calculation. :return scalar, None The unit dirty value of the instrument. """ quotes = self.spot_prices(dividend_adjusted=dividend_adjusted) date = to_datetime(date) if last_available: return quotes(index=date, last_available=last_available) if date > quotes.ts_values.last_valid_index(): return np.nan if date < quotes.ts_values.first_valid_index(): return np.nan return quotes(index=date)
def volatility_update(self, date, calendar, day_counter, ts_option, underlying_name, vol_value=None, last_available=False): """ :param date: date-like The date. :param calendar: QuantLib.Calendar The option calendar used to evaluate the model :param day_counter: QuantLib.DayCounter The option day count used to evaluate the model :param ts_option: py:class:`TimeSeries` The option Timeseries. :param underlying_name: The underlying Timeseries ts_name :param vol_value: float, optional An override of the volatility value in case you don't wan't to use the timeseries one. :param last_available: bool, optional Whether to use last available data in case dates are missing in ``quotes``. :return: """ dt_date = to_datetime(date) vol_updated = True if vol_value is not None: volatility_value = vol_value else: volatility_value = ts_option.ivol_mid.get_values(index=dt_date, last_available=last_available) if np.isnan(volatility_value): volatility_value = 0 vol_updated = False back_constant_vol = ql.BlackConstantVol(0, calendar, to_ql_quote_handle(volatility_value), day_counter) self.volatility_handle.linkTo(back_constant_vol) self.vol_updated[underlying_name][to_ql_date(date)] = vol_updated
def __init__(self, timeseries): super().__init__(timeseries=timeseries) self.option_type = self.ts_attributes[OPTION_TYPE] self.strike = float(self.ts_attributes[STRIKE_PRICE]) self.contract_size = float(self.ts_attributes[CONTRACT_SIZE]) self._maturity = to_ql_date(to_datetime(self.ts_attributes[MATURITY_DATE])) self.calendar = to_ql_calendar(self.ts_attributes[CALENDAR]) self.day_counter = to_ql_day_counter(self.ts_attributes[DAY_COUNTER]) self.exercise_type = self.ts_attributes[EXERCISE_TYPE] self.underlying_name = self.ts_attributes[UNDERLYING_INSTRUMENT] try: self.earliest_date = to_ql_date(self.ts_attributes[EARLIEST_DATE]) except KeyError: self.earliest_date = ql.Date.minDate() self.exercise = to_ql_option_exercise_type(self.exercise_type, self.earliest_date, self._maturity) self.payoff = to_ql_option_payoff(self.ts_attributes[PAYOFF_TYPE], to_ql_option_type(self.option_type), self.strike) self.option = to_ql_one_asset_option(self.payoff, self.exercise) self.risk_free_yield_curve_ts = None self.underlying_instrument = None # engine setup self.engine_name = 'FINITE_DIFFERENCES' self.base_equity_process = None self._implied_volatility = dict() self._implied_volatility_prices = dict()
def _dividends_to_date(self, start_date, date, *args, **kwargs): """ Cash amount paid by a unit of the instrument between `start_date` and `date`. :param start_date: Date-like Start date of the range :param date: Date-like Final date of the range :return: pandas.Series """ start_date = to_datetime(start_date) date = to_datetime(date) ts_dividends = getattr(self.timeseries, DIVIDENDS).ts_values if start_date >= date: start_date = date ts_dividends = ts_dividends[ts_dividends != 0] if date == start_date: return ts_dividends[(ts_dividends.index == date)] else: return ts_dividends[(ts_dividends.index >= start_date) & (ts_dividends.index <= date)]
def __init__(self, timeseries, ql_process): super().__init__(timeseries) self.opt_type = self.ts_attributes[OPTION_TYPE] self.strike = self.ts_attributes[STRIKE_PRICE] self.contract_size = self.ts_attributes[OPTION_CONTRACT_SIZE] self.option_maturity = to_ql_date(to_datetime(self.ts_attributes[MATURITY_DATE])) self.payoff = ql_option_payoff(to_ql_option_type(self.opt_type), self.strike) self.calendar = to_ql_calendar(self.ts_attributes[CALENDAR]) self.day_counter = to_ql_day_counter(self.ts_attributes[DAY_COUNTER]) self.exercise_type = self.ts_attributes[EXERCISE_TYPE] self.underlying_instrument = self.ts_attributes[UNDERLYING_INSTRUMENT] self.ql_process = ql_process self.option = None
def __init__(self, timeseries, first_cc): super().__init__(timeseries) self.first_cc = first_cc self.calendar = to_ql_calendar(self.attributes[CALENDAR]) try: self._tenor = ql.PeriodParser.parse(self.attributes[TENOR_PERIOD]) except KeyError: # If the deposit rate has no tenor, it must have a maturity. self._maturity = to_ql_date(to_datetime(self.attributes[MATURITY_DATE])) self.day_counter = to_ql_day_counter(self.attributes[DAY_COUNTER]) self.compounding = to_ql_compounding(self.attributes[COMPOUNDING]) self.frequency = to_ql_frequency(self.attributes[FREQUENCY]) self.business_convention = to_ql_business_convention(self.attributes[BUSINESS_CONVENTION]) self.fixing_days = int(self.attributes[FIXING_DAYS])
def __init__(self, timeseries): super().__init__(timeseries=timeseries) # TODO: Add support for puttable bonds. # TODO: Here we assume that the call prices are always clean prices. Fix this! # TODO: Implement an option to reduce (some kind of 'telescopic') call dates. # if there are too much. This is useful in case we are treating a callable perpetual bond, for example. called_date = self.ts_attributes[CALLED_DATE] if called_date: self.expire_date = to_ql_date(to_datetime(called_date)) self.callability_schedule = ql.CallabilitySchedule() for call_date, call_price in self.call_schedule.ts_values.iteritems(): # The original bond (with maturity at self.maturity will be added to the components after its # instantiation below. call_date = to_ql_date(to_datetime(call_date)) callability_price = ql.CallabilityPrice(call_price, ql.CallabilityPrice.Clean) self.callability_schedule.append( ql.Callability(callability_price, ql.Callability.Call, call_date)) self.bond_components[call_date] = create_call_component( call_date, call_price, self.schedule, self.calendar, self.business_convention, self.coupon_frequency, self.date_generation, self.month_end, self.settlement_days, self.face_amount, self.coupons, self.day_counter, self.issue_date) self.bond = ql.CallableFixedRateBond(self.settlement_days, self.face_amount, self.schedule, self.coupons, self.day_counter, self.business_convention, self.redemption, self.issue_date, self.callability_schedule) self.bond_components[ self. maturity_date] = self.bond # Add the original bond to bond_components. self._bond_components_backup = self.bond_components.copy()
def intrinsic(self, date): """ :param date: date-like The date :return: float The intrinsic value o the option at date. """ strike = self.strike dt_maturity = to_datetime(self.option_maturity) if to_datetime(date) >= dt_maturity: return 0 else: spot = self.ql_process.spot_price_handle.value() intrinsic = 0 if self.opt_type == 'CALL': intrinsic = spot - strike if self.opt_type == 'PUT': intrinsic = strike - spot if intrinsic < 0: return 0 else: return intrinsic
def performance(self, start_date=None, date=None, spread=None, fixing_at_start_date=False, **kwargs): """Performance of investment in the interest rate, taking tenor into account. If the period between start_date and date is larger the the deposit rate's tenor, considers the investment is rolled at the prevailing rate at each maturity. :param start_date: QuantLib.Date Start date of the investment period. :param date: QuantLib.Date, c-vectorized End date of the investment period. :param spread: float rate to be added to the return calculation. :param fixing_at_start_date: bool Whether to use the start date as the first fixing date or not. :return scalar Performance of the investment. """ first_available_date = self.quotes.ts_values.first_valid_index() if start_date is None: start_date = first_available_date if start_date < first_available_date: start_date = first_available_date if date < start_date: return np.nan start_date = to_ql_date(start_date) date = to_ql_date(date) fixing_dates, maturity_dates = self._get_fixing_maturity_dates( start_date, date, fixing_at_start_date) fixings = self.quotes.get_values( index=[to_datetime(fixing_date) for fixing_date in fixing_dates]) if spread is not None: fixings += spread return np.prod([ ql.InterestRate(fixing, self.day_counter, self.compounding, self.frequency).compoundFactor( self.value_date(fixing_date), maturity_date, start_date, date) for fixing, fixing_date, maturity_date in zip( fixings, fixing_dates, maturity_dates) if self.value_date(fixing_date) <= maturity_date ]) - 1
def option_engine(self, date, vol_last_available=False, dvd_tax_adjust=1, last_available=True, exercise_ovrd=None): """ :param date: date-like The date. :param vol_last_available: bool, optional Whether to use last available data in case dates are missing in volatility values. :param dvd_tax_adjust: float, default=1 The multiplier used to adjust for dividend tax. For example, US dividend taxes are 30% so you pass 0.7. :param last_available: bool, optional Whether to use last available data in case dates are missing in ``quotes``. :param exercise_ovrd: str, optional Used to force the option model to use a specific type of option. Only working for American and European option types. :return: QuantLib.VanillaOption This method returns the VanillaOption with a QuantLib engine. Used for calculating the option values and greeks. """ dt_date = to_datetime(date) self.option = self.ql_option(date=dt_date, exercise_ovrd=exercise_ovrd) vol_updated = self.ql_process.update_process(date=date, calendar=self.calendar, day_counter=self.day_counter, ts_option=self.timeseries, maturity=self.option_maturity, underlying_name=self.underlying_instrument, vol_last_available=vol_last_available, dvd_tax_adjust=dvd_tax_adjust, last_available=last_available) self.option.setPricingEngine(ql_option_engine(self.ql_process.bsm_process)) if vol_updated: return self.option else: self.ql_process.volatility_update(date=date, calendar=self.calendar, day_counter=self.day_counter, ts_option=self.timeseries, underlying_name=self.underlying_instrument, vol_value=0.2) mid_price = self.px_mid.get_values(index=dt_date, last_available=True) implied_vol = self.option.impliedVolatility(targetValue=mid_price, process=self.ql_process.bsm_process) self.ql_process.volatility_update(date=date, calendar=self.calendar, day_counter=self.day_counter, ts_option=self.timeseries, underlying_name=self.underlying_instrument, vol_value=implied_vol) self.option.setPricingEngine(ql_option_engine(self.ql_process.bsm_process)) return self.option
def dividend_yield(self, date, last_available=True, fill_value=np.nan): """ 12 month dividend yield at date(s). :param date: Date-like Date or dates to be return the dividend values. :param last_available: bool, optional Whether to use last available data in case dates are missing. :param fill_value: scalar Default value in case `date` can't be found. :return pandas.Series """ date = to_datetime(date) try: dividend_yield = getattr(self.timeseries, DIVIDEND_YIELD) return dividend_yield(index=date, last_available=last_available, fill_value=fill_value) except KeyError: return 0
def __init__(self, timeseries, is_deposit_rate=False, calculate_convexity=False, telescopic_value_dates=False): super().__init__(timeseries=timeseries) # Class Flags self.is_deposit_rate = is_deposit_rate self.calculate_convexity = calculate_convexity self.telescopic_value_dates = telescopic_value_dates # Database Attributes try: self._tenor = ql.PeriodParser.parse( self.ts_attributes[TENOR_PERIOD]) except KeyError: self._tenor = ql.PeriodParser.parse( self.ts_attributes[INDEX_TENOR]) try: self.issue_date = to_ql_date( to_datetime(self.ts_attributes[ISSUE_DATE])) except KeyError: self.issue_date = DEFAULT_ISSUE_DATE self.compounding = to_ql_compounding(self.ts_attributes[COMPOUNDING]) self.frequency = to_ql_frequency(self.ts_attributes[FREQUENCY]) self.currency = to_ql_currency(self.ts_attributes[CURRENCY]) # Other Interest Rate Class start from here self._index_tenor = None self._maturity = None # QuantLib Objects self.term_structure = ql.RelinkableYieldTermStructureHandle() self.index = None # QuantLib Attributes self.calendar = None self.day_counter = None self.business_convention = None self.fixing_days = None self.month_end = None self.interest_maturity_date = None # Rate Helper self.helper_rate = None self.helper_convexity = None # Defined self._rate_helper = None
def spot_price_update(self, date, underlying_name, spot_price=None, last_available=True): """ :param date: date-like The date. :param underlying_name: str The underlying Timeseries ts_name :param spot_price: float, optional An override of the underlying spot price in case you don't wan't to use the timeseries one. :param last_available: bool, optional Whether to use last available data in case dates are missing in ``quotes``. """ dt_date = to_datetime(date) ts_underlying = self.ts_underlying.get(underlying_name).price if spot_price is None: spot_price = ts_underlying.get_values(index=dt_date, last_available=last_available) else: spot_price = spot_price self.spot_price_handle.linkTo(ql.SimpleQuote(spot_price))
def spot_price(self, date, last_available=True, fill_value=np.nan, dividend_adjusted=False): """ Return the daily series of unadjusted price at date(s). :param date: Date-like Date or dates to be return the dividend values. :param last_available: bool, optional Whether to use last available data in case dates are missing. :param fill_value: scalar Default value in case `date` can't be found. :param dividend_adjusted: bool If true it will use the adjusted price for calculation. :return pandas.Series """ date = to_datetime(date) prices = self.spot_prices(dividend_adjusted=dividend_adjusted) return prices(index=date, last_available=last_available, fill_value=fill_value)
def volatility(self, date, n_days=252, annual_factor=252, log_returns=False): """ The converted volatility value series at date. :param date: Date-like Date or dates to be return the dividend values. :param n_days: int Rolling window for the volatility calculation. :param annual_factor: int, default 252 The number of days used for period transformation, default is 252, or 1 year. :param log_returns: bool If True it will use the log returns of prices :return pandas.Series """ date = to_datetime(date) prices = self.price() if log_returns: returns = np.log(prices[prices.index <= date].tail(n_days)).diff() else: returns = prices[prices.index <= date].tail(n_days).pct_change() return np.std(returns) * np.sqrt(annual_factor)
def cash_flow_to_date(self, start_date, date, tax_adjust=0, *args, **kwargs): """ Cash amount paid by a unit of the instrument between `start_date` and `date`. :param start_date: Date-like Start date of the range :param date: Date-like Final date of the range :param tax_adjust: float The tax value to adjust the dividends received :return list of tuples with (date, date, value) Return the ex-date, pay-date and dividend value """ ts_dividends = self._dividends_to_date(start_date=start_date, date=date, *args, **kwargs) return list((to_ql_date(date), to_ql_date(to_datetime(value[0])), value[1] * (1 - float(tax_adjust))) for date, value in ts_dividends.iteritems())
def __init__(self, timeseries, reference_curve=None, index_timeseries=None): super().__init__(timeseries, reference_curve, index_timeseries) self.coupon_reset_date = to_ql_date( to_datetime(self.ts_attributes[COUPON_TYPE_RESET_DATE])) self.fixed_coupons = [float(self.ts_attributes[COUPONS])] self.fixed_schedule = ql.Schedule(self.first_accrual_date, self.coupon_reset_date, self.coupon_frequency, self.calendar, self.business_convention, self.business_convention, self.date_generation, self.month_end) fixed_schedule_len = len(self.fixed_schedule) - 1 float_schedule_len = len(self.schedule) - fixed_schedule_len - 1 self.gearings = [0] * fixed_schedule_len + [1] * float_schedule_len self.total_spreads = self.fixed_coupons * fixed_schedule_len + self.spreads * float_schedule_len called_date = self.ts_attributes[CALLED_DATE] if called_date: self.expire_date = to_ql_date(to_datetime(called_date)) self.callability_schedule = ql.CallabilitySchedule() # noinspection PyCompatibility for call_date, call_price in self.call_schedule.ts_values.iteritems(): # The original bond (with maturity at self.maturity will be added to the components after its # instantiation below. call_date = to_ql_date(to_datetime(call_date)) callability_price = ql.CallabilityPrice(call_price, ql.CallabilityPrice.Clean) self.callability_schedule.append( ql.Callability(callability_price, ql.Callability.Call, call_date)) self.bond_components[call_date] = create_call_component( call_date, call_price, self.schedule, self.calendar, self.business_convention, self.coupon_frequency, self.date_generation, self.month_end, self.settlement_days, self.face_amount, self.day_counter, self.issue_date, self.index, fixed_schedule_len, self.fixed_coupons, self.spreads, self.caps, self.floors, self.in_arrears) self.bond = ql.FloatingRateBond( self.settlement_days, self.face_amount, self.schedule, self.index, self.day_counter, self.business_convention, self.index.fixingDays(), self.gearings, self.total_spreads, self.caps, self.floors, self.in_arrears, self.redemption, self.issue_date) self.fixing_schedule = ql.Schedule( self.first_accrual_date, self.maturity_date, self._index_tenor, self.calendar, self.business_convention, self.business_convention, ql.DateGeneration.Forward, self.month_end) self.reference_schedule = list(self.fixing_schedule)[:-1] self.fixing_dates = [ self.index.fixingDate(dt) for dt in self.reference_schedule ] # Coupon pricers self.pricer = ql.BlackIborCouponPricer() self.volatility = 0.0 self.vol = ql.ConstantOptionletVolatility( self.settlement_days, self.index_calendar, self.index_bus_day_convention, self.volatility, self.day_counter) self.pricer.setCapletVolatility( ql.OptionletVolatilityStructureHandle(self.vol)) self.bond_components[ self. maturity_date] = self.bond # Add the original bond to bond_components. for bond in self.bond_components.values(): ql.setCouponPricer(bond.cashflows(), self.pricer) self._bond_components_backup = self.bond_components.copy()
def ts_implied_volatility(self, date, last_available=False, fill_value=np.nan): date = to_datetime(to_list(date)) return getattr(self.timeseries, IMPLIED_VOL).get_values(index=date, last_available=last_available, fill_value=fill_value)
def six_months_ago(x): return to_datetime(to_ql_date(x) - ql.Period(6, ql.Months))
def one_month_ago(x): return to_datetime(to_ql_date(x) - ql.Period(1, ql.Months))
def ts_mid_price(self, date, last_available=True, fill_value=np.nan): date = to_datetime(to_list(date)) return getattr(self.timeseries, MID_PRICE).get_values(index=date, last_available=last_available, fill_value=fill_value)