def display_results(self):
        '''
            Displays the results of the strategy to the screen.
            Specifically displays the ranking of the securities using
            a Pandas Dataframe and the resulting recommendation set.
        '''
        log.info("Calculating Current Returns")
        raw_dataframe = calculator.mark_to_market(self.raw_dataframe, 'ticker',
                                                  'analysis_price',
                                                  self.current_price_date)
        recommendation_dataframe = calculator.mark_to_market(
            self.recommendation_dataframe, 'ticker', 'analysis_price',
            self.current_price_date)

        log.info("")
        log.info("Recommended Securities")
        log.info(util.format_dict(self.recommendation_set.to_dict()))
        log.info("")

        log.info("Recommended Securities Return: %.2f%%" %
                 (recommendation_dataframe['actual_return'].mean() * 100))
        log.info("Average Return: %.2f%%" %
                 (raw_dataframe['actual_return'].mean() * 100))
        log.info("")
        log.info("Analysis Period - %s, Actual Returns as of: %s" %
                 (self.analysis_period, self.current_price_date))

        # Using the logger will mess up the header of this table
        print(raw_dataframe[[
            'analysis_period', 'ticker', 'dispersion_stdev_pct',
            'analyst_expected_return', 'actual_return', 'decile'
        ]].to_string(index=False))
예제 #2
0
 def test_mark_to_market_price_exception(self):
     df_dict = {'ticker': ['a'], 'analysis_price': [10]}
     data_frame = pd.DataFrame(df_dict)
     with patch.object(intrinio_data,
                       'get_latest_close_price',
                       side_effect=Exception("Not Found")):
         with self.assertRaises(DataError):
             calculator.mark_to_market(data_frame, datetime.now())
예제 #3
0
 def test_mark_to_market_null_parameters(self):
     df_dict = {
         'ticker': ['a', 'b', 'c', 'd'],
         'analysis_price': [1, 2, 3, 4]
     }
     data_frame = pd.DataFrame(df_dict)
     with self.assertRaises(ValidationError):
         calculator.mark_to_market(data_frame, None)
         calculator.mark_to_market(None, datetime.now())
예제 #4
0
    def test_mark_to_market_valid(self):
        df_dict = {'ticker': ['a'], 'analysis_price': [10]}
        data_frame = pd.DataFrame(df_dict)
        with patch.object(intrinio_data,
                          'get_latest_close_price',
                          return_value=(datetime.now(), 20)):

            mmt_df = calculator.mark_to_market(data_frame, datetime.now())

            self.assertEqual(mmt_df['current_price'][0], 20)
            self.assertEqual(mmt_df['actual_return'][0], 1.0)
예제 #5
0
def display_calculation_dataframe(month: int, year: int, strategy: object,
                                  current_price_date: datetime):
    '''
        Displays the results of the calculation using a Pandas dataframe,
        using the supplied PriceDispersionStrategy object.
        Speficially display the underlining stock rankings that lead to the
        current recommendation
    '''

    recommendation_set = strategy.recommendation_set
    recommendation_dataframe = strategy.recommendation_dataframe
    raw_dataframe = strategy.raw_dataframe

    log.info("Calculating Current Returns")
    raw_dataframe = calculator.mark_to_market(strategy.raw_dataframe,
                                              current_price_date)
    recommendation_dataframe = calculator.mark_to_market(
        strategy.recommendation_dataframe, current_price_date)

    log.info("")
    log.info("Recommended Securities")
    log.info(util.format_dict(recommendation_set.to_dict()))
    log.info("")

    log.info("Recommended Securities Return: %.2f%%" %
             (recommendation_dataframe['actual_return'].mean() * 100))
    log.info("Average Return: %.2f%%" %
             (raw_dataframe['actual_return'].mean() * 100))
    log.info("")
    log.info("Analysis Period - %d/%d, Actual Returns as of: %s" %
             (month, year, datetime.strftime(current_price_date, '%Y/%m/%d')))

    # Using the logger will mess up the header of this table
    print(raw_dataframe[[
        'analysis_period', 'ticker', 'dispersion_stdev_pct',
        'analyst_expected_return', 'actual_return', 'decile'
    ]].to_string(index=False))
    def test_mark_to_market_valid(self):
        df_dict = {'ticker': ['a'], 'analysis_price': [10]}
        data_frame = pd.DataFrame(df_dict)
        with patch.object(intrinio_data,
                          'get_daily_stock_close_prices',
                          return_value=({
                              '2020-10-22': 20
                          })):

            mmt_df = calculator.mark_to_market(data_frame, 'ticker',
                                               'analysis_price',
                                               date(2020, 10, 22))

            self.assertEqual(mmt_df['current_price'][0], 20)
            self.assertEqual(mmt_df['actual_return'][0], 1.0)
