Exemplo n.º 1
0
    def setUp(self):
        # Fixture Setup
        # Fresh isolated loop testing pattern
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        config = {
            "trader": {
                "name": "tester",
                "id_tag": "000",
            },
            "logging": {
                "log_level_console": "INF",
                "log_level_file": "DBG",
                "log_level_store": "WRN",
            },
            "exec_database": {
                "type": "in-memory",
            },
            "strategy": {
                "load_state": True,
                "save_state": True,
            },
            "data_clients": {},
            "exec_clients": {},
        }

        self.node = TradingNode(
            strategies=[TradingStrategy("000")],
            config=config,
        )
Exemplo n.º 2
0
    def test_get_event_loop_returns_a_loop(self):
        # Arrange
        node = TradingNode()

        # Act
        loop = node.get_event_loop()

        # Assert
        assert isinstance(loop, asyncio.AbstractEventLoop)
Exemplo n.º 3
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
Exemplo n.º 4
0
    def test_config_with_redis_execution_database(self):
        # Arrange
        config = {
            "trader": {
                "name": "tester",
                "id_tag": "000",
            },
            "logging": {
                "log_level_console": "INF",
                "log_level_file": "DBG",
                "log_level_store": "WRN",
                "run_in_process":
                False  # Avoid pytest hanging on multiprocessing resources
            },
            "exec_database": {
                "type": "redis",
                "host": "localhost",
                "port": 6379,
            },
            "strategy": {
                "load_state": True,
                "save_state": True,
            },
            "data_clients": {
                "oanda": {
                    "api_token":
                    "OANDA_API_TOKEN",  # value is the environment variable name
                    "account_id":
                    "OANDA_ACCOUNT_ID",  # value is the environment variable name
                },
            },
            "exec_clients": {
                "oanda": {
                    "api_token":
                    "OANDA_API_TOKEN",  # value is the environment variable name
                    "account_id":
                    "OANDA_ACCOUNT_ID",  # value is the environment variable name
                },
            }
        }

        # Act
        node = TradingNode(
            strategies=[TradingStrategy("000")],
            config=config,
        )

        # Assert
        self.assertIsNotNone(node)
Exemplo n.º 5
0
    def test_config_with_inmemory_execution_database(self):
        # Arrange
        config = {
            "trader": {
                "name": "tester",
                "id_tag": "000",
            },
            "logging": {
                "log_level_console": "INF",
                "log_level_file": "DBG",
                "log_level_store": "WRN",
                "run_in_process":
                False  # Avoid pytest hanging on multiprocessing resources
            },
            "exec_database": {
                "type": "in-memory",
            },
            "strategy": {
                "load_state": True,
                "save_state": True,
            },
            "data_clients": {
                "binance": {
                    "api_key":
                    "BINANCE_API_KEY",  # value is the environment variable name
                    "api_secret":
                    "BINANCE_API_SECRET",  # value is the environment variable name
                },
            },
            "exec_clients": {
                "binance": {
                    "api_key":
                    "BINANCE_API_KEY",  # value is the environment variable name
                    "api_secret":
                    "BINANCE_API_SECRET",  # value is the environment variable name
                },
            }
        }

        # Act
        node = TradingNode(
            strategies=[TradingStrategy("000")],
            config=config,
        )

        # Assert
        self.assertIsNotNone(node)
                "market_id": market_id
            },
        },
    },
}

# Instantiate your strategies to pass into the trading node. You could add
# custom options into the configuration file or even use another configuration
# file.

strategy = BetfairTestStrategy(
    instrument_filter={"market_id": market_id},
    trade_size=Decimal(10.0),
    order_id_tag="001",
)

# Instantiate the node passing a list of strategies and configuration
node = TradingNode(strategies=[strategy], config=config)

# 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", BetfairLiveExecutionClientFactory)
node.build()

# Stop and dispose of the node with SIGINT/CTRL+C
if __name__ == "__main__":
    try:
        node.start()
    finally:
        node.dispose()
