-
|
Hi Folks, I am currently working on a very basic and rudimental implementation of Bloomberg Live Data into the TradingNode for live trading. My end goal is to just receive the live data for specific tickers and let my strategies work on new incoming BarType Data for now. 'NoneType' object has no attribute 'value'
Traceback (most recent call last):
File "D:\dev\algo_trading\at_backtest\src\at_backtest\nt_trader.py", line 82, in run_live_bbg
await self._live_node.run_async()
File "D:\dev\algo_trading\at_backtest\.venv\Lib\site-packages\nautilus_trader\live\node.py", line 349, in run_async
await self.kernel.start_async()
File "D:\dev\algo_trading\at_backtest\.venv\Lib\site-packages\nautilus_trader\system\kernel.py", line 1026, in start_async
if not await self._await_execution_reconciliation():
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\dev\algo_trading\at_backtest\.venv\Lib\site-packages\nautilus_trader\system\kernel.py", line 1337, in _await_execution_reconciliation
if not await self._exec_engine.reconcile_execution_state(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\dev\algo_trading\at_backtest\.venv\Lib\site-packages\nautilus_trader\live\execution_engine.py", line 1728, in reconcile_execution_state
result = self._reconcile_execution_mass_status(mass_status)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\dev\algo_trading\at_backtest\.venv\Lib\site-packages\nautilus_trader\live\execution_engine.py", line 1865, in _reconcile_execution_mass_status
self._adjust_mass_status_fills(mass_status)
File "D:\dev\algo_trading\at_backtest\.venv\Lib\site-packages\nautilus_trader\live\execution_engine.py", line 1985, in _adjust_mass_status_fills
adjusted_results = adjust_fills_for_partial_window(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\dev\algo_trading\at_backtest\.venv\Lib\site-packages\nautilus_trader\live\reconciliation.py", line 624, in adjust_fills_for_partial_window
pyo3_mass_status = mass_status.to_pyo3()
^^^^^^^^^^^^^^^^^^^^^
File "D:\dev\algo_trading\at_backtest\.venv\Lib\site-packages\nautilus_trader\execution\reports.py", line 1213, in to_pyo3
account_id=nautilus_pyo3.AccountId(self.account_id.value),
^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'value'Below you find my creation of the node: catalog_config = DataCatalogConfig(
path=self.catalog_path, fs_protocol="file", name="historical_data"
)
node_config = TradingNodeConfig(
trader_id=self._trader_id,
logging=LoggingConfig(log_level=self._logging_lvl),
catalogs=[catalog_config],
data_clients={
"SIM_CASH": BbgLiveDataClientConfig(
account_currency="EUR",
base_currency="EUR",
external_clients=[ClientId("SIM_CASH")],
instrument_provider=BbgInstrumentProviderConfig(
load_all=True,
),
)
},
exec_clients={
"SIM_CASH": SandboxExecutionClientConfig(
venue="SIM_CASH",
base_currency="EUR",
oms_type="NETTING",
account_type="CASH",
starting_balances=["1_000_000 EUR"],
instrument_provider=BbgInstrumentProviderConfig(
load_all=True,
),
)
},
)
node = TradingNode(config=node_config)
strat_combs = []
ticker_map = {}
inst_ids = []
for instrument, wrangler, _ticks in self.portfolio.hist_tpl:
instr_id = instrument.id
bar_type = wrangler.bar_type
# Adding the strategy list
strat_combs += self.strategy_ft.create_configs(
instrument_id=instr_id, bar_type=bar_type
)
# Adding the Ticker List
ticker = instr_id.symbol.value
ticker_map[ticker] = bar_type
inst_ids.append(instr_id)
strategies = self.strategy_ft.create_strategies(strat_combs)
node.trader.add_strategies(strategies)
node.add_data_client_factory("SIM_CASH", factory=BbgLiveDataClientFactory)
node.add_exec_client_factory("SIM_CASH", factory=SandboxLiveExecClientFactory)
_inst = self.catalog.instruments()
ids = []
for i in _inst:
node.cache.add_instrument(i)
ids.append(i.id)
node.build()The following code pulls the data from BBG successfully and keeps spinning if I remove the ExecFactory or change naming conventions: Unfortunately, due to the limitations of bloomberg I cannot share a small examples for you to test the issue.
Please apologize the messy code structure, since I am currently just trying to establish a rudimental version before moving on with improved readability and coding standards. Thank you. PS: Text File of Complete Output. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
I was able to solve the issue by wrapping the SandboxExecutionClient and adding a new self._set_account_id() to the init class SandboxLiveExecClientFactory(SandboxLiveExecClientFactory):
@staticmethod
def create(
loop: asyncio.AbstractEventLoop,
name: str,
config: SandboxExecutionClientConfig,
portfolio: PortfolioFacade,
msgbus: MessageBus,
cache: Cache,
clock: LiveClock,
) -> SandboxExecutionClient:
exec_client = BbgLiveExecutionClient(
loop=loop,
clock=clock,
portfolio=portfolio,
msgbus=msgbus,
cache=cache,
config=config,
)
return exec_client
class BbgLiveExecutionClient(SandboxExecutionClient):
def __init__(
self,
loop: asyncio.AbstractEventLoop,
portfolio: PortfolioFacade,
msgbus: MessageBus,
cache: Cache,
clock: LiveClock,
config: SandboxExecutionClientConfig,
) -> None:
super().__init__(
loop,
portfolio,
msgbus,
cache,
clock,
config,
)
# Adding to avoid error during creation
self._set_account_id(AccountId(f"{config.venue}-001"))This is not the go to solution, but maybe it helps somebody in the future tackling Bloomberg. |
Beta Was this translation helpful? Give feedback.
I was able to solve the issue by wrapping the SandboxExecutionClient and adding a new self._set_account_id() to the init