databento_node_test/
node_test.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Posei Systems Pty Ltd. All rights reserved.
3//  https://poseitrader.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use std::path::PathBuf;
17
18use nautilus_common::enums::Environment;
19use nautilus_core::env::get_env_var;
20use posei_traderbento::{
21    actor::{DatabentoSubscriberActor, DatabentoSubscriberActorConfig},
22    factories::{DatabentoDataClientFactory, DatabentoLiveClientConfig},
23};
24use nautilus_live::node::LiveNode;
25use nautilus_model::identifiers::{ClientId, InstrumentId, TraderId};
26use tokio::time::Duration;
27
28// Run with `cargo run -p nautilus-databento --bin databento-node-test --features live`
29
30#[tokio::main]
31async fn main() -> Result<(), Box<dyn std::error::Error>> {
32    // TODO: Initialize Python interpreter only if python feature is enabled
33    // #[cfg(feature = "python")]
34    pyo3::prepare_freethreaded_python();
35
36    tracing_subscriber::fmt()
37        .with_max_level(tracing::Level::INFO)
38        .init();
39
40    dotenvy::dotenv().ok();
41
42    let environment = Environment::Live;
43    let trader_id = TraderId::default();
44    let node_name = "DATABENTO-TESTER-001".to_string();
45
46    // Get Databento API key from environment
47    let api_key = get_env_var("DATABENTO_API_KEY").unwrap_or_else(|_| {
48        println!("⚠️  DATABENTO_API_KEY not found, using placeholder");
49        "db-placeholder-key".to_string()
50    });
51
52    // Determine publishers file path
53    let publishers_filepath = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("publishers.json");
54    if !publishers_filepath.exists() {
55        println!(
56            "⚠️  Publishers file not found at: {}",
57            publishers_filepath.display()
58        );
59    }
60
61    // Configure Databento client
62    let databento_config = DatabentoLiveClientConfig::new(
63        api_key,
64        publishers_filepath,
65        true, // use_exchange_as_venue
66        true, // bars_timestamp_on_close
67    );
68
69    let client_factory = Box::new(DatabentoDataClientFactory::new());
70
71    // Create and register a Databento subscriber actor
72    let client_id = ClientId::new("DATABENTO");
73    let instrument_ids = vec![
74        InstrumentId::from("ES.c.0.GLBX"),
75        // Add more instruments as needed
76    ];
77
78    // Build the live node with Databento data client
79    let mut node = LiveNode::builder(node_name, trader_id, environment)?
80        .with_load_state(false)
81        .with_save_state(false)
82        .add_data_client(None, client_factory, Box::new(databento_config))?
83        .build()?;
84
85    // TODO: Move this into trader registration
86    let actor_config = DatabentoSubscriberActorConfig::new(instrument_ids, client_id);
87    let cache = node.kernel().cache();
88    let clock = node.kernel().clock();
89    let actor = DatabentoSubscriberActor::new(actor_config, cache, clock);
90    node.add_actor(Box::new(actor))?;
91
92    node.start().await?;
93
94    // Let it run briefly to ensure all components are properly initialized
95    tokio::time::sleep(Duration::from_millis(100)).await;
96
97    node.stop().await?;
98
99    Ok(())
100}
101
102#[cfg(not(feature = "live"))]
103fn main() {
104    println!("⚠️  databento-node-test binary requires the 'live' feature to be enabled.");
105    println!(
106        "   Run with: cargo run -p nautilus-databento --bin databento-node-test --features live"
107    );
108    std::process::exit(1);
109}