Exemplo n.º 7
0
class TradingNodeOperationTests(unittest.TestCase):
    def setUp(self):
        # Fixture Setup
        # Fresh isolated loop testing pattern
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

        config = {
            "trader": {
                "name": "tester",
                "id_tag": "000",
            },
            "logging": {
                "log_level_console": "INF",
                "log_level_file": "DBG",
                "log_level_store": "WRN",
            },
            "exec_database": {
                "type": "in-memory",
            },
            "strategy": {
                "load_state": True,
                "save_state": True,
            },
            "data_clients": {},
            "exec_clients": {},
        }

        self.node = TradingNode(
            strategies=[TradingStrategy("000")],
            config=config,
        )

    def test_get_event_loop_returns_a_loop(self):
        # Arrange
        # Act
        loop = self.node.get_event_loop()

        # Assert
        self.assertTrue(isinstance(loop, asyncio.AbstractEventLoop))

    def test_start(self):
        # Arrange
        run = threading.Thread(target=self.node.start, daemon=True)
        run.start()

        time.sleep(0.3)

        # Act
        # Assert
        self.assertEqual(ComponentState.RUNNING, self.node.trader.state)
        self.node.stop()

    def test_stop(self):
        # Arrange
        run = threading.Thread(target=self.node.start, daemon=True)
        run.start()

        # Allow node to start
        time.sleep(0.3)
        self.loop.call_soon_threadsafe(self.node.stop)

        # Allow node to stop
        time.sleep(3)

        # Act
        # Assert
        self.assertEqual(ComponentState.STOPPED, self.node.trader.state)

    def test_dispose(self):
        # Arrange
        run = threading.Thread(target=self.node.start, daemon=True)
        run.start()

        # Allow node to start
        time.sleep(0.3)
        self.loop.call_soon_threadsafe(self.node.stop)

        # Allow node to stop
        time.sleep(3)

        self.node.dispose()

        # Act
        # Assert
        self.assertEqual(ComponentState.DISPOSED, self.node.trader.state)
Exemplo n.º 8
0
            # "api_secret": "YOUR_FTX_API_SECRET",
            # "account_id": "YOUR_FTX_ACCOUNT_ID", (optional)
            "sandbox_mode": False,  # If client uses the testnet
        },
    },
    exec_clients={
        "FTX": {
            # "api_key": "YOUR_FTX_API_KEY",
            # "api_secret": "YOUR_FTX_API_SECRET",
            # "account_id": "YOUR_FTX_ACCOUNT_ID", (optional)
            "sandbox_mode": False,  # If client uses the testnet,
        },
    },
)
# Instantiate the node with a configuration
node = TradingNode(config=config_node)

# Configure your strategy
strat_config = EMACrossConfig(
    instrument_id="ETH/USD.FTX",
    bar_type="ETH/USD.FTX-1-MINUTE-LAST-INTERNAL",
    fast_ema_period=10,
    slow_ema_period=20,
    trade_size=Decimal("0.01"),
    order_id_tag="001",
)
# Instantiate your strategy
strategy = EMACross(config=strat_config)

# Add your strategies and modules
node.trader.add_strategy(strategy)
            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,
)
# Instantiate the node with a configuration
node = TradingNode(config=config_node)

# Configure your strategy
strat_config = EMACrossConfig(
    instrument_id="ETHUSDT.BINANCE",
    bar_type="ETHUSDT.BINANCE-1-MINUTE-LAST-EXTERNAL",
    fast_ema_period=10,
    slow_ema_period=20,
    trade_size=Decimal("0.005"),
    order_id_tag="001",
)
# Instantiate your strategy
strategy = EMACross(config=strat_config)

# Add your strategies and modules
node.trader.add_strategy(strategy)
Exemplo n.º 10
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()
)

strategy3 = EMACross(
    instrument_id=instrument3,
    bar_spec=BarSpecification(1, BarAggregation.MINUTE, PriceType.MID),
    fast_ema_period=10,
    slow_ema_period=20,
    trade_size=Decimal(10000),
    order_id_tag="003",
)

