Exemple #1
0
    def test_config_with_inmemory_execution_database(self):
        # Arrange
        config = TradingNodeConfig(cache_database=CacheDatabaseConfig(
            type="in-memory"))

        # Act
        node = TradingNode(config=config)

        # Assert
        assert node is not None
config_node = TradingNodeConfig(
    trader_id="TESTER-001",
    log_level="INFO",
    exec_engine={
        "reconciliation_lookback_mins": 1440,
    },
    # cache_database=CacheDatabaseConfig(),
    data_clients={
        "BINANCE": BinanceDataClientConfig(
            api_key=None,  # "YOUR_BINANCE_API_KEY"
            api_secret=None,  # "YOUR_BINANCE_API_SECRET"
            account_type=BinanceAccountType.SPOT,
            base_url_http=None,  # Override with custom endpoint
            base_url_ws=None,  # Override with custom endpoint
            us=False,  # If client is for Binance US
            testnet=False,  # If client uses the testnet
            instrument_provider=InstrumentProviderConfig(load_all=True),
        ),
    },
    exec_clients={
        "BINANCE": BinanceExecClientConfig(
            api_key=None,  # "YOUR_BINANCE_API_KEY"
            api_secret=None,  # "YOUR_BINANCE_API_SECRET"
            account_type=BinanceAccountType.SPOT,
            base_url_http=None,  # Override with custom endpoint
            base_url_ws=None,  # Override with custom endpoint
            us=False,  # If client is for Binance US
            testnet=False,  # If client uses the testnet
            load_all_instruments=True,  # If load all instruments on start
            load_instrument_ids=[],  # Optionally pass a list of instrument IDs
            instrument_provider=InstrumentProviderConfig(load_all=True),
        ),
    },
    timeout_connection=5.0,
    timeout_reconciliation=5.0,
    timeout_portfolio=5.0,
    timeout_disconnection=5.0,
    check_residuals_delay=2.0,
)
config_node = TradingNodeConfig(
    trader_id="TESTER-001",
    log_level="INFO",
    exec_engine={
        "reconciliation_lookback_mins": 1440,
    },
    # cache_database=CacheDatabaseConfig(),
    data_clients={
        "FTX":
        FTXDataClientConfig(
            api_key=None,  # "YOUR_FTX_API_KEY"
            api_secret=None,  # "YOUR_FTX_API_SECRET"
            subaccount=None,  # "YOUR_FTX_SUBACCOUNT"
            us=False,  # If client is for FTX US
            instrument_provider=InstrumentProviderConfig(load_all=True),
        ),
    },
    exec_clients={
        "FTX":
        FTXExecClientConfig(
            api_key=None,  # "YOUR_FTX_API_KEY"
            api_secret=None,  # "YOUR_FTX_API_SECRET"
            subaccount=None,  # "YOUR_FTX_SUBACCOUNT"
            us=False,  # If client is for FTX US
            instrument_provider=InstrumentProviderConfig(load_all=True),
        ),
    },
    timeout_connection=5.0,
    timeout_reconciliation=5.0,
    timeout_portfolio=5.0,
    timeout_disconnection=5.0,
    check_residuals_delay=2.0,
)
Exemple #4
0
config_node = TradingNodeConfig(
    trader_id="TESTER-001",
    log_level="INFO",
    exec_engine={
        "reconciliation_lookback_mins": 1440,
    },
    # cache_database=CacheDatabaseConfig(),
    data_clients={
        "BINANCE":
        BinanceDataClientConfig(
            # api_key=os.getenv("BINANCE_FUTURES_API_KEY"),
            # api_secret=os.getenv("BINANCE_FUTURES_API_SECRET"),
            account_type=BinanceAccountType.FUTURES_USDT,
            instrument_provider=InstrumentProviderConfig(load_all=True),
        ),
    },
    exec_clients={
        "BINANCE":
        BinanceExecClientConfig(
            # api_key=os.getenv("BINANCE_FUTURES_API_KEY"),
            # api_secret=os.getenv("BINANCE_FUTURES_API_SECRET"),
            account_type=BinanceAccountType.FUTURES_USDT,
            instrument_provider=InstrumentProviderConfig(load_all=True),
        ),
    },
    timeout_connection=5.0,
    timeout_reconciliation=5.0,
    timeout_portfolio=5.0,
    timeout_disconnection=5.0,
    check_residuals_delay=2.0,
)
Exemple #5
0
async def main(market_id: str):
    # Connect to Betfair client early to load instruments and account currency
    loop = asyncio.get_event_loop()
    logger = LiveLogger(loop=loop, clock=LiveClock())
    client = get_cached_betfair_client(
        username=
        None,  # Pass here or will source from the `BETFAIR_USERNAME` env var
        password=
        None,  # Pass here or will source from the `BETFAIR_PASSWORD` env var
        app_key=
        None,  # Pass here or will source from the `BETFAIR_APP_KEY` env var
        cert_dir=
        None,  # Pass here or will source from the `BETFAIR_CERT_DIR` env var
        logger=logger,
        loop=loop,
    )
    await client.connect()

    # Find instruments for a particular market_id
    market_filter = {"market_id": (market_id, )}
    provider = get_cached_betfair_instrument_provider(
        client=client,
        logger=logger,
        market_filter=tuple(market_filter.items()),
    )
    await provider.load_all_async()
    instruments = provider.list_all()
    print(f"Found instruments:\n{instruments}")

    # Determine account currency
    account = await client.get_account_details()

    # Configure trading node
    config = TradingNodeConfig(
        timeout_connection=30.0,
        log_level="DEBUG",
        cache_database=CacheDatabaseConfig(type="in-memory"),
        exec_engine={"allow_cash_positions":
                     True},  # Retain original behaviour for now
        data_clients={
            "BETFAIR": {
                # "username": "******",
                # "password": "******",
                # "app_key": "YOUR_BETFAIR_APP_KEY",
                # "cert_dir": "YOUR_BETFAIR_CERT_DIR",
                "market_filter": market_filter,
            },
        },
        exec_clients={
            "BETFAIR": {
                "base_currency": account["currencyCode"],
                # "username": "******",
                # "password": "******",
                # "app_key": "YOUR_BETFAIR_APP_KEY",
                # "cert_dir": "YOUR_BETFAIR_CERT_DIR",
                "market_filter": market_filter,
            },
        },
    )
    strategies = [
        OrderBookImbalance(config=OrderBookImbalanceConfig(
            instrument_id=instrument.id.value,
            max_trade_size=10,
            order_id_tag=instrument.selection_id,
        )) for instrument in instruments
    ]

    # Setup TradingNode
    node = TradingNode(config=config)
    node.trader.add_strategies(strategies)

    # Register your client factories with the node (can take user defined factories)
    node.add_data_client_factory("BETFAIR", BetfairLiveDataClientFactory)
    node.add_exec_client_factory("BETFAIR", BetfairLiveExecClientFactory)
    node.build()

    try:
        await node.start()
    except Exception as ex:
        print(ex)
        print(traceback.format_exc())
    finally:
        node.dispose()
