Пример #1
0
    def infer_period(self):
        logger.debug('Attempting to infer period/frequency of cashflows.')

        # no_of_dates = len - 1 because delta is being computed, i.e.
        #   lose one date.
        dates, no_of_dates = self.sample.keys(), (len(self.sample.keys()) - 1)
        first_pass = True
        mean_delta = 0

        if no_of_dates < 2:
            logger.debug(
                'Cannot infer period from sample size less than or equal to 1')
            self.period = None
            self.frequency = None

        else:
            for date in dates:
                if first_pass:
                    tomorrows_date = dater.parse(date)
                    first_pass = False

                else:
                    todays_date = dater.parse(date)
                    delta = (tomorrows_date - todays_date).days / 365
                    mean_delta += delta / no_of_dates
                    tomorrows_date = todays_date

            self.period = mean_delta
            self.frequency = 1 / self.period
            logger.debug(f'Inferred period = {self.period} yrs')
            logger.debug(f'Inferred frequency = {self.frequency}')
Пример #2
0
def test_date_validation(ticker, asset_type, start_date_str, end_date_str,
                         expected_start_str, expected_end_str):
    start_date = dater.parse(start_date_str)
    end_date = dater.parse(end_date_str)
    validated_start, validated_end = errors.validate_dates(
        start_date, end_date, asset_type)
    assert(dater.to_string(validated_start) == expected_start_str and \
            dater.to_string(validated_end) == expected_end_str)
def test_standardized_sample_of_returns(ticker, start_date, end_date):
    with HTTMock(mock.mock_prices):
        these_returns = standardize(statistics.get_sample_of_returns(ticker=ticker,
                                                                        start_date=dater.parse(start_date),
                                                                        end_date=dater.parse(end_date)))
    
    if get_asset_type(ticker) == keys['ASSETS']['CRYPTO']:
        no_of_days = dater.days_between(start_date, end_date)
    else:
        no_of_days = dater.business_days_between(start_date, end_date)

    assert isinstance(these_returns, list)
    assert all(isinstance(this_return, float) for this_return in these_returns)
    # subtract one because differencing price history loses one sample
    assert len(these_returns) == no_of_days - 1
Пример #4
0
def plot_correlation_series(tickers: list,
                            series: dict,
                            show: bool = True,
                            savefile: str = None) -> Union[FigureCanvas, None]:
    start, end = list(series.keys())[-1], list(series.keys())[0]
    title = f'({tickers[0]}, {tickers[1]}) correlation time series'
    subtitle = f'{start} to {end}, rolling {settings.DEFAULT_ANALYSIS_PERIOD}-day estimate'

    canvas = FigureCanvas(Figure())
    figure = canvas.figure
    axes = figure.subplots()

    locator = mdates.AutoDateLocator()
    formatter = mdates.AutoDateFormatter(locator)

    correl_history, dates = [], []
    for date in series:
        dates.append(dater.parse(date))
        correl_history.append(series[date])

    axes.plot(dates, correl_history)
    axes.grid()
    axes.xaxis.set_major_locator(locator)
    axes.xaxis.set_major_formatter(formatter)
    axes.set_ylabel('Correlation')
    axes.set_xlabel('Dates')
    axes.set_title(subtitle, fontsize=12)
    figure.suptitle(title, fontsize=18)
    figure.autofmt_xdate()

    return _show_or_save(canvas=canvas, show=show, savefile=savefile)
Пример #5
0
    def generate_time_series_for_sample(self):
        self.time_series = []

        dates, no_of_dates = self.sample.keys(), len(self.sample.keys())

        if no_of_dates == 0:
            logger.debug(
                'Cannot generate a time series for a sample size of 0.')
            self.time_series = None
        else:
            first_date = dater.parse(list(dates)[-1])

            for date in dates:
                this_date = dater.parse(date)
                delta = (this_date - first_date).days
                time_in_years = delta / 365
                self.time_series.append(time_in_years)
Пример #6
0
    def calculate_net_present_value(self):
        """
        Returns the net present value of the cash flow by using the `get_growth_function` method to project future cash flows and then discounting those projections back to the present by the value of the `discount_rate`. Call this method after constructing/initializing a `Cashflow` object to retrieve its NPV.

        Raises
        ------
        1. **scrilla.errors.InputValidationError**
            If not enough information is present in the instance of the `Cashflow` object to project future cash flows, this error will be thrown.

        Returns
        -------
        ``float`` : NPV of cash flow.
        """
        if self.period is None:
            raise errors.InputValidationError(
                "No period detected for cashflows. Not enough information to calculate net present value.")

        time_to_first_payment = 0
        if self.period is None:
            raise errors.InputValidationError(
                'Not enough information to calculate net present value of cash flow.')
        if self.period == FREQ_ANNUAL:
            time_to_first_payment = dater.get_time_to_next_year()

        elif self.period == FREQ_QUARTER:
            time_to_first_payment = dater.get_time_to_next_quarter()

        elif self.period == FREQ_MONTH:
            time_to_first_payment = dater.get_time_to_next_month()

        elif self.period == FREQ_DAY:
            time_to_first_payment = FREQ_DAY

        else:
            dates = self.sample.keys()
            latest_date = dater.parse(list(dates)[0])
            time_to_first_payment = dater.get_time_to_next_period(
                starting_date=latest_date, period=self.period)

        net_present_value, i, current_time = 0, 0, 0
        calculating = True
        while calculating:
            previous_value = net_present_value
            current_time = time_to_first_payment + i * self.period

            net_present_value += self.get_growth_function(current_time) / (
                (1 + self.discount_rate)**current_time)

            if net_present_value - previous_value < constants.constants['NPV_DELTA_TOLERANCE']:
                calculating = False
            i += 1

        return net_present_value
Пример #7
0
 def calculate_time_to_today(self):
     first_date = dater.parse(list(self.sample.keys())[-1])
     today = datetime.date.today()
     return ((today - first_date).days/365)
Пример #8
0
def test_dates_between(start_date, end_date, length):
    date_range = dater.dates_between(start_date, end_date)
    assert(len(date_range) == length)
    assert(dater.parse(start_date) in date_range)
    assert(dater.parse(end_date) in date_range)
Пример #9
0
def test_decrement_date_by_business_days(start_date, days, result):
    test_date = dater.decrement_date_by_business_days(start_date, days)
    assert(test_date == dater.parse(result))
Пример #10
0
import os

from scrilla.util import dater
from scrilla.static import constants

TEST_DIR = os.path.dirname(os.path.abspath(__file__))

MOCK_DIR = os.path.join(TEST_DIR, 'data')

END_STR = "2021-11-19"
END = dater.parse(END_STR)

START_STR = "2021-07-14"
START = dater.parse(START_STR)


def is_within_tolerance(func):
    return (abs(func()) < 10**(-constants.constants['ACCURACY']))