strategies = [
    strategy1,
    strategy2,
    strategy3,
]

# Instantiate the node passing a list of strategies and configuration
node = TradingNode(strategies=strategies, config=config)

# Register your client factories with the node (can take user defined factories)
node.add_data_client_factory("OANDA", OandaDataClientFactory)
node.build()

# Stop and dispose of the node with SIGINT/CTRL+C
if __name__ == "__main__":
    try:
        node.start()
    finally:
        node.dispose()
Exemplo n.º 12
0
 def setup(self):
     # Fixture Setup
     self.node = TradingNode()
Exemplo n.º 13
0
class TestTradingNodeOperation:
    def setup(self):
        # Fixture Setup
        self.node = TradingNode()

    def test_get_event_loop_returns_a_loop(self):
        # Arrange
        node = TradingNode()

        # Act
        loop = node.get_event_loop()

        # Assert
        assert isinstance(loop, asyncio.AbstractEventLoop)

    def test_build_called_twice_raises_runtime_error(self):
        # Arrange, # Act
        with pytest.raises(RuntimeError):
            self.node.build()
            self.node.build()

    def test_start_when_not_built_raises_runtime_error(self):
        # Arrange, # Act
        with pytest.raises(RuntimeError):
            self.node.start()

    def test_add_data_client_factory(self):
        # Arrange, # Act
        self.node.add_data_client_factory("BETFAIR",
                                          BetfairLiveDataClientFactory)
        self.node.build()

        # TODO(cs): Assert existence of client

    def test_add_exec_client_factory(self):
        # Arrange, # Act
        self.node.add_exec_client_factory("BETFAIR",
                                          BetfairLiveExecutionClientFactory)
        self.node.build()

        # TODO(cs): Assert existence of client

    def test_build_with_multiple_clients(self):
        # Arrange, # Act
        self.node.add_data_client_factory("BETFAIR",
                                          BetfairLiveDataClientFactory)
        self.node.add_exec_client_factory("BETFAIR",
                                          BetfairLiveExecutionClientFactory)
        self.node.build()

        # TODO(cs): Assert existence of client

    @pytest.mark.asyncio
    async def test_register_log_sink(self):
        # Arrange
        sink = []

        # Act
        self.node.add_log_sink(sink.append)
        self.node.build()

        self.node.start()
        await asyncio.sleep(1)

        # Assert: Log record received
        assert sink[-1]["trader_id"] == self.node.trader_id.value
        assert sink[-1]["machine_id"] == self.node.machine_id
        assert sink[-1]["instance_id"] == self.node.instance_id.value

    @pytest.mark.asyncio
    async def test_start(self):
        # Arrange
        self.node.build()

        # Act
        self.node.start()
        await asyncio.sleep(2)

        # Assert
        assert self.node.trader.is_running

    @pytest.mark.asyncio
    async def test_stop(self):
        # Arrange
        self.node.build()
        self.node.start()
        await asyncio.sleep(2)  # Allow node to start

        # Act
        self.node.stop()
        await asyncio.sleep(3)  # Allow node to stop

        # Assert
        assert self.node.trader.is_stopped

    @pytest.mark.skip(reason="refactor TradingNode coroutines")
    @pytest.mark.asyncio
    async def test_dispose(self):
        # Arrange
        self.node.build()
        self.node.start()
        await asyncio.sleep(2)  # Allow node to start

        self.node.stop()
        await asyncio.sleep(2)  # Allow node to stop

        # Act
        self.node.dispose()
        await asyncio.sleep(1)  # Allow node to dispose

        # Assert
        assert self.node.trader.is_disposed
Exemplo n.º 14
0
    def test_config_with_redis_execution_database(self):
        # Arrange, Act
        node = TradingNode()

        # Assert
        assert node is not None
