Esempio n. 1
0
    def setUp(self):
        # Fixture Setup
        self.venue = Venue("SIM")
        self.trader_id = TestStubs.trader_id()
        self.account_id = TestStubs.account_id()
        self.serializer = MsgPackCommandSerializer()
        self.order_factory = OrderFactory(
            trader_id=self.trader_id,
            strategy_id=StrategyId("S", "001"),
            clock=TestClock(),
        )

        self.order = self.order_factory.market(
            AUDUSD,
            OrderSide.BUY,
            Quantity(100000),
        )

        self.command = SubmitOrder(
            self.venue,
            self.trader_id,
            self.account_id,
            StrategyId("SCALPER", "01"),
            PositionId("P-123456"),
            self.order,
            uuid4(),
            UNIX_EPOCH,
        )
 def setUp(self):
     # Fixture Setup
     self.venue = Venue("SIM")
     self.trader_id = TestStubs.trader_id()
     self.account_id = TestStubs.account_id()
     self.serializer = MsgPackCommandSerializer()
     self.order_factory = OrderFactory(
         trader_id=self.trader_id,
         strategy_id=StrategyId("S", "001"),
         clock=TestClock(),
     )
    def setUp(self):
        # Fixture Setup
        clock = TestClock()
        logger = TestLogger(clock)

        self.trader_id = TraderId("TESTER", "000")

        self.strategy = TradingStrategy(order_id_tag="001")
        self.strategy.register_trader(
            TraderId("TESTER", "000"),
            clock,
            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)
Esempio n. 4
0
    def setUp(self):
        # Fixture Setup
        clock = LiveClock()
        guid_factory = LiveGuidFactory()
        logger = LiveLogger()
        self.context = zmq.Context()
        self.client_sink = []
        self.server_sink = []

        self.server = MessageServer(
            ServerId("Server-001"),
            TEST_RECV_PORT,
            TEST_SEND_PORT,
            MsgPackDictionarySerializer(),
            MsgPackRequestSerializer(),
            MsgPackResponseSerializer(),
            CompressorBypass(),
            EncryptionSettings(),
            clock,
            guid_factory,
            LoggerAdapter('MessageServer', logger))

        # Register test handlers
        self.server.register_handler(MessageType.STRING, self.server_sink.append)
        self.server.start()

        self.command_serializer = MsgPackCommandSerializer()
        self.server.register_handler(MessageType.COMMAND, self.command_handler)

        self.client = MessageClient(
            ClientId("Trader-001"),
            LOCALHOST,
            TEST_RECV_PORT,
            TEST_SEND_PORT,
            MsgPackDictionarySerializer(),
            MsgPackRequestSerializer(),
            MsgPackResponseSerializer(),
            CompressorBypass(),
            EncryptionSettings(),
            clock,
            guid_factory,
            LoggerAdapter('MessageClient', logger))

        self.client.register_handler(self.client_sink.append)
Esempio n. 5
0
class SerializationPerformanceTests(unittest.TestCase):

    def setUp(self):
        # Fixture Setup
        self.venue = Venue("SIM")
        self.trader_id = TestStubs.trader_id()
        self.account_id = TestStubs.account_id()
        self.serializer = MsgPackCommandSerializer()
        self.order_factory = OrderFactory(
            trader_id=self.trader_id,
            strategy_id=StrategyId("S", "001"),
            clock=TestClock(),
        )

        self.order = self.order_factory.market(
            AUDUSD,
            OrderSide.BUY,
            Quantity(100000),
        )

        self.command = SubmitOrder(
            self.venue,
            self.trader_id,
            self.account_id,
            StrategyId("SCALPER", "01"),
            PositionId("P-123456"),
            self.order,
            uuid4(),
            UNIX_EPOCH,
        )

    def serialize_submit_order(self):
        # Arrange
        self.serializer.serialize(self.command)

    def test_make_builtin_uuid(self):
        PerformanceHarness.profile_function(self.serialize_submit_order, 10000, 1)
    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):
        # Fixture Setup
        self.clock = TestClock()
        self.logger = Logger(self.clock)
        self.trader_id = TraderId("TESTER-000")

        self.strategy = TradingStrategy(order_id_tag="001")
        self.strategy.register_trader(self.trader_id, self.clock, self.logger)

        config = {
            "host": "localhost",
            "port": 6379,
        }

        self.database = RedisCacheDatabase(
            trader_id=self.trader_id,
            logger=self.logger,
            instrument_serializer=MsgPackInstrumentSerializer(),
            command_serializer=MsgPackCommandSerializer(),
            event_serializer=MsgPackEventSerializer(),
            config=config,
        )

        self.test_redis = redis.Redis(host="localhost", port=6379, db=0)
