def main():
    '''
        Main testing script
    '''
    try:

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

        config = Configuration.try_from_s3(constants.STRATEGY_CONFIG_FILE_NAME,
                                           'sa')

        #macd_strategy = MACDCrossoverStrategy.from_configuration(config, 'sa')
        macd_strategy = MACDCrossoverStrategy(ticker_list, date(2020, 6, 16),
                                              0.0016, 12, 16, 9)
        macd_strategy.generate_recommendation()
        macd_strategy.display_results()
        '''
        #pd_strategy = PriceDispersionStrategy.from_configuration(config, 'sa')
        pd_strategy = PriceDispersionStrategy(
            ticker_list, '2020-06', date(2020, 5, 16), 3)
        pd_strategy.generate_recommendation()
        pd_strategy.display_results()
        '''

    except Exception as e:
        log.error("Could run script, because, %s" % (str(e)))
    def test_recommendation_set_dates(self):

        price_date = date(2020, 6, 8)
        with patch.object(intrinio_data, 'get_daily_stock_close_prices',
                          return_value=self.price_dict), \
            patch.object(intrinio_data, 'get_sma_indicator',
                         return_value=self.sma_dict), \
            patch.object(intrinio_data, 'get_macd_indicator',
                         return_value=self.macd_dict):

            strategy = MACDCrossoverStrategy(self.ticker_list, price_date,
                                             0.0016, 12, 26, 9)

            strategy.generate_recommendation()

            recommendation_set = strategy.recommendation_set

            self.assertEqual(recommendation_set.model['valid_from'],
                             str(date(2020, 6, 8)))
            self.assertEqual(recommendation_set.model['valid_to'],
                             str(date(2020, 6, 8)))
            self.assertEqual(recommendation_set.model['price_date'],
                             str(date(2020, 6, 8)))
def main():
    """
        Main Function for this script
    """

    description = """
                Executes a backtest for the MACD_CROSSOVER strategy given a ticker list,
                start date, end date and threshold, e.g. -0.02, used to determine the maximum
                allowed loss of a trade before a stop loss takes effect.
              """

    parser = argparse.ArgumentParser(description=description)
    parser.add_argument("-ticker_list",
                        help="Ticker List File",
                        type=str,
                        required=True)
    date_parser = lambda s: datetime.strptime(s, '%Y/%m/%d')
    parser.add_argument("-start_date",
                        help="Backtest start date (YYY/MM/DD)",
                        type=date_parser,
                        required=True)
    parser.add_argument("-end_date",
                        help="Backtest end date (YYYY/MM/DD)",
                        type=date_parser,
                        required=True)
    parser.add_argument("-stop_loss_theshold",
                        help="Stop Loss Threshold factor, e.g. -0.02 (-2%%)",
                        type=float,
                        required=True)

    args = parser.parse_args()

    ticker_file_name = args.ticker_list
    start_date = args.start_date
    end_date = args.end_date
    stop_loss_theshold = args.stop_loss_theshold

    log.info("Parameters:")
    log.info("Ticker File: %s" % ticker_file_name)
    log.info("Start Date: %s" % start_date)
    log.info("End Date: %s" % end_date)
    log.info("Stop Loss Threshold: %.2f" % stop_loss_theshold)

    log.info("")
    log.info("MACD Configuration:")
    log.info("Divergence Tolerance Factor: %f" % DIVERGENCE_FACTOR_THRESHOLD)
    log.info("Slow Period: %d" % SLOW_PERIOD)
    log.info("Fast Period: %d" % FAST_PERIOD)
    log.info("Signal Period: %d" % SIGNAL_PERIOD)

    log.info("")

    ticker_list = TickerList.from_local_file(
        "%s/%s" % (constants.TICKER_DATA_DIR, ticker_file_name))

    trade_dict = {
        'ticker': [],
        'buy_date': [],
        'buy_price': [],
        'sell_date': [],
        'sell_price': [],
        'trade_pnl_factor': [],
        'false_signal': []
    }

    try:
        date_list = get_business_date_list(start_date, end_date)
        init_portfolio_dict(ticker_list)

        for i in range(0, len(date_list) - 1):
            recommendation_date = date_list[i]
            trade_date = date_list[i + 1]

            strategy = MACDCrossoverStrategy(ticker_list, recommendation_date,
                                             DIVERGENCE_FACTOR_THRESHOLD,
                                             FAST_PERIOD, SLOW_PERIOD,
                                             SIGNAL_PERIOD)
            strategy.generate_recommendation()

            print("processing: %s" % recommendation_date, end="\r")

            unwound_positions = trade(trade_date, strategy.recommendation_set)

            for position in unwound_positions:
                (ticker, buy_date, sell_date, buy_price) = position

                sell_price = get_close_price(ticker, sell_date)
                pnl = ((sell_price / buy_price) - 1)
                false_signal = 0

                if (pnl < stop_loss_theshold):
                    sell_price = 'STOP_LOSS'
                    false_signal = 1
                    pnl = stop_loss_theshold

                if (pnl < 0):
                    false_signal = 1

                trade_dict['ticker'].append(ticker)
                trade_dict['buy_date'].append(buy_date)
                trade_dict['buy_price'].append(buy_price)
                trade_dict['sell_date'].append(str(sell_date))
                trade_dict['sell_price'].append(sell_price)
                trade_dict['trade_pnl_factor'].append(pnl)
                trade_dict['false_signal'].append(false_signal)

        trades_by_ticker = []
        for ticker in ticker_list.model['ticker_symbols']:
            trades_by_ticker.append(calculate_returns(ticker, trade_dict))
        trade_dataframe = pd.concat(trades_by_ticker)

        display_results(trade_dataframe)

    except Exception as e:
        log.error("Could run script, because, %s" % (str(e)))
        raise e