def setUp(self): # Fixture Setup clock = TestClock() uuid_factory = TestUUIDFactory() logger = TestLogger(clock) self.trader_id = TraderId("TESTER", "000") self.strategy = EmptyStrategy(order_id_tag="001") self.strategy.register_trader( TraderId("TESTER", "000"), clock, uuid_factory, logger, ) config = { 'host': 'localhost', 'port': 6379 } self.database = RedisExecutionDatabase( trader_id=self.trader_id, logger=logger, command_serializer=MsgPackCommandSerializer(), event_serializer=MsgPackEventSerializer(), config=config ) self.test_redis = redis.Redis(host="localhost", port=6379, db=0)
def test_trader_detects_none_unique_identifiers(self): # Arrange strategies = [EmptyStrategy("000"), EmptyStrategy("000")] # Act self.assertRaises(ValueError, self.trader.initialize_strategies, strategies)
def setUp(self): # Fixture Setup usdjpy = TestStubs.instrument_usdjpy() data = BacktestDataContainer() data.add_instrument(usdjpy) data.add_bars(usdjpy.symbol, BarStructure.MINUTE, PriceType.BID, TestDataProvider.usdjpy_1min_bid()[:2000]) data.add_bars(usdjpy.symbol, BarStructure.MINUTE, PriceType.ASK, TestDataProvider.usdjpy_1min_ask()[:2000]) clock = TestClock() guid_factory = TestGuidFactory() logger = TestLogger() trader_id = TraderId('TESTER', '000') account_id = TestStubs.account_id() data_client = BacktestDataClient(data=data, tick_capacity=100, clock=clock, logger=logger) self.portfolio = Portfolio(currency=Currency.USD, clock=clock, guid_factory=guid_factory, logger=logger) self.analyzer = PerformanceAnalyzer() self.exec_db = InMemoryExecutionDatabase(trader_id=trader_id, logger=logger) self.exec_engine = ExecutionEngine(trader_id=trader_id, account_id=account_id, database=self.exec_db, portfolio=self.portfolio, clock=clock, guid_factory=guid_factory, logger=logger) self.exec_client = BacktestExecClient( exec_engine=self.exec_engine, instruments={usdjpy.symbol: usdjpy}, config=BacktestConfig(), fill_model=FillModel(), clock=clock, guid_factory=guid_factory, logger=logger) self.exec_engine.register_client(self.exec_client) strategies = [EmptyStrategy('001'), EmptyStrategy('002')] self.trader = Trader(trader_id=trader_id, account_id=account_id, strategies=strategies, data_client=data_client, exec_engine=self.exec_engine, clock=clock, guid_factory=guid_factory, logger=logger)
def test_change_strategies(self): # Arrange strategies = [EmptyStrategy("003"), EmptyStrategy("004")] # Act self.trader.initialize_strategies(strategies) # Assert self.assertTrue(strategies[0].id in self.trader.strategy_states()) self.assertTrue(strategies[1].id in self.trader.strategy_states()) self.assertEqual(2, len(self.trader.strategy_states()))
def test_run_with_empty_strategy(self): # Arrange usdjpy = TestStubs.instrument_usdjpy() data = BacktestDataContainer() data.add_instrument(usdjpy) data.add_bars(usdjpy.symbol, BarStructure.MINUTE, PriceType.BID, TestDataProvider.usdjpy_1min_bid()) data.add_bars(usdjpy.symbol, BarStructure.MINUTE, PriceType.ASK, TestDataProvider.usdjpy_1min_ask()) strategies = [EmptyStrategy('001')] config = BacktestConfig(exec_db_type='in-memory') engine = BacktestEngine( data=data, strategies=strategies, fill_model=FillModel(), config=config) start = datetime(2013, 1, 1, 22, 0, 0, 0, tzinfo=timezone.utc) stop = datetime(2013, 8, 10, 0, 0, 0, 0, tzinfo=timezone.utc) stats_file = 'perf_stats_backtest_run_empty.prof' cProfile.runctx('engine.run(start, stop)', globals(), locals(), stats_file) s = pstats.Stats(stats_file) s.strip_dirs().sort_stats("time").print_stats() self.assertTrue(True)
def setUp(self): self.usdjpy = InstrumentLoader.default_fx_ccy( TestStubs.symbol_usdjpy_fxcm()) data = BacktestDataContainer() data.add_instrument(self.usdjpy) data.add_bars(self.usdjpy.symbol, BarAggregation.MINUTE, PriceType.BID, TestDataProvider.usdjpy_1min_bid()[:2000]) data.add_bars(self.usdjpy.symbol, BarAggregation.MINUTE, PriceType.ASK, TestDataProvider.usdjpy_1min_ask()[:2000]) config = BacktestConfig( tick_capacity=1000, bar_capacity=1000, exec_db_type='in-memory', exec_db_flush=False, frozen_account=False, starting_capital=1000000, account_currency=USD, short_term_interest_csv_path='default', bypass_logging=False, level_console=LogLevel.DEBUG, level_file=LogLevel.DEBUG, level_store=LogLevel.WARNING, log_thread=False, log_to_file=False, ) self.engine = BacktestEngine( data=data, strategies=[EmptyStrategy('000')], venue=Venue("FXCM"), oms_type=OMSType.HEDGING, generate_position_ids=True, config=config, )
def setUp(self): self.usdjpy = TestStubs.instrument_usdjpy() data = BacktestDataContainer() data.add_instrument(self.usdjpy) data.add_bars(self.usdjpy.symbol, BarStructure.MINUTE, PriceType.BID, TestDataProvider.usdjpy_1min_bid()[:2000]) data.add_bars(self.usdjpy.symbol, BarStructure.MINUTE, PriceType.ASK, TestDataProvider.usdjpy_1min_ask()[:2000]) config = BacktestConfig(exec_db_type='in-memory', exec_db_flush=False, frozen_account=False, starting_capital=1000000, account_currency=Currency.USD, short_term_interest_csv_path='default', commission_rate_bp=0.20, bypass_logging=True, level_console=LogLevel.DEBUG, level_file=LogLevel.DEBUG, level_store=LogLevel.WARNING, log_thread=False, log_to_file=False) self.engine = BacktestEngine(data=data, strategies=[EmptyStrategy('000')], config=config)
def test_run_with_empty_strategy(self): # Arrange usdjpy = InstrumentLoader.default_fx_ccy(TestStubs.symbol_usdjpy_fxcm()) data = BacktestDataContainer() data.add_instrument(usdjpy) data.add_bars(usdjpy.symbol, BarAggregation.MINUTE, PriceType.BID, TestDataProvider.usdjpy_1min_bid()) data.add_bars(usdjpy.symbol, BarAggregation.MINUTE, PriceType.ASK, TestDataProvider.usdjpy_1min_ask()) strategies = [EmptyStrategy("001")] config = BacktestConfig(exec_db_type="in-memory") engine = BacktestEngine( data=data, strategies=strategies, venue=Venue("FXCM"), oms_type=OMSType.HEDGING, generate_position_ids=True, fill_model=FillModel(), config=config, ) start = datetime(2013, 1, 1, 22, 0, 0, 0, tzinfo=pytz.utc) stop = datetime(2013, 8, 10, 0, 0, 0, 0, tzinfo=pytz.utc) stats_file = "perf_stats_backtest_run_empty.prof" cProfile.runctx("engine.run(start, stop)", globals(), locals(), stats_file) s = pstats.Stats(stats_file) s.strip_dirs().sort_stats("time").print_stats() self.assertTrue(True)
def setUp(self): # Fixture Setup clock = TestClock() logger = TestLogger() self.trader_id = TraderId('TESTER', '000') self.strategy = EmptyStrategy(order_id_tag='001') self.strategy.change_clock(clock) self.strategy.change_logger(logger) self.database = RedisExecutionDatabase( trader_id=self.trader_id, host='localhost', port=6379, command_serializer=MsgPackCommandSerializer(), event_serializer=MsgPackEventSerializer(), logger=logger) self.test_redis = redis.Redis(host='localhost', port=6379, db=0)
def setUp(self): usdjpy = TestStubs.instrument_usdjpy() data = BacktestDataContainer() data.add_instrument(usdjpy) data.add_bars(usdjpy.symbol, BarStructure.MINUTE, PriceType.BID, TestDataProvider.usdjpy_1min_bid()[:2000]) data.add_bars(usdjpy.symbol, BarStructure.MINUTE, PriceType.ASK, TestDataProvider.usdjpy_1min_ask()[:2000]) self.engine = BacktestEngine(data=data, strategies=[EmptyStrategy('000')], fill_model=FillModel(), config=BacktestConfig())
def setUp(self): usdjpy = InstrumentLoader.default_fx_ccy( TestStubs.symbol_usdjpy_fxcm()) data = BacktestDataContainer() data.add_instrument(usdjpy) data.add_bars(usdjpy.symbol, BarAggregation.MINUTE, PriceType.BID, TestDataProvider.usdjpy_1min_bid()[:2000]) data.add_bars(usdjpy.symbol, BarAggregation.MINUTE, PriceType.ASK, TestDataProvider.usdjpy_1min_ask()[:2000]) self.engine = BacktestEngine( data=data, strategies=[EmptyStrategy("000")], venue=Venue("FXCM"), oms_type=OMSType.HEDGING, generate_position_ids=True, fill_model=FillModel(), config=BacktestConfig(), )
def setUp(self): # Fixture Setup usdjpy = InstrumentLoader.default_fx_ccy( TestStubs.symbol_usdjpy_fxcm()) data = BacktestDataContainer() data.add_instrument(usdjpy) data.add_bars(usdjpy.symbol, BarAggregation.MINUTE, PriceType.BID, TestDataProvider.usdjpy_1min_bid()[:2000]) data.add_bars(usdjpy.symbol, BarAggregation.MINUTE, PriceType.ASK, TestDataProvider.usdjpy_1min_ask()[:2000]) clock = TestClock() uuid_factory = TestUUIDFactory() logger = TestLogger(clock) trader_id = TraderId("TESTER", "000") account_id = TestStubs.account_id() self.portfolio = Portfolio( clock=clock, uuid_factory=uuid_factory, logger=logger, ) data_engine = BacktestDataEngine( data=data, tick_capacity=1000, bar_capacity=1000, portfolio=self.portfolio, clock=clock, logger=logger, ) self.analyzer = PerformanceAnalyzer() self.exec_db = BypassExecutionDatabase( trader_id=trader_id, logger=logger, ) self.exec_engine = ExecutionEngine( database=self.exec_db, portfolio=self.portfolio, clock=clock, uuid_factory=uuid_factory, logger=logger, ) self.market = SimulatedMarket( venue=Venue("FXCM"), oms_type=OMSType.HEDGING, generate_position_ids=True, exec_cache=self.exec_engine.cache, instruments={usdjpy.symbol: usdjpy}, config=BacktestConfig(), fill_model=FillModel(), commission_model=GenericCommissionModel(), clock=clock, uuid_factory=TestUUIDFactory(), logger=logger, ) self.exec_client = BacktestExecClient( market=self.market, account_id=account_id, engine=self.exec_engine, logger=logger, ) self.exec_engine.register_client(self.exec_client) strategies = [ EmptyStrategy("001"), EmptyStrategy("002"), ] self.trader = Trader( trader_id=trader_id, strategies=strategies, data_engine=data_engine, exec_engine=self.exec_engine, clock=clock, uuid_factory=uuid_factory, logger=logger, )
class RedisExecutionDatabaseTests(unittest.TestCase): def setUp(self): # Fixture Setup clock = TestClock() uuid_factory = TestUUIDFactory() logger = TestLogger(clock) self.trader_id = TraderId("TESTER", "000") self.strategy = EmptyStrategy(order_id_tag="001") self.strategy.register_trader( TraderId("TESTER", "000"), clock, uuid_factory, logger, ) config = { 'host': 'localhost', 'port': 6379 } self.database = RedisExecutionDatabase( trader_id=self.trader_id, logger=logger, command_serializer=MsgPackCommandSerializer(), event_serializer=MsgPackEventSerializer(), config=config ) self.test_redis = redis.Redis(host="localhost", port=6379, db=0) def tearDown(self): # Tests will start failing if redis is not flushed on tear down self.test_redis.flushall() # Comment this line out to preserve data between tests pass def test_keys(self): # Arrange # Act # Assert self.assertEqual("Trader-TESTER-000", self.database.key_trader) self.assertEqual("Trader-TESTER-000:Accounts:", self.database.key_accounts) self.assertEqual("Trader-TESTER-000:Orders:", self.database.key_orders) self.assertEqual("Trader-TESTER-000:Positions:", self.database.key_positions) self.assertEqual("Trader-TESTER-000:Strategies:", self.database.key_strategies) # TODO: AccountState not finalized (no serialization yet) # def test_add_account(self): # # Arrange # event = TestStubs.account_event() # account = Account(event) # # # Act # self.database.add_account(account) # # # Assert # self.assertEqual(account, self.database.load_account(account.id)) def test_add_order(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), ) position_id = PositionId.py_null() # Act self.database.add_order(order, position_id) # Assert self.assertEqual(order, self.database.load_order(order.cl_ord_id)) def test_add_position(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = PositionId('P-1') self.database.add_order(order, position_id) order_filled = TestStubs.event_order_filled(order, position_id=position_id, fill_price=Price("1.00000")) position = Position(order_filled) # Act self.database.add_position(position) # Assert self.assertEqual(position, self.database.load_position(position.id)) # TODO: Investigate why str is deserializing to a list # def test_update_account(self): # # Arrange # event = TestStubs.account_event() # account = Account(event) # self.database.add_account(account) # # # Act # self.database.update_account(account) # # # Assert # self.assertEqual(account, self.database.load_account(account.id)) def test_update_order_for_working_order(self): # Arrange order = self.strategy.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) position_id = PositionId('P-1') self.database.add_order(order, position_id) order.apply(TestStubs.event_order_submitted(order)) self.database.update_order(order) order.apply(TestStubs.event_order_accepted(order)) self.database.update_order(order) # Act order.apply(TestStubs.event_order_working(order)) self.database.update_order(order) # Assert self.assertEqual(order, self.database.load_order(order.cl_ord_id)) def test_update_order_for_completed_order(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = PositionId('P-1') self.database.add_order(order, position_id) order.apply(TestStubs.event_order_submitted(order)) self.database.update_order(order) order.apply(TestStubs.event_order_accepted(order)) self.database.update_order(order) order.apply(TestStubs.event_order_filled(order, fill_price=Price("1.00001"))) # Act self.database.update_order(order) # Assert self.assertEqual(order, self.database.load_order(order.cl_ord_id)) def test_update_position_for_closed_position(self): # Arrange order1 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = PositionId('P-1') self.database.add_order(order1, position_id) order1.apply(TestStubs.event_order_submitted(order1)) self.database.update_order(order1) order1.apply(TestStubs.event_order_accepted(order1)) self.database.update_order(order1) order1.apply(TestStubs.event_order_filled(order1, position_id=position_id, fill_price=Price("1.00001"))) self.database.update_order(order1) # Act position = Position(order1.last_event()) self.database.add_position(position) order2 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.SELL, Quantity(100000)) self.database.add_order(order2, position_id) order2.apply(TestStubs.event_order_submitted(order2)) self.database.update_order(order2) order2.apply(TestStubs.event_order_accepted(order2)) self.database.update_order(order2) filled = TestStubs.event_order_filled(order2, position_id=position_id, fill_price=Price("1.00001")) order2.apply(filled) self.database.update_order(order2) position.apply(filled) # Act self.database.update_position(position) # Assert self.assertEqual(position, self.database.load_position(position.id)) def test_load_account_when_no_account_in_database_returns_none(self): # Arrange event = TestStubs.event_account_state() account = Account(event) # Act result = self.database.load_account(account.id) # Assert self.assertIsNone(result) # TODO: Investigate why str is deserializing to a list # def test_load_account_when_account_in_database_returns_account(self): # # Arrange # event = TestStubs.account_event() # account = Account(event) # self.database.add_account(account) # # # Act # result = self.database.load_account(account.id) # # # Assert # self.assertEqual(account, result) def test_load_order_when_no_order_in_database_returns_none(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) # Act result = self.database.load_order(order.cl_ord_id) # Assert self.assertIsNone(result) def test_load_order_when_order_in_database_returns_order(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = PositionId('P-1') self.database.add_order(order, position_id) # Act result = self.database.load_order(order.cl_ord_id) # Assert self.assertEqual(order, result) def test_load_position_when_no_position_in_database_returns_none(self): # Arrange position_id = PositionId('P-1') # Act result = self.database.load_position(position_id) # Assert self.assertIsNone(result) def test_load_order_when_position_in_database_returns_position(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = PositionId('P-1') self.database.add_order(order, position_id) order_filled = TestStubs.event_order_filled(order, position_id=position_id, fill_price=Price("1.00000")) position = Position(order_filled) self.database.add_position(position) # Act result = self.database.load_position(position_id) # Assert self.assertEqual(position, result) def test_load_accounts_when_no_accounts_returns_empty_dict(self): # Arrange # Act result = self.database.load_accounts() # Assert self.assertEqual({}, result) # TODO: Investigate why str is deserializing to a list # def test_load_accounts_cache_when_one_account_in_database(self): # # Arrange # event = TestStubs.account_event() # account = Account(event) # self.database.add_account(account) # # # Act # # # Assert # self.assertEqual(account, self.database.load_account(account.id)) def test_load_orders_cache_when_no_orders(self): # Arrange # Act self.database.load_orders() # Assert self.assertEqual({}, self.database.load_orders()) def test_load_orders_cache_when_one_order_in_database(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), ) position_id = PositionId('P-1') self.database.add_order(order, position_id) # Act result = self.database.load_orders() # Assert self.assertEqual({order.cl_ord_id: order}, result) def test_load_positions_cache_when_no_positions(self): # Arrange # Act self.database.load_positions() # Assert self.assertEqual({}, self.database.load_positions()) def test_load_positions_cache_when_one_position_in_database(self): # Arrange order1 = self.strategy.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) position_id = PositionId('P-1') self.database.add_order(order1, position_id) order1.apply(TestStubs.event_order_submitted(order1)) order1.apply(TestStubs.event_order_accepted(order1)) order1.apply(TestStubs.event_order_working(order1)) order1.apply(TestStubs.event_order_filled(order1, position_id=position_id, fill_price=Price("1.00001"))) position = Position(order1.last_event()) self.database.add_position(position) # Act result = self.database.load_positions() # Assert self.assertEqual({position.id: position}, result) def test_can_delete_strategy(self): # Arrange # Act self.database.delete_strategy(self.strategy.id) result = self.database.load_strategy(self.strategy.id) # Assert self.assertEqual({}, result) def test_can_flush(self): # Arrange order1 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position1_id = PositionId('P-1') self.database.add_order(order1, position1_id) filled = TestStubs.event_order_filled(order1, position_id=position1_id, fill_price=Price("1.00000")) position1 = Position(filled) self.database.update_order(order1) self.database.add_position(position1) order2 = self.strategy.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000")) position2_id = PositionId('P-2') self.database.add_order(order2, position2_id) order2.apply(TestStubs.event_order_submitted(order2)) order2.apply(TestStubs.event_order_accepted(order2)) order2.apply(TestStubs.event_order_working(order2)) self.database.update_order(order2) # Act self.database.flush()
class RedisExecutionDatabaseTests(unittest.TestCase): # These tests require a Redis instance listening on the default port 6379 def setUp(self): # Fixture Setup clock = TestClock() logger = TestLogger() self.trader_id = TraderId('TESTER', '000') self.strategy = EmptyStrategy(order_id_tag='001') self.strategy.change_clock(clock) self.strategy.change_logger(logger) self.database = RedisExecutionDatabase( trader_id=self.trader_id, host='localhost', port=6379, command_serializer=MsgPackCommandSerializer(), event_serializer=MsgPackEventSerializer(), logger=logger) self.test_redis = redis.Redis(host='localhost', port=6379, db=0) def tearDown(self): # Tests will start failing if redis is not flushed on tear down self.test_redis.flushall() # Comment this line out to preserve data between tests pass def test_keys(self): # Arrange # Act # Assert self.assertEqual('Trader-TESTER-000', self.database.key_trader) self.assertEqual('Trader-TESTER-000:Accounts:', self.database.key_accounts) self.assertEqual('Trader-TESTER-000:Orders:', self.database.key_orders) self.assertEqual('Trader-TESTER-000:Positions:', self.database.key_positions) self.assertEqual('Trader-TESTER-000:Strategies:', self.database.key_strategies) self.assertEqual('Trader-TESTER-000:Index:OrderPosition', self.database.key_index_order_position) self.assertEqual('Trader-TESTER-000:Index:OrderStrategy', self.database.key_index_order_strategy) self.assertEqual('Trader-TESTER-000:Index:PositionStrategy', self.database.key_index_position_strategy) self.assertEqual('Trader-TESTER-000:Index:PositionOrders:', self.database.key_index_position_orders) self.assertEqual('Trader-TESTER-000:Index:StrategyOrders:', self.database.key_index_strategy_orders) self.assertEqual('Trader-TESTER-000:Index:StrategyPositions:', self.database.key_index_strategy_positions) self.assertEqual('Trader-TESTER-000:Index:Orders:Working', self.database.key_index_orders_working) self.assertEqual('Trader-TESTER-000:Index:Orders:Completed', self.database.key_index_orders_completed) self.assertEqual('Trader-TESTER-000:Index:Positions:Open', self.database.key_index_positions_open) self.assertEqual('Trader-TESTER-000:Index:Positions:Closed', self.database.key_index_positions_closed) def test_can_add_account(self): # Arrange event = TestStubs.account_event() account = Account(event) # Act self.database.add_account(account) # Assert self.assertEqual(account, self.database.get_account(account.id)) def test_can_add_order(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() # Act self.database.add_order(order, self.strategy.id, position_id) # Assert self.assertTrue(order.id in self.database.get_order_ids()) self.assertEqual(order, self.database.get_orders()[order.id]) def test_can_add_position(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() self.database.add_order(order, self.strategy.id, position_id) order_filled = TestStubs.event_order_filled(order, fill_price=Price(1.00000, 5)) position = Position(position_id, order_filled) # Act self.database.add_position(position, self.strategy.id) # Assert self.assertTrue(self.database.position_exists_for_order(order.id)) self.assertTrue(self.database.position_exists(position.id)) self.assertTrue(position.id in self.database.get_position_ids()) self.assertTrue(position.id in self.database.get_positions()) self.assertTrue(position.id in self.database.get_positions_open(self.strategy.id)) self.assertTrue(position.id in self.database.get_positions_open()) self.assertTrue(position.id not in self.database.get_positions_closed(self.strategy.id)) self.assertTrue(position.id not in self.database.get_positions_closed()) def test_can_update_account(self): # Arrange event = TestStubs.account_event() account = Account(event) self.database.add_account(account) # Act self.database.update_account(account) # Assert self.assertEqual(account, self.database.get_account(account.id)) def test_can_update_order_for_working_order(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() self.database.add_order(order, self.strategy.id, position_id) order_working = TestStubs.event_order_working(order) order.apply(order_working) # Act self.database.update_order(order) # Assert self.assertTrue(self.database.order_exists(order.id)) self.assertTrue(order.id in self.database.get_order_ids()) self.assertTrue(order.id in self.database.get_orders()) self.assertTrue(order.id in self.database.get_orders_working(self.strategy.id)) self.assertTrue(order.id in self.database.get_orders_working()) self.assertTrue(order.id not in self.database.get_orders_completed(self.strategy.id)) self.assertTrue(order.id not in self.database.get_orders_completed()) def test_can_update_order_for_completed_order(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() self.database.add_order(order, self.strategy.id, position_id) order_filled = TestStubs.event_order_filled(order, fill_price=Price(1.00001, 5)) order.apply(order_filled) # Act self.database.update_order(order) # Assert self.assertTrue(self.database.order_exists(order.id)) self.assertTrue(order.id in self.database.get_order_ids()) self.assertTrue(order.id in self.database.get_orders()) self.assertTrue(order.id in self.database.get_orders_completed(self.strategy.id)) self.assertTrue(order.id in self.database.get_orders_completed()) self.assertTrue(order.id not in self.database.get_orders_working(self.strategy.id)) self.assertTrue(order.id not in self.database.get_orders_working()) def test_can_update_position_for_closed_position(self): # Arrange order1 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() self.database.add_order(order1, self.strategy.id, position_id) order1_filled = TestStubs.event_order_filled(order1, fill_price=Price(1.00001, 5)) order1.apply(order1_filled) position = Position(position_id, order1.last_event) self.database.add_position(position, self.strategy.id) order2 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.SELL, Quantity(100000)) order2_filled = TestStubs.event_order_filled(order2, fill_price=Price(1.00001, 5)) position.apply(order2_filled) # Act self.database.update_position(position) # Assert self.assertTrue(self.database.position_exists(position.id)) self.assertTrue(position.id in self.database.get_position_ids()) self.assertTrue(position.id in self.database.get_positions()) self.assertTrue(position.id in self.database.get_positions_closed(self.strategy.id)) self.assertTrue(position.id in self.database.get_positions_closed()) self.assertTrue(position.id not in self.database.get_positions_open(self.strategy.id)) self.assertTrue(position.id not in self.database.get_positions_open()) self.assertEqual(position, self.database.get_position_for_order(order1.id)) def test_load_account_when_no_account_in_database_returns_none(self): # Arrange event = TestStubs.account_event() account = Account(event) # Act result = self.database.load_account(account.id) # Assert self.assertIsNone(result) def test_load_account_when_account_in_database_returns_account(self): # Arrange event = TestStubs.account_event() account = Account(event) self.database.add_account(account) # Act result = self.database.load_account(account.id) # Assert self.assertEqual(account, result) def test_load_order_when_no_order_in_database_returns_none(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) # Act result = self.database.load_order(order.id) # Assert self.assertIsNone(result) def test_load_order_when_order_in_database_returns_order(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() self.database.add_order(order, self.strategy.id, position_id) # Act result = self.database.load_order(order.id) # Assert self.assertEqual(order, result) def test_load_position_when_no_position_in_database_returns_none(self): # Arrange position_id = self.strategy.position_id_generator.generate() # Act result = self.database.load_position(position_id) # Assert self.assertIsNone(result) def test_load_order_when_position_in_database_returns_position(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() self.database.add_order(order, self.strategy.id, position_id) order_filled = TestStubs.event_order_filled(order, fill_price=Price(1.00000, 5)) position = Position(position_id, order_filled) self.database.add_position(position, self.strategy.id) # Act result = self.database.load_position(position_id) # Assert self.assertEqual(position, result) def test_can_load_accounts_cache_when_no_accounts(self): # Arrange # Act self.database.load_accounts_cache() event = TestStubs.account_event() account = Account(event) # Assert self.assertIsNone(self.database.get_account(account.id)) def test_can_load_accounts_cache_when_one_account_in_database(self): # Arrange event = TestStubs.account_event() account = Account(event) self.database.add_account(account) self.database.reset() # Act self.database.load_accounts_cache() # Assert self.assertEqual(account, self.database.get_account(account.id)) def test_can_load_orders_cache_when_no_orders(self): # Arrange # Act self.database.load_orders_cache() # Assert self.assertEqual({}, self.database.get_orders()) def test_can_load_orders_cache_when_one_order_in_database(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() self.database.add_order(order, self.strategy.id, position_id) # Act self.database.load_orders_cache() # Assert self.assertEqual({order.id: order}, self.database.get_orders()) def test_can_load_positions_cache_when_no_positions(self): # Arrange # Act self.database.load_positions_cache() # Assert self.assertEqual({}, self.database.get_positions()) def test_can_load_positions_cache_when_one_position_in_database(self): # Arrange order1 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position_id = self.strategy.position_id_generator.generate() self.database.add_order(order1, self.strategy.id, position_id) order1_filled = TestStubs.event_order_filled(order1, fill_price=Price(1.00001, 5)) order1.apply(order1_filled) position = Position(position_id, order1.last_event) self.database.add_position(position, self.strategy.id) # Act self.database.load_positions_cache() # Assert self.assertEqual({position_id: position}, self.database.get_positions()) def test_can_delete_strategy(self): # Arrange # Act self.database.delete_strategy(self.strategy) # Assert self.assertTrue(self.strategy.id not in self.database.get_strategy_ids()) def test_can_check_residuals(self): # Arrange order1 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position1_id = self.strategy.position_id_generator.generate() self.database.add_order(order1, self.strategy.id, position1_id) order1_filled = TestStubs.event_order_filled(order1, fill_price=Price(1.00000, 5)) position1 = Position(position1_id, order1_filled) self.database.update_order(order1) self.database.add_position(position1, self.strategy.id) order2 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position2_id = self.strategy.position_id_generator.generate() self.database.add_order(order2, self.strategy.id, position2_id) order2_working = TestStubs.event_order_working(order2) order2.apply(order2_working) self.database.update_order(order2) # Act self.database.check_residuals() # Does not raise exception def test_can_reset(self): # Arrange order1 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position1_id = self.strategy.position_id_generator.generate() self.database.add_order(order1, self.strategy.id, position1_id) order1_filled = TestStubs.event_order_filled(order1, fill_price=Price(1.00000, 5)) position1 = Position(position1_id, order1_filled) self.database.update_order(order1) self.database.add_position(position1, self.strategy.id) order2 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position2_id = self.strategy.position_id_generator.generate() self.database.add_order(order2, self.strategy.id, position2_id) order2_working = TestStubs.event_order_working(order2) order2.apply(order2_working) self.database.update_order(order2) # Act self.database.reset() # Assert self.assertEqual(0, len(self.database.get_orders())) self.assertEqual(0, len(self.database.get_positions())) def test_can_flush(self): # Arrange order1 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position1_id = self.strategy.position_id_generator.generate() self.database.add_order(order1, self.strategy.id, position1_id) order1_filled = TestStubs.event_order_filled(order1, fill_price=Price(1.00000, 5)) position1 = Position(position1_id, order1_filled) self.database.update_order(order1) self.database.add_position(position1, self.strategy.id) order2 = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) position2_id = self.strategy.position_id_generator.generate() self.database.add_order(order2, self.strategy.id, position2_id) order2_working = TestStubs.event_order_working(order2) order2.apply(order2_working) self.database.update_order(order2) # Act self.database.reset() self.database.flush() # Assert # Does not raise exception def test_get_strategy_ids_with_no_ids_returns_empty_set(self): # Arrange # Act result = self.database.get_strategy_ids() # Assert self.assertEqual(set(), result) def test_get_strategy_ids_with_id_returns_correct_set(self): # Arrange self.database.update_strategy(self.strategy) # Act result = self.database.get_strategy_ids() # Assert self.assertEqual({self.strategy.id}, result) def test_position_exists_when_no_position_returns_false(self): # Arrange # Act # Assert self.assertFalse(self.database.position_exists(PositionId('P-123456'))) def test_position_exists_for_order_when_no_position_returns_false(self): # Arrange # Act # Assert self.assertFalse(self.database.position_exists_for_order(OrderId('O-123456'))) def test_position_indexed_for_order_when_no_indexing_returns_false(self): # Arrange # Act # Assert self.assertFalse(self.database.position_indexed_for_order(OrderId('O-123456'))) def test_order_exists_when_no_order_returns_false(self): # Arrange # Act # Assert self.assertFalse(self.database.order_exists(OrderId('O-123456'))) def test_position_for_order_when_not_found_returns_none(self): # Arrange # Act # Assert self.assertIsNone(self.database.get_position_for_order(OrderId('O-123456'))) def test_get_order_when_no_order_returns_none(self): # Arrange position_id = PositionId('P-123456') # Act result = self.database.get_position(position_id) # Assert self.assertIsNone(result) def test_get_position_when_no_position_returns_none(self): # Arrange order_id = OrderId('O-201908080101-000-001') # Act result = self.database.get_order(order_id) # Assert self.assertIsNone(result)