Esempio n. 8
0
    def __init__(
        self,
        strategies: List[TradingStrategy],
        config: Dict[str, object],
    ):
        """
        Initialize a new instance of the TradingNode class.

        Parameters
        ----------
        strategies : list[TradingStrategy]
            The list of strategies to run on the trading node.
        config : dict[str, object]
            The configuration for the trading node.

        Raises
        ------
        ValueError
            If strategies is None or empty.
        ValueError
            If config is None or empty.

        """
        PyCondition.not_none(strategies, "strategies")
        PyCondition.not_none(config, "config")
        PyCondition.not_empty(strategies, "strategies")
        PyCondition.not_empty(config, "config")

        # Extract configs
        config_trader = config.get("trader", {})
        config_log = config.get("logging", {})
        config_exec_db = config.get("exec_database", {})
        config_strategy = config.get("strategy", {})
        config_adapters = config.get("adapters", {})

        self._uuid_factory = UUIDFactory()
        self._loop = asyncio.get_event_loop()
        self._executor = concurrent.futures.ThreadPoolExecutor()
        self._loop.set_default_executor(self._executor)
        self._clock = LiveClock(loop=self._loop)

        self.created_time = self._clock.utc_now()
        self._is_running = False

        # Uncomment for debugging
        # self._loop.set_debug(True)

        # Setup identifiers
        self.trader_id = TraderId(
            name=config_trader["name"],
            tag=config_trader["id_tag"],
        )

        # Setup logging
        self._logger = LiveLogger(
            clock=self._clock,
            name=self.trader_id.value,
            level_console=LogLevelParser.from_str_py(config_log.get("log_level_console")),
            level_file=LogLevelParser.from_str_py(config_log.get("log_level_file")),
            level_store=LogLevelParser.from_str_py(config_log.get("log_level_store")),
            run_in_process=config_log.get("run_in_process", True),  # Run logger in a separate process
            log_thread=config_log.get("log_thread_id", False),
            log_to_file=config_log.get("log_to_file", False),
            log_file_path=config_log.get("log_file_path", ""),
        )

        self._log = LoggerAdapter(component_name=self.__class__.__name__, logger=self._logger)
        self._log_header()
        self._log.info("Building...")

        self._setup_loop()  # Requires the logger to be initialized

        self.portfolio = Portfolio(
            clock=self._clock,
            logger=self._logger,
        )

        self._data_engine = LiveDataEngine(
            loop=self._loop,
            portfolio=self.portfolio,
            clock=self._clock,
            logger=self._logger,
            config={"qsize": 10000},
        )

        self.portfolio.register_cache(self._data_engine.cache)
        self.analyzer = PerformanceAnalyzer()

        if config_exec_db["type"] == "redis":
            exec_db = RedisExecutionDatabase(
                trader_id=self.trader_id,
                logger=self._logger,
                command_serializer=MsgPackCommandSerializer(),
                event_serializer=MsgPackEventSerializer(),
                config={
                    "host": config_exec_db["host"],
                    "port": config_exec_db["port"],
                }
            )
        else:
            exec_db = BypassExecutionDatabase(
                trader_id=self.trader_id,
                logger=self._logger,
            )

        self._exec_engine = LiveExecutionEngine(
            loop=self._loop,
            database=exec_db,
            portfolio=self.portfolio,
            clock=self._clock,
            logger=self._logger,
            config={"qsize": 10000},
        )

        self._exec_engine.load_cache()
        self._setup_adapters(config_adapters, self._logger)

        self.trader = Trader(
            trader_id=self.trader_id,
            strategies=strategies,
            portfolio=self.portfolio,
            data_engine=self._data_engine,
            exec_engine=self._exec_engine,
            clock=self._clock,
            logger=self._logger,
        )

        self._check_residuals_delay = config_trader.get("check_residuals_delay", 5.0)
        self._load_strategy_state = config_strategy.get("load_state", True)
        self._save_strategy_state = config_strategy.get("save_state", True)

        if self._load_strategy_state:
            self.trader.load()

        self._log.info("state=INITIALIZED.")
        self.time_to_initialize = self._clock.delta(self.created_time)
        self._log.info(f"Initialized in {self.time_to_initialize.total_seconds():.3f}s.")
