Exemplo n.º 1
0
    def testSimpleTraderWithTwoStocks(self):
        trader = SimpleTrader(PerfectPredictor(CompanyEnum.COMPANY_A),
                              PerfectPredictor(CompanyEnum.COMPANY_B))
        self.assertIsNotNone(trader)
        stock_market_data = read_stock_market_data(
            [CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_1])
        self.assertIsNotNone(stock_market_data)
        portfolio = Portfolio(10000, [])
        self.assertIsNotNone(portfolio)

        # Buy stocks based on prediction:
        # SimpleTrader buys only stocks A again
        # Why doesn't SimpleTrader buy stocks B?
        # This is because `SimpleTrader` buys sequentially without considering future/earlier trade actions. So in case
        # of two BUY actions, all available cash is spent for buying the first stock - an issue I already raised (jh)
        order_list = trader.doTrade(portfolio, 0.0, stock_market_data)

        order_list = order_list
        self.assertIsNotNone(order_list)

        self.assertEqual(len(order_list), 1)

        order = order_list[0]
        self.assertEqual(order.action, OrderType.BUY)
        self.assertEqual(order.shares.amount, 287)
        self.assertEqual(order.shares.company_enum, CompanyEnum.COMPANY_A)
Exemplo n.º 2
0
    def testDoPredictStockB(self):
        predictor = PerfectPredictor(CompanyEnum.COMPANY_B)

        # only one possible value: take 30.12.2011 and predict 03.01.2012
        current_value = StockData([(dt.date(2011, 12, 30), 157.077850)])
        future_value = 159.145142
        self.assertEqual(predictor.doPredict(current_value), future_value)

        # only one possible value: take 03.01.2012 and predict 04.01.2012
        current_value = StockData([(dt.date(2012, 1, 3), 159.145142)])
        future_value = 158.495911
        self.assertEqual(predictor.doPredict(current_value), future_value)
Exemplo n.º 3
0
    def testTeamRedDqlTrader(self):
        trader = TeamRedDqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B))
        self.assertIsNotNone(trader)
        stock_market_data = read_stock_market_data([CompanyEnum.COMPANY_A], [PERIOD_1])
        self.assertIsNotNone(stock_market_data)
        portfolio = Portfolio(10000, [])
        self.assertIsNotNone(portfolio)

        # Buy stocks based on prediction: With 10000, we can buy 287 stocks A for 34.80 each
        order_list: OrderList = trader.doTrade(portfolio, 0.0, stock_market_data)
        self.assertIsNotNone(order_list)

        self.assertEqual(len(order_list), 0)
Exemplo n.º 4
0
    def testConstructor(self):
        # Create a perfect predictor for stock A
        predictor_a = PerfectPredictor(CompanyEnum.COMPANY_A)
        self.assertIsNotNone(predictor_a)
        self.assertIsNotNone(predictor_a.stock_data)
        self.assertEqual(predictor_a.stock_data.get(0)[1], 0.05962)
        self.assertEqual(predictor_a.stock_data.get_last()[1], 101.610001)

        # Create a perfect predictor for stock B
        predictor_b = PerfectPredictor(CompanyEnum.COMPANY_B)
        self.assertIsNotNone(predictor_b)
        self.assertIsNotNone(predictor_b.stock_data)
        self.assertEqual(predictor_b.stock_data.get(0)[1], 2.192523)
        self.assertEqual(predictor_b.stock_data.get_last()[1], 151.350006)
Exemplo n.º 5
0
    def testDoPredictStockA(self):
        predictor = PerfectPredictor(CompanyEnum.COMPANY_A)

        # only one possible value: take 30.12.2011 and predict 03.01.2012
        current_value = StockData([(dt.date(2011, 12, 30), 34.802376)])
        future_value = 35.554108
        self.assertEqual(predictor.doPredict(current_value), future_value)

        # only one possible value: take 03.01.2012 and predict 04.01.2012
        current_value = StockData([(dt.date(2012, 1, 3), 35.554108)])
        future_value = 36.055264
        self.assertEqual(predictor.doPredict(current_value), future_value)

        # more than one possible values: take 08.01.1962 and predict 09.01.1962
        # because values from 03.01.1962 till 08.01.1962 are identical
        current_value = StockData([(dt.date(1962, 1, 8), 0.060421)])
        future_value = 0.061621
        self.assertEqual(predictor.doPredict(current_value), future_value)
