Beispiel #1
0
    def test_recommendation_set_price_date_during_analysisperiod(self):
        with patch.object(PriceDispersionStrategy,
                          '_load_financial_data',
                          return_value=self.financial_data):

            price_date = date(2020, 6, 10)

            strategy = PriceDispersionStrategy(
                TickerList.from_dict({
                    "list_name": "DOW30",
                    "list_type": "US_EQUITIES",
                    "comparison_symbol": "DIA",
                    "ticker_symbols": ['AAPL', 'V']
                }), '2020-06', price_date, 3)

            strategy.generate_recommendation()

            recommendation_set = strategy.recommendation_set

            self.assertEqual(recommendation_set.model['valid_from'],
                             str(date(2020, 7, 1)))
            self.assertEqual(recommendation_set.model['valid_to'],
                             str(date(2020, 7, 31)))
            self.assertEqual(recommendation_set.model['price_date'],
                             str(date(2020, 6, 10)))
Beispiel #2
0
 def test_from_configuration_invalid(self):
     with patch('support.constants.CONFIG_FILE_PATH',
                "./test/config-unittest-bad/"):
         with self.assertRaises(ValidationError):
             PriceDispersionStrategy.from_configuration(
                 Configuration.from_local_config("bad-test-config.ini"),
                 'sa')
Beispiel #3
0
    def test_api_exception(self):
        with patch.object(intrinio_data.COMPANY_API,
                          'get_company_historical_data',
                          side_effect=ApiException("Not Found")):

            strategy = PriceDispersionStrategy(['1', '2'], 2020, 2, 1)

            with self.assertRaises(DataError):
                strategy.__load_financial_data__()
Beispiel #4
0
    def test_api_exception(self):
        with patch.object(intrinio_data.COMPANY_API,
                          'get_company_historical_data',
                          side_effect=ApiException("Not Found")):

            strategy = PriceDispersionStrategy(
                TickerList.from_dict({
                    "list_name": "DOW30",
                    "list_type": "US_EQUITIES",
                    "comparison_symbol": "DIA",
                    "ticker_symbols": ['AAPL', 'V']
                }), '2000-05', date(2000, 6, 10), 3)

            with self.assertRaises(DataError):
                strategy._load_financial_data()
Beispiel #5
0
 def test_init_no_price_date(self):
     PriceDispersionStrategy(
         TickerList.from_dict({
             "list_name": "DOW30",
             "list_type": "US_EQUITIES",
             "comparison_symbol": "DIA",
             "ticker_symbols": ['AAPL', 'V']
         }), '2020-05', None, 3)
Beispiel #6
0
 def test_init_enough_tickers(self):
     PriceDispersionStrategy(
         TickerList.from_dict({
             "list_name": "DOW30",
             "list_type": "US_EQUITIES",
             "comparison_symbol": "DIA",
             "ticker_symbols": ['AAPL', 'V']
         }), '2020-02', date(2020, 6, 10), 3)
Beispiel #7
0
 def test_init_bad_period(self):
     with self.assertRaises(ValidationError):
         PriceDispersionStrategy(
             TickerList.from_dict({
                 "list_name": "DOW30",
                 "list_type": "US_EQUITIES",
                 "comparison_symbol": "DIA",
                 "ticker_symbols": ['AAPL', 'V']
             }), 'invalid_period', date(2020, 6, 10), 3)
Beispiel #8
0
 def test_init_empty_ticker_list(self):
     with self.assertRaises(ValidationError):
         PriceDispersionStrategy(
             TickerList.from_dict({
                 "list_name": "DOW30",
                 "list_type": "US_EQUITIES",
                 "comparison_symbol": "DIA",
                 "ticker_symbols": []
             }), '2020-02', date(2020, 6, 10), 3)
Beispiel #9
0
 def test_init_output_size_too_small(self):
     with self.assertRaises(ValidationError):
         PriceDispersionStrategy(
             TickerList.from_dict({
                 "list_name": "DOW30",
                 "list_type": "US_EQUITIES",
                 "comparison_symbol": "DIA",
                 "ticker_symbols": ['AAPL', 'V']
             }), '2020-02', date(2020, 6, 10), 0)
Beispiel #10
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)
Beispiel #11
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)
Beispiel #12
0
    def test_recommendation_set_price_date_before_analysisperiod(self):
        with patch.object(PriceDispersionStrategy,
                          '_load_financial_data',
                          return_value=self.financial_data):

            price_date = date(2020, 5, 10)

            with self.assertRaises(ValidationError):
                strategy = PriceDispersionStrategy(
                    TickerList.from_dict({
                        "list_name": "DOW30",
                        "list_type": "US_EQUITIES",
                        "comparison_symbol": "DIA",
                        "ticker_symbols": ['AAPL', 'V']
                    }), '2020-06', price_date, 3)