Esempio n. 9
0
    def __init__(
        self,
        strategies: List[TradingStrategy],
        config: Dict[str, object],
    ):
        """
        Initialize a new instance of the TradingNode class.

        Parameters
        ----------
        strategies : list[TradingStrategy]
            The list of strategies to run on the trading node.
        config : dict[str, object]
            The configuration for the trading node.

        """
        if strategies is None:
            strategies = []

        config_trader = config.get("trader", {})
        config_log = config.get("logging", {})
        config_exec_db = config.get("exec_database", {})
        config_strategy = config.get("strategy", {})
        config_data_clients = config.get("data_clients", {})
        config_exec_clients = config.get("exec_clients", {})

        self._clock = LiveClock()
        self._uuid_factory = UUIDFactory()
        self._loop = asyncio.get_event_loop()
        self._executor = concurrent.futures.ThreadPoolExecutor()
        self._loop.set_default_executor(self._executor)
        self._loop.set_debug(False)  # TODO: Development
        self._is_running = False

        # Setup identifiers
        self.trader_id = TraderId(
            name=config_trader["name"],
            tag=config_trader["id_tag"],
        )

        # Setup logging
        logger = LiveLogger(
            clock=self._clock,
            name=self.trader_id.value,
            level_console=LogLevelParser.from_str_py(
                config_log.get("log_level_console")),
            level_file=LogLevelParser.from_str_py(
                config_log.get("log_level_file")),
            level_store=LogLevelParser.from_str_py(
                config_log.get("log_level_store")),
            log_thread=config_log.get("log_thread_id", True),
            log_to_file=config_log.get("log_to_file", False),
            log_file_path=config_log.get("log_file_path", ""),
        )

        self._log = LoggerAdapter(component_name=self.__class__.__name__,
                                  logger=logger)
        self._log_header()
        self._log.info("Building...")

        self.portfolio = Portfolio(
            clock=self._clock,
            logger=logger,
        )

        self._data_engine = LiveDataEngine(
            loop=self._loop,
            portfolio=self.portfolio,
            clock=self._clock,
            logger=logger,
        )

        self.portfolio.register_cache(self._data_engine.cache)
        self.analyzer = PerformanceAnalyzer()

        if config_exec_db["type"] == "redis":
            exec_db = RedisExecutionDatabase(
                trader_id=self.trader_id,
                logger=logger,
                command_serializer=MsgPackCommandSerializer(),
                event_serializer=MsgPackEventSerializer(),
                config={
                    "host": config_exec_db["host"],
                    "port": config_exec_db["port"],
                })
        else:
            exec_db = BypassExecutionDatabase(
                trader_id=self.trader_id,
                logger=logger,
            )

        self._exec_engine = LiveExecutionEngine(
            loop=self._loop,
            database=exec_db,
            portfolio=self.portfolio,
            clock=self._clock,
            logger=logger,
        )

        self._exec_engine.load_cache()
        self._setup_data_clients(config_data_clients, logger)
        self._setup_exec_clients(config_exec_clients, logger)

        self.trader = Trader(
            trader_id=self.trader_id,
            strategies=strategies,
            data_engine=self._data_engine,
            exec_engine=self._exec_engine,
            clock=self._clock,
            logger=logger,
        )

        self._check_residuals_delay = 2.0  # Hard coded delay (refactor)
        self._load_strategy_state = config_strategy.get("load_state", True)
        self._save_strategy_state = config_strategy.get("save_state", True)

        if self._load_strategy_state:
            self.trader.load()

        self._setup_loop()
        self._log.info("state=INITIALIZED.")