Exemplo n.º 6
0
    def testSimpleTraderWithOneStock(self):
        trader = SimpleTrader(PerfectPredictor(CompanyEnum.COMPANY_A),
                              PerfectPredictor(CompanyEnum.COMPANY_B))
        self.assertIsNotNone(trader)
        stock_market_data = read_stock_market_data([CompanyEnum.COMPANY_A],
                                                   [PERIOD_1])
        self.assertIsNotNone(stock_market_data)
        portfolio = Portfolio(10000, [])
        self.assertIsNotNone(portfolio)

        # Buy stocks based on prediction: With 10000, we can buy 287 stocks A for 34.80 each
        order_list = trader.doTrade(portfolio, 0.0, stock_market_data)
        self.assertIsNotNone(order_list)

        self.assertEqual(len(order_list), 1)

        order = order_list[0]
        self.assertEqual(order.action, OrderType.BUY)
        self.assertEqual(order.shares.amount, 287)
        self.assertEqual(order.shares.company_enum, CompanyEnum.COMPANY_A)
Exemplo n.º 7
0
    def testGetAction(self):
        trader = DqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B), False)
        self.assertIsNotNone(trader)

        state = State(1000, 0, 0, 0, 0, 0, 0)
        self.assertIsNotNone(state)
        # Check random actions because epsilon is 1.0
        trader.epsilon = 1.0
        for i in range(100):
            action_a, action_b = trader.get_action(state)
            self.assertGreaterEqual(action_a, -1.0)
            self.assertGreaterEqual(action_b, -1.0)
            self.assertLessEqual(action_a, 1.0)
            self.assertLessEqual(action_b, 1.0)
        # Check predicted actions because epsilon is 0.0
        trader.epsilon = 0.0
        for i in range(100):
            action_a, action_b = trader.get_action(state)
            self.assertGreaterEqual(action_a, -1.0)
            self.assertGreaterEqual(action_b, -1.0)
            self.assertLessEqual(action_a, 1.0)
            self.assertLessEqual(action_b, 1.0)
Exemplo n.º 8
0
    def test_different_mappings(self):
        """
        Tests: Evaluator#inspect_over_time and #inspect_over_time_with_mappings

        Compares if both methods return the same values
        """
        stock_market_data = read_stock_market_data(
            [CompanyEnum.COMPANY_A], [PERIOD_1, PERIOD_2, PERIOD_3])

        portfolio_1 = Portfolio(20000,
                                [SharesOfCompany(CompanyEnum.COMPANY_A, 200)])
        portfolio_2 = Portfolio(20000,
                                [SharesOfCompany(CompanyEnum.COMPANY_A, 200)])
        portfolios = [portfolio_1, portfolio_2]

        perfect_predictor = PerfectPredictor(CompanyEnum.COMPANY_A)

        trader_1 = SimpleTrader(perfect_predictor, perfect_predictor)
        trader_2 = SimpleTrader(perfect_predictor, perfect_predictor)
        trader_3 = SimpleTrader(RandomPredictor(), RandomPredictor())
        traders = [trader_1, trader_2]

        portfolio_trader_mappings = list(
            zip(portfolios, traders, [None] * len(portfolios)))

        evaluator_1 = PortfolioEvaluator([trader_1, trader_1])
        evaluator_2 = PortfolioEvaluator([])
        evaluator_3 = PortfolioEvaluator([trader_3, trader_3])

        # 1 Use evaluator that is initialized *with* traders and call `#inspect_over_time` (i.e. without traders)
        result_1 = evaluator_1.inspect_over_time(stock_market_data, portfolios,
                                                 100)

        # 2 Use evaluator that is initialized *without* traders and call `#inspect_over_time_with_mapping`
        # (i.e. with traders)
        result_2 = evaluator_2.inspect_over_time_with_mapping(
            stock_market_data, portfolio_trader_mappings, 100)

        # 3 Use evaluator that is initialized *with* traders and call `#inspect_over_time_with_mapping`
        # (i.e. with traders) - this should be no problem, because the traders given at initialization time are ignored
        result_3 = evaluator_3.inspect_over_time_with_mapping(
            stock_market_data, portfolio_trader_mappings, 100)

        assert result_1 == result_2 == result_3