Exemplo n.º 15
0
instrument_id = InstrumentId(
    symbol=Symbol("BTC/USD"),
    venue=Venue("BITMEX"),
)

strategy = VolatilityMarketMaker(
    instrument_id=instrument_id,
    bar_spec=BarSpecification(1, BarAggregation.MINUTE, PriceType.LAST),
    trade_size=Decimal("10"),
    atr_period=20,
    atr_multiple=1.5,
    order_id_tag="091",
)

# Instantiate the node passing a list of strategies and configuration
node = TradingNode(strategies=[strategy], config=config)

# Register your client factories with the node (can take user defined factories)
node.add_data_client_factory("CCXT", CCXTDataClientFactory)
node.add_exec_client_factory("CCXT", CCXTExecutionClientFactory)
node.build()


# Stop and dispose of the node with SIGINT/CTRL+C
if __name__ == "__main__":
    try:
        node.start()
    finally:
        node.dispose()
Exemplo n.º 16
0
)

strategy2 = EMACross(
    symbol=Symbol("EUR/USD", Venue("OANDA")),
    bar_spec=BarSpecification(1, BarAggregation.MINUTE, PriceType.MID),
    fast_ema=10,
    slow_ema=20,
    trade_size=Decimal(10000),
)

strategy3 = EMACross(
    symbol=Symbol("GBP/USD", Venue("OANDA")),
    bar_spec=BarSpecification(1, BarAggregation.MINUTE, PriceType.MID),
    fast_ema=10,
    slow_ema=20,
    trade_size=Decimal(10000),
)

# Instantiate the node passing a list of strategies and configuration
node = TradingNode(
    strategies=[strategy1, strategy2, strategy3],
    config=config,
)

# Stop and dispose of the node with SIGINT/CTRL+C
if __name__ == "__main__":
    try:
        node.start()
    finally:
        node.dispose()
Exemplo n.º 17
0
# ]

# strategies_cfd = []
# for symbol in symbols_cfd:
#     strategies_fx.append(EMACrossPy(
#         symbol,
#         BAR_SPEC_CFD,
#         risk_bp=10.0,
#         fast_ema=10,
#         slow_ema=20,
#         atr_period=20))

strategies = strategies_fx  # + strategies_cfd

if __name__ == "__main__":

    node = TradingNode(config_path='config.json', strategies=strategies)

    node.connect()
    time.sleep(1)
    node.start()

    input()
    node.stop()

    input()
    node.disconnect()

    input()
    node.dispose()
Exemplo n.º 18
0
            "api_key":
            "BINANCE_API_KEY",  # value is the environment variable key
            "api_secret":
            "BINANCE_API_SECRET",  # value is the environment variable key
            "sandbox_mode": False,  # If clients use the testnet
        },
    },
}

# Instantiate your strategies to pass into the trading node. You could add
# custom options into the configuration file or even use another configuration
# file.
strategy = EMACross(
    symbol=Symbol("ETH/USDT", Venue("BINANCE")),
    bar_spec=BarSpecification(1, BarAggregation.MINUTE, PriceType.LAST),
    fast_ema_period=10,
    slow_ema_period=20,
    trade_size=Decimal("0.05"),
    order_id_tag="001",
)

# Instantiate the node passing a list of strategies and configuration
node = TradingNode(strategies=[strategy], config=config)

# Stop and dispose of the node with SIGINT/CTRL+C
if __name__ == "__main__":
    try:
        node.start()
    finally:
        node.dispose()
            ),
            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,
)

# Instantiate the node with a configuration
node = TradingNode(config=config_node)

# Configure your strategy
strategy_config = SubscribeStrategyConfig(
    instrument_id="EUR/USD.IDEALPRO",
    book_type=BookType.L2_MBP,
    snapshots=True,
    # trade_ticks=True,
    # quote_ticks=True,
)
# Instantiate your strategy
strategy = SubscribeStrategy(config=strategy_config)

# Add your strategies and modules
node.trader.add_strategy(strategy)