Beispiel #13
0
    def test_from_configuration_valid(self):

        ticker_list = TickerList.from_local_file("%s/djia30.json" %
                                                 (constants.APP_DATA_DIR))

        with patch.object(util, 'get_business_date',
                          return_value=date(2020, 6, 3)), \
            patch.object(pd, 'to_datetime',
                         return_value=datetime(2020, 6, 19)), \
            patch.object(TickerList, 'from_s3',
                         return_value=ticker_list):

            strategy = PriceDispersionStrategy.from_configuration(
                Configuration.from_local_config(
                    constants.STRATEGY_CONFIG_FILE_NAME), 'sa')

            self.assertEqual(strategy.analysis_start_date, date(2020, 5, 1))
            self.assertEqual(strategy.analysis_end_date, date(2020, 5, 31))
            self.assertEqual(strategy.current_price_date, date(2020, 6, 3))
        '''
Beispiel #14
0
 def test_init_no_tickers(self):
     with self.assertRaises(ValidationError):
         PriceDispersionStrategy(None, 2020, 2, 1)
Beispiel #15
0
 def test_init_output_size_too_small(self):
     with self.assertRaises(ValidationError):
         PriceDispersionStrategy(['1', '2'], 2020, 1, 0)
Beispiel #16
0
 def test_init_too_few_tickers(self):
     with self.assertRaises(ValidationError):
         PriceDispersionStrategy(['AAPL'], 2020, 2, 1)
Beispiel #17
0
 def test_init_enough_tickers(self):
     PriceDispersionStrategy(['1', '2'], 2020, 1, 1)
Beispiel #18
0
def main():
    """
        Main function for this script
    """
    try:
        (environment, ticker_file_name, output_size, month, year,
         current_price_date, app_ns) = parse_params()

        log.info("Parameters:")
        log.info("Environment: %s" % environment)
        log.info("Ticker File: %s" % ticker_file_name)
        log.info("Output Size: %d" % output_size)
        log.info("Analysis Month: %d" % month)
        log.info("Analysis Year: %d" % year)

        if environment == "TEST":
            log.info("reading ticker file from local filesystem")
            ticker_list = TickerFile.from_local_file(
                constants.TICKER_DATA_DIR, ticker_file_name).ticker_list

            log.info("Performing Recommendation Algorithm")
            strategy = PriceDispersionStrategy(ticker_list, year, month,
                                               output_size)
            strategy.generate_recommendation()
            display_calculation_dataframe(month, year, strategy,
                                          current_price_date)
        else:  # environment == "PRODUCTION"
            # test all connectivity upfront, so if there any issues
            # the problem becomes more apparent
            connector_test.test_aws_connectivity()
            connector_test.test_intrinio_connectivity()

            log.info("Reading ticker file from s3 bucket")
            ticker_list = TickerFile.from_s3_bucket(ticker_file_name,
                                                    app_ns).ticker_list

            log.info("Loading existing recommendation set from S3")
            recommendation_set = None

            try:
                recommendation_set = SecurityRecommendationSet.from_s3(app_ns)
            except AWSError as awe:
                if not awe.resource_not_found():
                    raise awe
                log.info("No recommendation set was found in S3.")

            if recommendation_set == None  \
                    or not recommendation_set.is_current(datetime.now()):

                log.info("Performing Recommendation Algorithm")
                strategy = PriceDispersionStrategy(ticker_list, year, month,
                                                   output_size)

                strategy.generate_recommendation()
                recommendation_set = strategy.recommendation_set
                display_calculation_dataframe(month, year, strategy,
                                              current_price_date)

                recommendation_set.save_to_s3(app_ns)
                recommendation_svc.notify_new_recommendation(
                    recommendation_set, app_ns)
            else:
                log.info(
                    "Recommendation set is still valid. There is nothing to do"
                )

    except Exception as e:
        stack_trace = traceback.format_exc()
        log.error("Could run script, because: %s" % (str(e)))
        log.error(stack_trace)

        if environment == "PRODUCTION":
            aws_service_wrapper.notify_error(
                e, "Securities Recommendation Service", stack_trace, app_ns)
Beispiel #19
0
 def test_init_no_tickers(self):
     with self.assertRaises(ValidationError):
         PriceDispersionStrategy(None, '2020-02', date(2020, 6, 10), 3)
def main():
    """
        Main function for this script
    """
    try:
        app_ns = parse_params()

        log.info("Parameters:")
        log.info("Application Namespace: %s" % app_ns)

        business_date = util.get_business_date(
            constants.BUSINESS_DATE_DAYS_LOOKBACK, constants.BUSINESS_DATE_CUTOVER_TIME)
        log.info("Business Date is: %s" % business_date)

        # test all connectivity upfront, so if there any issues
        # the problem becomes more apparent
        connector_test.test_aws_connectivity()
        connector_test.test_intrinio_connectivity()

        log.info('Loading Strategy Configuration "%s" from S3' %
                 constants.STRATEGY_CONFIG_FILE_NAME)
        configuration = Configuration.try_from_s3(
            constants.STRATEGY_CONFIG_FILE_NAME, app_ns)

        log.info("Initalizing Trading Strategies")
        strategies = [
            PriceDispersionStrategy.from_configuration(configuration, app_ns),
            MACDCrossoverStrategy.from_configuration(configuration, app_ns)
        ]

        notification_list = []
        for strategy in strategies:
            recommendation_set = None
            try:
                log.info("Executing %s strategy" % strategy.STRATEGY_NAME)
                recommendation_set = SecurityRecommendationSet.from_s3(
                    app_ns, strategy.S3_RECOMMENDATION_SET_OBJECT_NAME)
            except AWSError as awe:
                if not awe.resource_not_found():
                    raise awe
                log.info("No recommendation set was found in S3.")

            if recommendation_set == None  \
                    or not recommendation_set.is_current(business_date):

                strategy.generate_recommendation()
                strategy.display_results()

                recommendation_set = strategy.recommendation_set

                recommendation_set.save_to_s3(
                    app_ns, strategy.S3_RECOMMENDATION_SET_OBJECT_NAME)

                notification_list.append(recommendation_set)
            else:
                log.info(
                    "Recommendation set is still valid. There is nothing to do")

        recommendation_svc.notify_new_recommendation(
            notification_list, app_ns)
    except Exception as e:
        stack_trace = traceback.format_exc()
        log.error("Could run script, because: %s" % (str(e)))
        log.error(stack_trace)
Beispiel #21
0
 def test_init_empty_ticker_list(self):
     with self.assertRaises(ValidationError):
         PriceDispersionStrategy([], 2020, 2, 1)