# This method retrains the trader from scratch using training data from PERIOD_1 and test data from PERIOD_2
EPISODES = 7
if __name__ == "__main__":
    # Read the training data
    training_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_1])
    test_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_1, PERIOD_2])
    start_training_day, final_training_day = dt.date(2009, 1, 2), dt.date(2011, 12, 29)
    start_test_day, final_test_day = dt.date(2012, 1, 3), dt.date(2015, 12, 30)

    # Define initial portfolio
    name = 'DQL trader portfolio'
    portfolio = Portfolio(10000.0, [], name)

    # Initialize trader: use perfect predictors, don't use an already trained model, but learn while trading
    trader = TeamGreenDqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B), False,
                                True, MODEL_FILENAME_DQLTRADER_PERFECT_PREDICTOR)
    # trader = DqlTrader(StockANnPerfectBinaryPredictor(), StockBNnPerfectBinaryPredictor(), False, True, MODEL_FILENAME_DQLTRADER_PERFECT_NN_BINARY_PREDICTOR)
    # trader = TeamGreenDqlTrader(StockANnBinaryPredictor(), StockBNnBinaryPredictor(), False, True, MODEL_FILENAME_DQLTRADER_NN_BINARY_PREDICTOR)

    # Start evaluation and train correspondingly; don't display the results in a plot but display final portfolio value
    evaluator = PortfolioEvaluator([trader], False)
    final_values_training, final_values_test = [], []
    for i in range(EPISODES):
        logger.info(f"DQL Trader: Starting training episode {i}")
        all_portfolios_over_time = evaluator.inspect_over_time(training_data, [portfolio],
                                                               date_offset=start_training_day)
        portfolio_over_time = all_portfolios_over_time[name]
        final_values_training.append(
            portfolio_over_time[final_training_day].total_value(final_training_day, training_data))
        trader.save_trained_model()
# This method retrains the trader from scratch using training data from PERIOD_1 and test data from PERIOD_2
EPISODES = 15
if __name__ == "__main__":
    # Read the training data
    training_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_1])
    test_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_1, PERIOD_2])
    start_training_day, final_training_day = dt.date(2009, 1, 2), dt.date(2011, 12, 29)
    start_test_day, final_test_day = dt.date(2012, 1, 3), dt.date(2015, 12, 30)

    # Define initial portfolio
    name = 'DQL trader portfolio'
    portfolio = Portfolio(10000.0, [], name)

    # Initialize trader: use perfect predictors, don't use an already trained model, but learn while trading
    trader = TeamRedDqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B), False, True, MODEL_FILENAME_DQLTRADER_NN_BINARY_PREDICTOR)
    # trader = TeamRedDqlTrader(StockANnPerfectBinaryPredictor(), StockBNnPerfectBinaryPredictor(), False, True, MODEL_FILENAME_DQLTRADER_PERFECT_NN_BINARY_PREDICTOR)
    # trader = TeamRedDqlTrader(StockANnBinaryPredictor(), StockBNnBinaryPredictor(), False, True, MODEL_FILENAME_DQLTRADER_NN_BINARY_PREDICTOR)

    # Start evaluation and train correspondingly; don't display the results in a plot but display final portfolio value
    evaluator = PortfolioEvaluator([trader], False)
    final_values_training, final_values_test = [], []
    for i in range(EPISODES):
        logger.info(f"DQL Trader: Starting training episode {i}")
        all_portfolios_over_time = evaluator.inspect_over_time(training_data, [portfolio],
                                                               date_offset=start_training_day)
        portfolio_over_time = all_portfolios_over_time[name]
        final_values_training.append(
            portfolio_over_time[final_training_day].total_value(final_training_day, training_data))
        trader.save_trained_model()
Exemplo n.º 11
0
EPISODES = 10
if __name__ == "__main__":
    # Read the training data
    training_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_1])
    test_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_1, PERIOD_2])
    start_training_day, final_training_day = dt.date(2009, 1, 2), dt.date(2011, 12, 29)
    start_test_day, final_test_day = dt.date(2012, 1, 3), dt.date(2015, 12, 30)

    # Define initial portfolio
    name = 'DQL trader portfolio'
    portfolio = Portfolio(10000.0, [], name)

    # Initialize trader: use perfect predictors, don't use an already trained model, but learn while trading
    # trader = DqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B), False, True, MODEL_FILENAME_DQLTRADER_PERFECT_PREDICTOR)
    # trader = DqlTrader(StockANnPerfectBinaryPredictor(), StockBNnPerfectBinaryPredictor(), False, True, MODEL_FILENAME_DQLTRADER_PERFECT_NN_BINARY_PREDICTOR)
    trader = TeamBlackDqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B), False, True, MODEL_FILENAME_DQLTRADER_PERFECT_PREDICTOR)

    # Start evaluation and train correspondingly; don't display the results in a plot but display final portfolio value
    evaluator = PortfolioEvaluator([trader], False)
    final_values_training, final_values_test = [], []
    for i in range(EPISODES):
        logger.info(f"DQL Trader: Starting training episode {i}")
        all_portfolios_over_time = evaluator.inspect_over_time(training_data, [portfolio],
                                                               date_offset=start_training_day)
        portfolio_over_time = all_portfolios_over_time[name]
        final_values_training.append(
            portfolio_over_time[final_training_day].total_value(final_training_day, training_data))
        trader.save_trained_model()

        # Evaluation over training and visualization
        # trader_test = TeamBlackDqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B), True, False, MODEL_FILENAME_DQLTRADER_PERFECT_PREDICTOR)