Exemple #6
0
    def __init__(self, config: Optional[TradingNodeConfig] = None):
        if config is None:
            config = TradingNodeConfig()
        PyCondition.not_none(config, "config")
        PyCondition.type(config, TradingNodeConfig, "config")

        # Configuration
        self._config = config

        # 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.loop_debug)

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

        # Identifiers
        self.trader_id = TraderId(config.trader_id)
        self.machine_id = socket.gethostname()
        self.instance_id = self._uuid_factory.generate()

        # Setup logging
        self._logger = LiveLogger(
            loop=self._loop,
            clock=self._clock,
            trader_id=self.trader_id,
            machine_id=self.machine_id,
            instance_id=self.instance_id,
            level_stdout=LogLevelParser.from_str_py(config.log_level.upper()),
        )

        self._log = LoggerAdapter(
            component_name=type(self).__name__,
            logger=self._logger,
        )

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

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

        ########################################################################
        # Build platform
        ########################################################################
        if config.cache_database is None or config.cache_database.type == "in-memory":
            cache_db = None
        elif config.cache_database.type == "redis":
            cache_db = RedisCacheDatabase(
                trader_id=self.trader_id,
                logger=self._logger,
                serializer=MsgPackSerializer(timestamps_as_str=True),
                config=config.cache_database,
            )
        else:  # pragma: no cover (design-time error)
            raise ValueError(
                "The cache_db_type in the configuration is unrecognized, "
                "can one of {{'in-memory', 'redis'}}.",
            )

        self._msgbus = MessageBus(
            trader_id=self.trader_id,
            clock=self._clock,
            logger=self._logger,
        )

        self._cache = Cache(
            database=cache_db,
            logger=self._logger,
            config=config.cache,
        )

        self.portfolio = Portfolio(
            msgbus=self._msgbus,
            cache=self._cache,
            clock=self._clock,
            logger=self._logger,
        )

        self._data_engine = LiveDataEngine(
            loop=self._loop,
            msgbus=self._msgbus,
            cache=self._cache,
            clock=self._clock,
            logger=self._logger,
            config=config.data_engine,
        )

        self._exec_engine = LiveExecutionEngine(
            loop=self._loop,
            msgbus=self._msgbus,
            cache=self._cache,
            clock=self._clock,
            logger=self._logger,
            config=config.exec_engine,
        )
        self._exec_engine.load_cache()

        self._risk_engine = LiveRiskEngine(
            loop=self._loop,
            portfolio=self.portfolio,
            msgbus=self._msgbus,
            cache=self._cache,
            clock=self._clock,
            logger=self._logger,
            config=config.risk_engine,
        )

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

        if config.load_strategy_state:
            self.trader.load()

        # Setup persistence (requires trader)
        self.persistence_writers: List[Any] = []
        if config.persistence:
            self._setup_persistence(config=config.persistence)

        self._builder = TradingNodeBuilder(
            loop=self._loop,
            data_engine=self._data_engine,
            exec_engine=self._exec_engine,
            msgbus=self._msgbus,
            cache=self._cache,
            clock=self._clock,
            logger=self._logger,
            log=self._log,
        )

        self._log.info("INITIALIZED.")
        self.time_to_initialize = self._clock.delta(self.created_time)
        self._log.info(f"Initialized in {int(self.time_to_initialize.total_seconds() * 1000)}ms.")

        self._is_built = False