class MsgPackCommandSerializerTests(unittest.TestCase):
    def setUp(self):
        # Fixture Setup
        self.venue = Venue("SIM")
        self.trader_id = TestStubs.trader_id()
        self.account_id = TestStubs.account_id()
        self.serializer = MsgPackCommandSerializer()
        self.order_factory = OrderFactory(
            trader_id=self.trader_id,
            strategy_id=StrategyId("S", "001"),
            clock=TestClock(),
        )

    def test_serialize_and_deserialize_submit_order_commands(self):
        # Arrange
        order = self.order_factory.market(AUDUSD_SIM.symbol, OrderSide.BUY,
                                          Quantity(100000))

        command = SubmitOrder(
            self.venue,
            self.trader_id,
            self.account_id,
            StrategyId("SCALPER", "01"),
            PositionId("P-123456"),
            order,
            uuid4(),
            UNIX_EPOCH,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        self.assertEqual(command, deserialized)
        self.assertEqual(order, deserialized.order)
        print(command)
        print(len(serialized))
        print(serialized)
        print(b64encode(serialized))

    def test_serialize_and_deserialize_submit_bracket_order_no_take_profit_commands(
            self):
        # Arrange
        entry_order = self.order_factory.market(AUDUSD_SIM.symbol,
                                                OrderSide.BUY,
                                                Quantity(100000))

        bracket_order = self.order_factory.bracket(
            entry_order,
            stop_loss=Price("0.99900"),
        )

        command = SubmitBracketOrder(
            self.venue,
            self.trader_id,
            self.account_id,
            StrategyId("SCALPER", "01"),
            bracket_order,
            uuid4(),
            UNIX_EPOCH,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        self.assertEqual(command, deserialized)
        self.assertEqual(bracket_order, deserialized.bracket_order)
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_submit_bracket_order_with_take_profit_commands(
            self):
        # Arrange
        entry_order = self.order_factory.limit(
            AUDUSD_SIM.symbol,
            OrderSide.BUY,
            Quantity(100000),
            Price("1.00000"),
        )

        bracket_order = self.order_factory.bracket(
            entry_order,
            stop_loss=Price("0.99900"),
            take_profit=Price("1.00010"),
        )

        command = SubmitBracketOrder(
            self.venue,
            self.trader_id,
            self.account_id,
            StrategyId("SCALPER", "01"),
            bracket_order,
            uuid4(),
            UNIX_EPOCH,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        self.assertEqual(command, deserialized)
        self.assertEqual(bracket_order, deserialized.bracket_order)
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_modify_order_commands(self):
        # Arrange
        command = ModifyOrder(
            self.venue,
            self.trader_id,
            self.account_id,
            ClientOrderId("O-123456"),
            Quantity(100000),
            Price("1.00001"),
            uuid4(),
            UNIX_EPOCH,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        self.assertEqual(command, deserialized)
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_cancel_order_commands(self):
        # Arrange
        command = CancelOrder(
            self.venue,
            self.trader_id,
            self.account_id,
            ClientOrderId("O-123456"),
            uuid4(),
            UNIX_EPOCH,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        self.assertEqual(command, deserialized)
        print(b64encode(serialized))
        print(command)
Esempio n. 11
0
    def __init__(
        self,
        strategies: List[TradingStrategy],
        config: Dict[str, object],
    ):
        """
        Initialize a new instance of the TradingNode class.

        Parameters
        ----------
        strategies : list[TradingStrategy]
            The list of strategies to run on the trading node.
        config : dict[str, object]
            The configuration for the trading node.

        Raises
        ------
        ValueError
            If strategies is None or empty.
        ValueError
            If config is None or empty.

        """
        PyCondition.not_none(strategies, "strategies")
        PyCondition.not_none(config, "config")
        PyCondition.not_empty(strategies, "strategies")
        PyCondition.not_empty(config, "config")

        self._config = config

        # Extract configs
        config_trader = config.get("trader", {})
        config_system = config.get("system", {})
        config_log = config.get("logging", {})
        config_exec_db = config.get("exec_database", {})
        config_risk = config.get("risk", {})
        config_strategy = config.get("strategy", {})

        # System config
        self._connection_timeout = config_system.get("connection_timeout", 5.0)
        self._disconnection_timeout = config_system.get(
            "disconnection_timeout", 5.0)
        self._check_residuals_delay = config_system.get(
            "check_residuals_delay", 5.0)
        self._load_strategy_state = config_strategy.get("load_state", True)
        self._save_strategy_state = config_strategy.get("save_state", True)

        # Setup loop
        self._loop = asyncio.get_event_loop()
        self._executor = concurrent.futures.ThreadPoolExecutor()
        self._loop.set_default_executor(self._executor)
        self._loop.set_debug(config_system.get("loop_debug", False))

        # Components
        self._clock = LiveClock(loop=self._loop)
        self._uuid_factory = UUIDFactory()
        self.system_id = self._uuid_factory.generate()
        self.created_time = self._clock.utc_now()
        self._is_running = False

        # Setup identifiers
        self.trader_id = TraderId(
            name=config_trader["name"],
            tag=config_trader["id_tag"],
        )

        # Setup logging
        level_stdout = LogLevelParser.from_str_py(
            config_log.get("level_stdout"))

        self._logger = LiveLogger(
            loop=self._loop,
            clock=self._clock,
            trader_id=self.trader_id,
            system_id=self.system_id,
            level_stdout=level_stdout,
        )

        self._log = LoggerAdapter(
            component=self.__class__.__name__,
            logger=self._logger,
        )

        self._log_header()
        self._log.info("Building...")

        if platform.system() != "Windows":
            # Requires the logger to be initialized
            # Windows does not support signal handling
            # https://stackoverflow.com/questions/45987985/asyncio-loops-add-signal-handler-in-windows
            self._setup_loop()

        # Build platform
        # ----------------------------------------------------------------------
        self.portfolio = Portfolio(
            clock=self._clock,
            logger=self._logger,
        )

        self._data_engine = LiveDataEngine(
            loop=self._loop,
            portfolio=self.portfolio,
            clock=self._clock,
            logger=self._logger,
            config={"qsize": 10000},
        )

        self.portfolio.register_cache(self._data_engine.cache)
        self.analyzer = PerformanceAnalyzer()

        if config_exec_db["type"] == "redis":
            exec_db = RedisExecutionDatabase(
                trader_id=self.trader_id,
                logger=self._logger,
                command_serializer=MsgPackCommandSerializer(),
                event_serializer=MsgPackEventSerializer(),
                config={
                    "host": config_exec_db["host"],
                    "port": config_exec_db["port"],
                },
            )
        else:
            exec_db = BypassExecutionDatabase(
                trader_id=self.trader_id,
                logger=self._logger,
            )

        self._exec_engine = LiveExecutionEngine(
            loop=self._loop,
            database=exec_db,
            portfolio=self.portfolio,
            clock=self._clock,
            logger=self._logger,
            config={"qsize": 10000},
        )

        self._risk_engine = LiveRiskEngine(
            loop=self._loop,
            exec_engine=self._exec_engine,
            portfolio=self.portfolio,
            clock=self._clock,
            logger=self._logger,
            config=config_risk,
        )

        self._exec_engine.load_cache()
        self._exec_engine.register_risk_engine(self._risk_engine)

        self.trader = Trader(
            trader_id=self.trader_id,
            strategies=strategies,
            portfolio=self.portfolio,
            data_engine=self._data_engine,
            exec_engine=self._exec_engine,
            risk_engine=self._risk_engine,
            clock=self._clock,
            logger=self._logger,
        )

        if self._load_strategy_state:
            self.trader.load()

        self._builder = TradingNodeBuilder(
            data_engine=self._data_engine,
            exec_engine=self._exec_engine,
            risk_engine=self._risk_engine,
            clock=self._clock,
            logger=self._logger,
            log=self._log,
        )

        self._log.info("state=INITIALIZED.")
        self.time_to_initialize = self._clock.delta(self.created_time)
        self._log.info(
            f"Initialized in {self.time_to_initialize.total_seconds():.3f}s.")

        self._is_built = False
Esempio n. 12
0
class MessageClientTests(unittest.TestCase):

    def setUp(self):
        # Fixture Setup
        clock = LiveClock()
        guid_factory = LiveGuidFactory()
        logger = LiveLogger()
        self.context = zmq.Context()
        self.client_sink = []
        self.server_sink = []

        self.server = MessageServer(
            ServerId("Server-001"),
            TEST_RECV_PORT,
            TEST_SEND_PORT,
            MsgPackDictionarySerializer(),
            MsgPackRequestSerializer(),
            MsgPackResponseSerializer(),
            CompressorBypass(),
            EncryptionSettings(),
            clock,
            guid_factory,
            LoggerAdapter('MessageServer', logger))

        # Register test handlers
        self.server.register_handler(MessageType.STRING, self.server_sink.append)
        self.server.start()

        self.command_serializer = MsgPackCommandSerializer()
        self.server.register_handler(MessageType.COMMAND, self.command_handler)

        self.client = MessageClient(
            ClientId("Trader-001"),
            LOCALHOST,
            TEST_RECV_PORT,
            TEST_SEND_PORT,
            MsgPackDictionarySerializer(),
            MsgPackRequestSerializer(),
            MsgPackResponseSerializer(),
            CompressorBypass(),
            EncryptionSettings(),
            clock,
            guid_factory,
            LoggerAdapter('MessageClient', logger))

        self.client.register_handler(self.client_sink.append)

    def tearDown(self):
        # Tear Down
        self.client.disconnect()
        self.server.stop()
        # Allowing the garbage collector to clean up resources avoids threading
        # errors caused by the continuous disposal of sockets. Thus for testing
        # we're avoiding calling .dispose() on the sockets.

    def command_handler(self, message):
        command = self.command_serializer.deserialize(message)
        self.server_sink.append(command)

    def test_can_connect_to_server_and_receive_response(self):
        # Arrange
        # Act
        self.client.connect()

        time.sleep(0.1)

        # Assert
        self.assertTrue(self.client.is_connected())

    def test_can_send_one_string_message(self):
        # Arrange
        self.client.connect()

        # Act
        self.client.send_string('hello')

        time.sleep(0.1)

        # Assert
        self.assertEqual(2, self.client.sent_count)
        self.assertEqual(2, self.client.recv_count)
        self.assertEqual(2, self.server.sent_count)
        self.assertEqual(2, self.server.recv_count)
        self.assertEqual(1, len(self.client_sink))
        self.assertEqual(1, len(self.server_sink))
        self.assertEqual('hello', self.server_sink[0])
        self.assertEqual('OK', self.client_sink[0])

    def test_can_send_multiple_messages_and_receive_correctly_ordered_responses(self):
        # Arrange
        self.client.connect()

        # Act
        self.client.send_string('hello1')
        self.client.send_string('hello2')
        self.client.send_string('hello3')

        time.sleep(0.1)

        # Assert
        self.assertEqual(4, self.client.sent_count)
        self.assertEqual(4, self.client.recv_count)
        self.assertEqual(4, self.server.sent_count)
        self.assertEqual(4, self.server.recv_count)
        self.assertEqual(3, len(self.client_sink))
        self.assertEqual(3, len(self.server_sink))
        self.assertEqual('hello1', self.server_sink[0])
        self.assertEqual('hello2', self.server_sink[1])
        self.assertEqual('hello3', self.server_sink[2])
        self.assertEqual('OK', self.client_sink[0])
        self.assertEqual('OK', self.client_sink[1])
        self.assertEqual('OK', self.client_sink[2])
Esempio n. 13
0
    def setUp(self):
        # Fixture Setup
        trader_id = TraderId('TESTER', '000')
        account_id = TestStubs.account_id()

        clock = LiveClock()
        guid_factory = LiveGuidFactory()
        logger = LiveLogger()

        self.command_server = MessageServer(
            server_id=ServerId("CommandServer-001"),
            recv_port=TEST_COMMANDS_REQ_PORT,
            send_port=TEST_COMMANDS_REP_PORT,
            header_serializer=MsgPackDictionarySerializer(),
            request_serializer=MsgPackRequestSerializer(),
            response_serializer=MsgPackResponseSerializer(),
            compressor=CompressorBypass(),
            encryption=EncryptionSettings(),
            clock=clock,
            guid_factory=guid_factory,
            logger=LoggerAdapter('CommandServer', logger))

        self.command_serializer = MsgPackCommandSerializer()

        self.command_server_sink = []
        self.command_server.register_handler(MessageType.COMMAND, self.command_handler)
        self.command_server.start()

        time.sleep(0.1)

        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 = LiveExecutionEngine(
            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_engine.handle_event(TestStubs.account_event())

        self.exec_client = LiveExecClient(
            exec_engine=self.exec_engine,
            host=LOCALHOST,
            command_req_port=TEST_COMMANDS_REQ_PORT,
            command_res_port=TEST_COMMANDS_REP_PORT,
            event_pub_port=TEST_EVENTS_PUB_PORT,
            compressor=CompressorBypass(),
            encryption=EncryptionSettings(),
            command_serializer=MsgPackCommandSerializer(),
            header_serializer=MsgPackDictionarySerializer(),
            request_serializer=MsgPackRequestSerializer(),
            response_serializer=MsgPackResponseSerializer(),
            event_serializer=MsgPackEventSerializer(),
            clock=clock,
            guid_factory=guid_factory,
            logger=logger)

        self.exec_engine.register_client(self.exec_client)
        self.exec_client.connect()

        time.sleep(0.1)

        self.bar_type = TestStubs.bartype_audusd_1min_bid()
        self.strategy = TestStrategy1(self.bar_type, id_tag_strategy='001')
        self.strategy.change_logger(logger)
        self.exec_engine.register_strategy(self.strategy)
Esempio n. 14
0
class LiveExecutionTests(unittest.TestCase):

    def setUp(self):
        # Fixture Setup
        trader_id = TraderId('TESTER', '000')
        account_id = TestStubs.account_id()

        clock = LiveClock()
        guid_factory = LiveGuidFactory()
        logger = LiveLogger()

        self.command_server = MessageServer(
            server_id=ServerId("CommandServer-001"),
            recv_port=TEST_COMMANDS_REQ_PORT,
            send_port=TEST_COMMANDS_REP_PORT,
            header_serializer=MsgPackDictionarySerializer(),
            request_serializer=MsgPackRequestSerializer(),
            response_serializer=MsgPackResponseSerializer(),
            compressor=CompressorBypass(),
            encryption=EncryptionSettings(),
            clock=clock,
            guid_factory=guid_factory,
            logger=LoggerAdapter('CommandServer', logger))

        self.command_serializer = MsgPackCommandSerializer()

        self.command_server_sink = []
        self.command_server.register_handler(MessageType.COMMAND, self.command_handler)
        self.command_server.start()

        time.sleep(0.1)

        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 = LiveExecutionEngine(
            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_engine.handle_event(TestStubs.account_event())

        self.exec_client = LiveExecClient(
            exec_engine=self.exec_engine,
            host=LOCALHOST,
            command_req_port=TEST_COMMANDS_REQ_PORT,
            command_res_port=TEST_COMMANDS_REP_PORT,
            event_pub_port=TEST_EVENTS_PUB_PORT,
            compressor=CompressorBypass(),
            encryption=EncryptionSettings(),
            command_serializer=MsgPackCommandSerializer(),
            header_serializer=MsgPackDictionarySerializer(),
            request_serializer=MsgPackRequestSerializer(),
            response_serializer=MsgPackResponseSerializer(),
            event_serializer=MsgPackEventSerializer(),
            clock=clock,
            guid_factory=guid_factory,
            logger=logger)

        self.exec_engine.register_client(self.exec_client)
        self.exec_client.connect()

        time.sleep(0.1)

        self.bar_type = TestStubs.bartype_audusd_1min_bid()
        self.strategy = TestStrategy1(self.bar_type, id_tag_strategy='001')
        self.strategy.change_logger(logger)
        self.exec_engine.register_strategy(self.strategy)

    def tearDown(self):
        # Tear Down
        self.exec_client.disconnect()
        self.command_server.stop()
        # Allowing the garbage collector to clean up resources avoids threading
        # errors caused by the continuous disposal of sockets. Thus for testing
        # we're avoiding calling .dispose() on the sockets.

    def command_handler(self, message):
        command = self.command_serializer.deserialize(message)
        self.command_server_sink.append(command)

    def test_can_send_submit_order_command(self):
        # Arrange
        order = self.strategy.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000))

        # Act
        self.strategy.submit_order(order, self.strategy.position_id_generator.generate())

        time.sleep(0.3)
        # # Assert
        self.assertEqual(order, self.strategy.order(order.id))
        self.assertEqual(2, self.command_server.recv_count)
        self.assertEqual(1, self.command_server.sent_count)
        self.assertEqual(SubmitOrder, type(self.command_server_sink[0]))

    def test_can_send_submit_atomic_order(self):
        # Arrange
        atomic_order = self.strategy.order_factory.atomic_market(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000),
            Price(0.99900, 5))

        # Act
        self.strategy.submit_atomic_order(atomic_order, self.strategy.position_id_generator.generate())

        time.sleep(0.3)
        # Assert
        self.assertEqual(atomic_order.entry, self.strategy.order(atomic_order.entry.id))
        self.assertEqual(atomic_order.stop_loss, self.strategy.order(atomic_order.stop_loss.id))
        self.assertEqual(2, self.command_server.recv_count)
        self.assertEqual(1, self.command_server.sent_count)
        self.assertEqual(SubmitAtomicOrder, type(self.command_server_sink[0]))

    def test_can_send_cancel_order_command(self):
        # Arrange
        order = self.strategy.order_factory.market(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000))

        # Act
        self.strategy.submit_order(order, self.strategy.position_id_generator.generate())
        self.strategy.cancel_order(order, 'SIGNAL_GONE')

        time.sleep(0.3)
        # Assert
        self.assertEqual(order, self.strategy.order(order.id))
        self.assertEqual(3, self.command_server.recv_count)
        self.assertEqual(1, self.command_server.sent_count)
        self.assertEqual(SubmitOrder, type(self.command_server_sink[0]))
        self.assertEqual(CancelOrder, type(self.command_server_sink[1]))

    def test_can_send_modify_order_command(self):
        # Arrange
        order = self.strategy.order_factory.limit(
            AUDUSD_FXCM,
            OrderSide.BUY,
            Quantity(100000),
            Price(1.00000, 5))

        # Act
        self.strategy.submit_order(order, self.strategy.position_id_generator.generate())
        self.strategy.modify_order(order, Quantity(110000), Price(1.00001, 5))

        time.sleep(0.3)
        # Assert
        self.assertEqual(order, self.strategy.order(order.id))
        self.assertEqual(3, self.command_server.recv_count)
        self.assertEqual(1, self.command_server.sent_count)
        self.assertEqual(SubmitOrder, type(self.command_server_sink[0]))
        self.assertEqual(ModifyOrder, type(self.command_server_sink[1]))

    def test_can_send_account_inquiry_command(self):
        # Arrange
        # Act
        self.strategy.account_inquiry()

        time.sleep(0.3)
        # Assert
        self.assertEqual(2, self.command_server.recv_count)
        self.assertEqual(1, self.command_server.sent_count)
        self.assertEqual(AccountInquiry, type(self.command_server_sink[0]))
Esempio n. 15
0
class TestMsgPackCommandSerializer:
    def setup(self):
        # Fixture Setup
        self.venue = Venue("SIM")
        self.trader_id = TestStubs.trader_id()
        self.account_id = TestStubs.account_id()
        self.serializer = MsgPackCommandSerializer()
        self.order_factory = OrderFactory(
            trader_id=self.trader_id,
            strategy_id=StrategyId("S", "001"),
            clock=TestClock(),
        )

    def test_serialize_and_deserialize_submit_order_commands(self):
        # Arrange
        order = self.order_factory.market(AUDUSD_SIM.id, OrderSide.BUY,
                                          Quantity(100000))

        command = SubmitOrder(
            order.instrument_id.venue.client_id,
            self.trader_id,
            self.account_id,
            StrategyId("SCALPER", "01"),
            PositionId("P-123456"),
            order,
            uuid4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        assert deserialized.order == order
        print(command)
        print(len(serialized))
        print(serialized)
        print(b64encode(serialized))

    def test_serialize_and_deserialize_submit_bracket_order_no_take_profit_commands(
        self, ):
        # Arrange
        entry_order = self.order_factory.market(AUDUSD_SIM.id, OrderSide.BUY,
                                                Quantity(100000))

        bracket_order = self.order_factory.bracket(
            entry_order,
            stop_loss=Price("0.99900"),
            take_profit=Price("1.00100"),
        )

        command = SubmitBracketOrder(
            entry_order.instrument_id.venue.client_id,
            self.trader_id,
            self.account_id,
            StrategyId("SCALPER", "01"),
            bracket_order,
            uuid4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        assert deserialized.bracket_order == bracket_order
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_submit_bracket_order_with_take_profit_commands(
        self, ):
        # Arrange
        entry_order = self.order_factory.limit(
            AUDUSD_SIM.id,
            OrderSide.BUY,
            Quantity(100000),
            Price("1.00000"),
        )

        bracket_order = self.order_factory.bracket(
            entry_order,
            stop_loss=Price("0.99900"),
            take_profit=Price("1.00010"),
        )

        command = SubmitBracketOrder(
            entry_order.instrument_id.venue.client_id,
            self.trader_id,
            self.account_id,
            StrategyId("SCALPER", "01"),
            bracket_order,
            uuid4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        assert deserialized.bracket_order == bracket_order
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_amend_order_commands(self):
        # Arrange
        command = UpdateOrder(
            AUDUSD_SIM.id.venue.client_id,
            self.trader_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            Quantity(100000),
            Price("1.00001"),
            uuid4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        print(b64encode(serialized))
        print(command)

    def test_serialize_and_deserialize_cancel_order_commands(self):
        # Arrange
        command = CancelOrder(
            AUDUSD_SIM.id.venue.client_id,
            self.trader_id,
            self.account_id,
            AUDUSD_SIM.id,
            ClientOrderId("O-123456"),
            VenueOrderId("001"),
            uuid4(),
            0,
        )

        # Act
        serialized = self.serializer.serialize(command)
        deserialized = self.serializer.deserialize(serialized)

        # Assert
        assert deserialized == command
        print(b64encode(serialized))
        print(command)