Exemplo n.º 12
0
    def testCreateActionList(self):
        trader = DqlTrader(PerfectPredictor(CompanyEnum.COMPANY_A), PerfectPredictor(CompanyEnum.COMPANY_B), False)
        self.assertIsNotNone(trader)
        portfolio = Portfolio(10000, [])
        stock_market_data = read_stock_market_data([CompanyEnum.COMPANY_A, CompanyEnum.COMPANY_B], [PERIOD_3])
        self.assertIsNotNone(stock_market_data)

        # Check doing nothing
        # commented because that STOCKACTION is not used anymore
        # action_a, action_b = 0.0, 0.0
        # order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data)
        # self.assertIsNotNone(order_list)
        # self.assertTrue(order_list.is_empty())

        # Check buying halve stock
        # commented because that STOCKACTION is not used anymore
        # action_a, action_b = 0.5, 0.5
        # order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data)
        # self.assertIsNotNone(order_list)
        # self.assertEqual(order_list.get(0).action, OrderType.BUY)
        # self.assertEqual(order_list.get(0).shares.company_enum, CompanyEnum.COMPANY_A)
        # self.assertEqual(order_list.get(0).shares.amount, 49)
        # self.assertEqual(order_list.get(1).action, OrderType.BUY)
        # self.assertEqual(order_list.get(1).shares.company_enum, CompanyEnum.COMPANY_B)
        # self.assertEqual(order_list.get(1).shares.amount, 33)

        # Check buying full stock
        action_a, action_b = 1.0, 1.0
        order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data)
        self.assertIsNotNone(order_list)

        order_1 = order_list[0]
        order_2 = order_list[1]

        self.assertEqual(order_1.action, OrderType.BUY)
        self.assertEqual(order_1.shares.company_enum, CompanyEnum.COMPANY_A)
        self.assertEqual(order_1.shares.amount, 98)
        self.assertEqual(order_2.action, OrderType.BUY)
        self.assertEqual(order_2.shares.company_enum, CompanyEnum.COMPANY_B)
        self.assertEqual(order_2.shares.amount, 66)

        # Check selling stock without enough owned shares
        action_a, action_b = -1.0, -1.0
        order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data)
        self.assertIsNotNone(order_list)
        self.assertTrue(order_list.is_empty())

        # Check selling halve stock with enough owned shares
        # commented because that STOCKACTION is not used anymore
        # portfolio = Portfolio(10000, [SharesOfCompany(CompanyEnum.COMPANY_A, 2), SharesOfCompany(CompanyEnum.COMPANY_B, 2)])
        # action_a, action_b = -0.5, -0.5
        # order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data)
        # self.assertIsNotNone(order_list)
        # self.assertEqual(order_list.get(0).action, OrderType.SELL)
        # self.assertEqual(order_list.get(0).shares.company_enum, CompanyEnum.COMPANY_A)
        # self.assertEqual(order_list.get(0).shares.amount, 2)
        # self.assertEqual(order_list.get(1).action, OrderType.SELL)
        # self.assertEqual(order_list.get(1).shares.company_enum, CompanyEnum.COMPANY_B)
        # self.assertEqual(order_list.get(1).shares.amount, 1)

        # Check selling full stock with enough owned shares
        portfolio = Portfolio(10000,
                              [SharesOfCompany(CompanyEnum.COMPANY_A, 2), SharesOfCompany(CompanyEnum.COMPANY_B, 2)])
        action_a, action_b = -1.0, -1.0
        order_list = trader.create_order_list(action_a, action_b, portfolio, stock_market_data)
        self.assertIsNotNone(order_list)

        order_1 = order_list[0]
        order_2 = order_list[1]

        self.assertEqual(order_1.action, OrderType.SELL)
        self.assertEqual(order_1.shares.company_enum, CompanyEnum.COMPANY_A)
        self.assertEqual(order_1.shares.amount, 2)
        self.assertEqual(order_2.action, OrderType.SELL)
        self.assertEqual(order_2.shares.company_enum, CompanyEnum.COMPANY_B)
        self.assertEqual(order_2.shares.amount, 2)