config_node = TradingNodeConfig(
    trader_id="TESTER-001",
    log_level="INFO",
    data_clients={
        "IB":
        InteractiveBrokersDataClientConfig(
            gateway_host="127.0.0.1",
            instrument_provider=InstrumentProviderConfig(
                load_all=True,
                filters=tuple({
                    "secType": "CASH",
                    "pair": "EURUSD"
                }.items()),
                #     filters=tuple(
                #         {
                #             "secType": "STK",
                #             "symbol": "9988",
                #             "exchange": "SEHK",
                #             "currency": "HKD",
                #             "build_options_chain": True,
                #             "option_kwargs": json.dumps(
                #                 {
                #                     "min_expiry": "20220601",
                #                     "max_expiry": "20220701",
                #                     "min_strike": 90,
                #                     "max_strike": 110,
                #                     "exchange": "SEHK"
                #                 }
                #             ),
                #         }.items()
                #     ),
            ),
            routing=RoutingConfig(venues={"IDEALPRO"}),
        ),
    },
    # exec_clients={
    #     "IB": InteractiveBrokersExecClientConfig(),
    # },
    timeout_connection=90.0,
    timeout_reconciliation=5.0,
    timeout_portfolio=5.0,
    timeout_disconnection=5.0,
    check_residuals_delay=2.0,
)