예제 #7
0
    def backtest(analysis_period: str):
        log.info("Performing backtest for %s" % analysis_period)

        period = pd.Period(analysis_period)

        data_end_date = intrinio_util.get_month_period_range(period)[1]

        strategy = PriceDispersionStrategy(
            ticker_list, period, None, output_size)
        strategy.generate_recommendation()

        date_1m = get_nearest_business_date(data_end_date + timedelta(days=30))
        date_2m = get_nearest_business_date(data_end_date + timedelta(days=60))
        date_3m = get_nearest_business_date(data_end_date + timedelta(days=90))

        portfolio_1m = calculator.mark_to_market(
            strategy.recommendation_dataframe, 'ticker', 'analysis_price', date_1m)['actual_return'].mean() * 100
        portfolio_2m = calculator.mark_to_market(
            strategy.recommendation_dataframe, 'ticker', 'analysis_price', date_2m)['actual_return'].mean() * 100
        portfolio_3m = calculator.mark_to_market(
            strategy.recommendation_dataframe, 'ticker', 'analysis_price', date_3m)['actual_return'].mean() * 100

        all_stocks_1m = calculator.mark_to_market(strategy.raw_dataframe, 'ticker', 'analysis_price', date_1m)[
            'actual_return'].mean() * 100
        all_stocks_2m = calculator.mark_to_market(strategy.raw_dataframe, 'ticker', 'analysis_price', date_2m)[
            'actual_return'].mean() * 100
        all_stocks_3m = calculator.mark_to_market(strategy.raw_dataframe, 'ticker', 'analysis_price', date_3m)[
            'actual_return'].mean() * 100

        backtest_report['investment_period'].append(
            data_end_date.strftime('%Y/%m'))
        backtest_report['ticker_sample_size'].append(
            len(strategy.raw_dataframe))

        backtest_report['avg_ret_1M'].append(all_stocks_1m)
        backtest_report['sel_ret_1M'].append(portfolio_1m)
        backtest_report['avg_ret_2M'].append(all_stocks_2m)
        backtest_report['sel_ret_2M'].append(portfolio_2m)
        backtest_report['avg_ret_3M'].append(all_stocks_3m)
        backtest_report['sel_ret_3M'].append(portfolio_3m)
예제 #8
0
    def backtest(year: int, month: int):
        log.info("Peforming backtest for %d/%d" % (month, year))
        data_end_date = intrinio_util.get_month_date_range(year, month)[1]

        strategy = PriceDispersionStrategy(ticker_list, year, month,
                                           output_size)
        strategy.generate_recommendation()

        date_1m = data_end_date + timedelta(days=30)
        date_2m = data_end_date + timedelta(days=60)
        date_3m = data_end_date + timedelta(days=90)

        portfolio_1m = calculator.mark_to_market(
            strategy.recommendation_dataframe,
            date_1m)['actual_return'].mean() * 100
        portfolio_2m = calculator.mark_to_market(
            strategy.recommendation_dataframe,
            date_2m)['actual_return'].mean() * 100
        portfolio_3m = calculator.mark_to_market(
            strategy.recommendation_dataframe,
            date_3m)['actual_return'].mean() * 100

        all_stocks_1m = calculator.mark_to_market(
            strategy.raw_dataframe, date_1m)['actual_return'].mean() * 100
        all_stocks_2m = calculator.mark_to_market(
            strategy.raw_dataframe, date_2m)['actual_return'].mean() * 100
        all_stocks_3m = calculator.mark_to_market(
            strategy.raw_dataframe, date_3m)['actual_return'].mean() * 100

        backtest_report['investment_period'].append(
            data_end_date.strftime('%Y/%m'))
        backtest_report['ticker_sample_size'].append(
            len(strategy.raw_dataframe))

        backtest_report['avg_ret_1M'].append(all_stocks_1m)
        backtest_report['sel_ret_1M'].append(portfolio_1m)
        backtest_report['avg_ret_2M'].append(all_stocks_2m)
        backtest_report['sel_ret_2M'].append(portfolio_2m)
        backtest_report['avg_ret_3M'].append(all_stocks_3m)
        backtest_report['sel_ret_3M'].append(portfolio_3m)
예제 #9
0
 def test_mark_to_market_df_invalid_columns(self):
     df_dict = {'a': ['a', 'b', 'c', 'd'], 'b': [1, 2, 3, 4]}
     data_frame = pd.DataFrame(df_dict)
     with self.assertRaises(ValidationError):
         calculator.mark_to_market(data_frame, datetime.now())
 def test_mark_to_market_df_invalid_columns(self):
     df_dict = {'a': ['a', 'b', 'c', 'd'], 'b': [1, 2, 3, 4]}
     data_frame = pd.DataFrame(df_dict)
     with self.assertRaises(ValidationError):
         calculator.mark_to_market(data_frame, 'ticker', 'analysis_price',
                                   date.today())