RunModeHelper - Enriched API Documentation
Executive Summaryβ
RunModeHelper is a static utility class in the Bookmap Layer1 API that provides global access to the application's operational mode. It distinguishes between live vs. replayed data and real vs. simulated trading, enabling strategies to adapt their behavior based on the runtime environment. The class is initialized once by the Bookmap framework during startup and remains immutable throughout the session.
Table of Contentsβ
- Class Overview
- Lifecycle and Initialization
- Method Reference
- Operating Modes
- Relationship with Other Classes
- Usage Patterns
- Edge Cases and Gotchas
- Complete Examples
- Utility Wrapper
- Document Metadata
Class Overviewβ
Package and Inheritanceβ
package velox.api.layer1.common;
public class RunModeHelper extends java.lang.Object
Purpose: Centralized accessor for Bookmap's runtime execution mode configuration.
Official Descriptionβ
This class can be used to retrieve Bookmap Run Mode
Enhanced Descriptionβ
RunModeHelper serves as a global configuration gate that controls how strategies, data providers, and trading logic behave. It maintains two critical boolean flags:
isLive()- Determines the data source: live from provider vs. replayed by BookmapisRealTrading()- Determines order handling: real execution via provider vs. simulated by Bookmap
These flags propagate throughout the Layer1 API ecosystem, affecting:
- Provider selection (
ExternalLiveBaseProvidervsExternalReaderBaseProvider) - Data event generation (
Layer1ApiDataListenercallbacks) - Trading event semantics (
Layer1ApiTradingListenercallbacks) - Execution simulation status (
ExecutionInfo.isSimulated,OrderInfo.isSimulated)
Key Characteristics:
- All methods are static (no instance required)
- Initialized once during Bookmap startup
- Immutable after initialization
- Thread-safe for read operations after initialization (inferred from static read-only pattern)
Lifecycle and Initializationβ
Initialization Sequenceβ
Γ’βΕΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΒ
Γ’ββ 1. User selects mode in Bookmap UI Γ’ββ
Γ’ββ - Live/Replay Γ’ββ
Γ’ββ - Real Trading/Simulated Γ’ββ
Γ’ββΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΛ
Γ’ββ
Γ’βΒΌ
Γ’βΕΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΒ
Γ’ββ 2. Bookmap Framework reads configuration Γ’ββ
Γ’ββΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΛ
Γ’ββ
Γ’βΒΌ
Γ’βΕΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΒ
Γ’ββ 3. setRunModeOnce(isLive, isRealTrading) called Γ’ββ
Γ’ββ [FRAMEWORK ONLY - NOT USER CODE] Γ’ββ
Γ’ββΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬ Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΛ
Γ’ββ
Γ’βΒΌ
Γ’βΕΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΒ
Γ’ββ 4. isSet() returns true Γ’ββ
Γ’ββΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΛ
Γ’ββ
Γ’βΒΌ
Γ’βΕΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΒ
Γ’ββ 5. Provider initialization Γ’ββ
Γ’ββ - ExternalLiveBaseProvider (if isLive=true) Γ’ββ
Γ’ββ - ExternalReaderBaseProvider (if isLive=false) Γ’ββ
Γ’ββΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΛ
Γ’ββ
Γ’βΒΌ
Γ’βΕΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΒ
Γ’ββ 6. Strategy code queries isLive() / isRealTrading() Γ’ββ
Γ’ββΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΛ
Γ’ββ
Γ’βΒΌ
Γ’βΕΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΒ
Γ’ββ 7. Strategy adapts behavior based on mode Γ’ββ
Γ’ββΓ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’βΛ
Note: This lifecycle sequence is inferred from the API design patterns and the "Once" naming convention. The exact internal implementation details are not publicly documented.
When is RunModeHelper Ready?β
Safe to use: After isSet() returns true
Typical initialization point for strategies:
- In
Layer1ApiAdminListener.onLoginSuccessful()callback - In strategy constructor (if called after framework initialization)
- In
Layer1ApiListener.onUserMessage()handlers
NOT safe: During static initialization or very early constructor code
API Version Note: The
Layer1ApiAdminListenerinterface definesonLoginSuccessful()with no parameters. Some adapter implementations may provide overloaded versions with additional parameters. Always refer to the specific interface you're implementing.
Method Referenceβ
setRunModeOnce()β
public static void setRunModeOnce(boolean isLive, boolean isRealTrading)
Called by: Bookmap framework (internal use only)
Description: Called by Bookmap code once to set Run Mode.
Parameters:
isLive-trueif data comes from provider (may still be delayed),falseif replayed by BookmapisRealTrading-trueif trading orders go to provider,falseif simulated by Bookmap
Behavior:
- Called exactly once during Bookmap startup
- Method name "Once" implies idempotent or error on duplicate calls
- User code should never call this method
Confidence: HIGH (explicitly documented as framework-only)
isSet()β
public static boolean isSet()
Returns: Primitive boolean (never null)
trueif run mode has been initializedfalseif not yet initialized
Description: Gate check to determine if isLive() and isRealTrading() are safe to call.
Official Documentation:
Returns true if the Run Mode is selected
Usage:
if (RunModeHelper.isSet()) {
// Safe to query mode
Boolean isLive = RunModeHelper.isLive();
Boolean isRealTrading = RunModeHelper.isRealTrading();
} else {
// Use default behavior or defer initialization
}
Thread Safety: Safe to call from any thread at any time.
Confidence: HIGH (documented behavior, primitive return)
isLive()β
public static Boolean isLive()
Returns: Object Boolean (can be null)
true- Bookmap receives data from the providerfalse- Bookmap replays data locallynull- Not yet initialized (beforesetRunModeOnce())
Description: Indicates the data source for market events.
Important Notes:
- "Live" does NOT mean "real-time": Provider can supply delayed or replayed data even when
isLive() == true - "Live" means "from provider": The data originates from the external data source rather than Bookmap's replay engine
- Null handling required: Always check for null or use
isSet()guard
Official Documentation:
This flag indicates that Bookmap gets the data from the provider, it still can be delayed or replayed by the provider. Otherwise, the data is replayed by Bookmap.
Returns: true if the data live (by provider)
Usage:
Boolean isLive = RunModeHelper.isLive();
if (isLive != null && isLive) {
// Provider-sourced data (live connection)
} else if (isLive != null) {
// Bookmap-replayed data (historical playback)
} else {
// Not initialized yet
}
Confidence: HIGH (directly documented)
isRealTrading()β
public static Boolean isRealTrading()
Returns: Object Boolean (can be null)
true- Trading orders are sent to the providerfalse- Trading is simulated by Bookmapnull- Not yet initialized (beforesetRunModeOnce())
Description: Indicates whether trading operations have real-world consequences.
Important Notes:
- "Real" does NOT mean "executed": Provider can still simulate orders even when
isRealTrading() == true - "Real" means "sent to provider": Orders are transmitted to the external broker/exchange rather than handled locally
- Affects simulation flags: When
false,ExecutionInfo.isSimulatedandOrderInfo.isSimulatedwill betrue - Null handling required: Always check for null or use
isSet()guard
Official Documentation:
This flag indicates that all the trading events will be passed to provider, it still can be simulated on provider side. Otherwise, the trading is simulated by Bookmap.
Returns: true if the trading is real (by provider)
Usage:
Boolean isRealTrading = RunModeHelper.isRealTrading();
if (isRealTrading != null && isRealTrading) {
// Real trading mode (orders go to provider)
// CAUTION: Real money at risk!
} else if (isRealTrading != null) {
// Simulated trading (Bookmap simulation)
} else {
// Not initialized yet
}
Confidence: HIGH (directly documented)
Operating Modesβ
Four-Mode Matrixβ
The two boolean flags create a 2Γβ2 state space with four distinct operating modes:
| Mode | isLive | isRealTrading | Use Case | Risk Level |
|---|---|---|---|---|
| LIVE_REAL | true | true | Production trading with live market data | Γ°ΕΈβΒ΄ CRITICAL |
| LIVE_SIMULATED | true | false | Paper trading with live market data | Γ°ΕΈΕΈΒ‘ LOW |
| REPLAY_SIMULATED | false | false | Backtesting with historical data | Γ°ΕΈΕΈΒ’ NONE |
| REPLAY_REAL | false | true | Theoretically possible but dangerous | Γ’Ε‘Β Γ―ΒΈΒ AVOID |
Mode Descriptionsβ
1. LIVE_REAL (Production)β
isLive() == true && isRealTrading() == true
Characteristics:
- Real-time market data from broker/exchange
- Real trading orders sent to broker
- Actual money at risk
- Highest latency sensitivity
Typical Configuration:
- ExternalLiveBaseProvider active
- Real account credentials
- Production API endpoints
Strategy Behavior:
- Enable risk limits
- Reduce logging verbosity
- Monitor connection health
- Implement circuit breakers
2. LIVE_SIMULATED (Paper Trading)β
isLive() == true && isRealTrading() == false
Characteristics:
- Real-time market data from broker/exchange
- Simulated order fills by Bookmap
- No real money at risk
- Safe for testing strategies
Typical Configuration:
- ExternalLiveBaseProvider active
- Simulation mode enabled in UI
- May use demo account credentials
Strategy Behavior:
- Test execution logic
- Validate signal generation
- Verify risk controls
- Log detailed diagnostics
3. REPLAY_SIMULATED (Backtesting)β
isLive() == false && isRealTrading() == false
Characteristics:
- Historical data replayed by Bookmap
- Simulated order fills
- Controllable playback speed
- Safe for optimization and analysis
Typical Configuration:
- ExternalReaderBaseProvider active
- Historical data files loaded
- Replay controls active
Strategy Behavior:
- Collect performance metrics
- Test parameter combinations
- Analyze historical patterns
- Generate research insights
4. REPLAY_REAL (Unusual/Dangerous)β
isLive() == false && isRealTrading() == true
Characteristics:
- Historical data replayed by Bookmap
- Orders would be sent to real broker
- Γ’Ε‘Β Γ―ΒΈΒ DANGEROUS: Real trades based on old data
Likely Behavior:
- Probably blocked by Bookmap framework
- Or provider rejects orders due to stale timestamps
- Should be avoided in all circumstances
Why This Mode Exists:
- Theoretical combination of flags
- May be used for specialized testing scenarios
- Not recommended for production use
Detecting Current Modeβ
public static String getCurrentMode() {
if (!RunModeHelper.isSet()) {
return "NOT_INITIALIZED";
}
boolean live = Boolean.TRUE.equals(RunModeHelper.isLive());
boolean real = Boolean.TRUE.equals(RunModeHelper.isRealTrading());
if (live && real) return "LIVE_REAL";
if (live && !real) return "LIVE_SIMULATED";
if (!live && real) return "REPLAY_REAL";
return "REPLAY_SIMULATED";
}
Relationship with Other Classesβ
Direct Dependenciesβ
RunModeHelper
Γ’ββ
Γ’βΕΓ’ββ¬Γ’ββ¬ Sets state for Γ’ββ¬Γ’ββ¬Γ’βΒΆ ExecutionInfo.isSimulated
Γ’ββ - true when isRealTrading() == false
Γ’ββ - Field: public final boolean isSimulated
Γ’ββ - Doc: "True if execution is simulated by Bookmap"
Γ’ββ
Γ’βΕΓ’ββ¬Γ’ββ¬ Sets state for Γ’ββ¬Γ’ββ¬Γ’βΒΆ OrderInfo.isSimulated
Γ’ββ - true when isRealTrading() == false
Γ’ββ - Field: public final boolean isSimulated
Γ’ββ
Γ’ββΓ’ββ¬Γ’ββ¬ Mirrors concept Γ’ββ¬Γ’ββ¬Γ’βΒΆ Layer1ApiIsRealTradingMessage
- Field: public final boolean isRealTrading
- Doc: "Indicates that trading is real or simulated
on provider side"
- Note: "Is used for statistics only"
Provider Selectionβ
isLive() == true Γ’ββ¬Γ’ββ¬Γ’βΒΆ ExternalLiveBaseProvider instantiated
Γ’ββ
Γ’ββΓ’ββ¬Γ’βΒΆ Connects to broker/exchange
Streams real-time data
isLive() == false Γ’ββ¬Γ’ββ¬Γ’βΒΆ ExternalReaderBaseProvider instantiated
Γ’ββ
Γ’ββΓ’ββ¬Γ’βΒΆ Reads historical data files
Controls replay speed
Evidence: Both
ExternalLiveBaseProviderandExternalReaderBaseProviderare listed as implementing classes forLayer1ApiProvider,Layer1ApiAdminProvider,Layer1ApiDataProvider, andLayer1ApiTradingProviderinterfaces in the knowledge base.
Listener Behaviorβ
Layer1ApiDataListener
Γ’ββ
Γ’βΕΓ’ββ¬Γ’βΒΆ onDepth() Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’βΒΆ If isLive()==true: Real-time depth updates
Γ’ββ Γ’ββΓ’ββ¬Γ’βΒΆ If isLive()==false: Replayed depth from file
Γ’ββ
Γ’ββΓ’ββ¬Γ’βΒΆ onTrade() Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’βΒΆ If isLive()==true: Real-time trades
Γ’ββΓ’ββ¬Γ’βΒΆ If isLive()==false: Replayed trades
Layer1ApiTradingListener
Γ’ββ
Γ’βΕΓ’ββ¬Γ’β ΒΆ onOrderExecuted() Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’βΒΆ If isRealTrading()==true: Real execution from provider
Γ’ββ Γ’ββΓ’ββ¬Γ’βΒΆ If isRealTrading()==false: Simulated by Bookmap
Γ’ββ (ExecutionInfo.isSimulated == true)
Γ’ββ
Γ’ββΓ’ββ¬Γ’βΒΆ onOrderUpdated() Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’ββ¬Γ’β¬Òββ¬Γ’βΒΆ OrderInfo.isSimulated set based on isRealTrading()
Usage Patternsβ
Pattern 1: Safe Null-Check Guardβ
// ALWAYS check isSet() before querying mode
if (RunModeHelper.isSet()) {
Boolean isLive = RunModeHelper.isLive();
Boolean isRealTrading = RunModeHelper.isRealTrading();
// Now safe to use (but still check for null if paranoid)
if (Boolean.TRUE.equals(isLive)) {
// Live mode logic
}
}
Why: Prevents NullPointerException from auto-unboxing null Boolean to boolean.
Pattern 2: Default Valuesβ
// Provide sensible defaults when mode is unknown
boolean isLive = (RunModeHelper.isSet() && Boolean.TRUE.equals(RunModeHelper.isLive()));
boolean isRealTrading = (RunModeHelper.isSet() && Boolean.TRUE.equals(RunModeHelper.isRealTrading()));
// Now you have primitive booleans with false as default
Why: Simplifies logic when null represents "unknown" or "not initialized".
Pattern 3: Mode-Specific Initializationβ
@Override
public void onLoginSuccessful() {
// Initialize based on run mode
if (!RunModeHelper.isSet()) {
Log.warn("RunModeHelper not initialized at login");
return;
}
Boolean isLive = RunModeHelper.isLive();
Boolean isRealTrading = RunModeHelper.isRealTrading();
if (Boolean.TRUE.equals(isLive)) {
// Set up live data handlers
this.dataBuffer = new RealTimeBuffer(1000);
} else {
// Set up replay data handlers
this.dataBuffer = new HistoricalBuffer(100000);
}
if (Boolean.TRUE.equals(isRealTrading)) {
// Enable risk controls
this.maxPositionSize = 100;
this.enableCircuitBreaker = true;
} else {
// Relaxed limits for simulation
this.maxPositionSize = 10000;
this.enableCircuitBreaker = false;
}
}
Note: The
Layer1ApiAdminListener.onLoginSuccessful()method takes no parameters per the official interface. This example uses the correct signature.
Pattern 4: Conditional Loggingβ
// Reduce log verbosity in production
private void logTrade(TradeInfo trade) {
boolean isProduction = RunModeHelper.isSet()
&& Boolean.TRUE.equals(RunModeHelper.isLive())
&& Boolean.TRUE.equals(RunModeHelper.isRealTrading());
if (isProduction) {
// Minimal logging
Log.info("Trade: " + trade.isBidAggressor);
} else {
// Detailed logging for debugging
Log.debug("Trade details: " + trade);
Log.debug(" isBidAggressor: " + trade.isBidAggressor);
Log.debug(" isOtc: " + trade.isOtc);
}
}
Pattern 5: Risk Management Based on Modeβ
private int calculateMaxPositionSize() {
if (!RunModeHelper.isSet()) {
return 100; // Most conservative default
}
Boolean isLive = RunModeHelper.isLive();
Boolean isRealTrading = RunModeHelper.isRealTrading();
// Production: strict limits
if (Boolean.TRUE.equals(isLive) && Boolean.TRUE.equals(isRealTrading)) {
return 100;
}
// Paper trading: moderate limits
else if (Boolean.TRUE.equals(isLive)) {
return 1000;
}
// Backtesting: generous limits
else {
return 10000;
}
}
Pattern 6: Execution Verificationβ
@Override
public void onOrderExecuted(ExecutionInfo execution) {
// Verify execution matches expected mode
Boolean isRealTrading = RunModeHelper.isRealTrading();
if (isRealTrading != null && !isRealTrading) {
// We're in simulated mode, execution should be simulated
if (!execution.isSimulated) {
Log.error("INCONSISTENCY: Real execution in simulated mode!");
}
} else if (Boolean.TRUE.equals(isRealTrading)) {
// We're in real mode, execution should NOT be simulated
if (execution.isSimulated) {
Log.warn("Simulated execution in real trading mode");
}
}
// Process execution...
Log.info("Execution: " + execution.size + " @ " + execution.price);
}
Edge Cases and Gotchasβ
1. NullPointerException on Auto-Unboxingβ
Problem:
// DANGER: NPE if isLive() returns null
if (RunModeHelper.isLive()) { // Auto-unboxes null -> NPE!
// ...
}
Solution:
// SAFE: Explicit null check
Boolean isLive = RunModeHelper.isLive();
if (isLive != null && isLive) {
// ...
}
// BETTER: Guard with isSet()
if (RunModeHelper.isSet() && RunModeHelper.isLive()) {
// isLive() is guaranteed non-null after isSet()==true
}
2. Assuming Immediate Availabilityβ
Problem:
public MyStrategy() {
// Called during construction - RunModeHelper may not be initialized
if (RunModeHelper.isLive()) { // May return null!
// ...
}
}
Solution:
public MyStrategy() {
// Defer mode-dependent initialization
}
@Override
public void onLoginSuccessful() {
// NOW RunModeHelper is guaranteed to be initialized
if (RunModeHelper.isSet()) {
initializeBasedOnMode();
}
}
3. Confusing "Live" with "Real-Time"β
Problem:
if (RunModeHelper.isLive()) {
// Assumption: Data is instantaneous and up-to-date
// WRONG: Provider may have delays or be replaying
}
Reality:
- Live = Data comes from provider (may have network latency, exchange delays, etc.)
- Replay = Data comes from Bookmap's historical files
Solution:
- Always check data timestamps
- Implement staleness detection
- Don't assume zero latency
4. Confusing "Real Trading" with "Executed"β
Problem:
if (RunModeHelper.isRealTrading()) {
// Assumption: Orders will definitely execute
// WRONG: Provider may reject, simulate, or delay orders
}
Reality:
- Real Trading = Orders are sent to the provider
- Provider may still:
- Simulate the orders on their side
- Reject orders due to insufficient funds
- Apply additional risk controls
Solution:
- Check
ExecutionInfo.isSimulatedto verify actual execution type - Implement order confirmation logic
- Don't assume orders automatically execute
5. Attempting to Change Mode from Strategyβ
Problem:
// User wants to test different modes without restarting
RunModeHelper.setRunModeOnce(false, false); // DON'T DO THIS!
Why It's Wrong:
setRunModeOnce()is framework-only- May be ignored, throw exception, or corrupt state
- Mode is immutable after initialization
Solution:
- Change mode via Bookmap UI
- Restart Bookmap to apply new mode
- Use separate test configurations
6. Thread Safety During Initializationβ
Problem:
// Multiple threads query mode while setRunModeOnce() is executing
new Thread(() -> {
Boolean isLive = RunModeHelper.isLive(); // May be null or partially set
}).start();
Solution:
// Wait for initialization to complete
new Thread(() -> {
while (!RunModeHelper.isSet()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
// Now safe to query
Boolean isLive = RunModeHelper.isLive();
}).start();
7. Using Mode for Feature Flagsβ
Problem:
// Treating run mode as generic configuration
if (RunModeHelper.isLive()) {
enableAdvancedCharts(); // Unrelated to data source
}
Why It's Wrong:
- RunMode is specifically for execution behavior (data source, trading simulation)
- Not a general-purpose configuration system
Solution:
- Use separate configuration for features
- Reserve RunMode checks for execution-critical logic
- Use proper feature flags or settings files
8. Ignoring Null Returnsβ
Problem:
// Treating null as false
boolean isLive = RunModeHelper.isLive(); // Auto-unbox: null -> NPE!
// Or:
if (RunModeHelper.isLive() == false) { // NPE if null!
// ...
}
Solution:
// Explicit null handling
Boolean isLiveObj = RunModeHelper.isLive();
boolean isLive = (isLiveObj != null && isLiveObj);
// Or use isSet() guard
if (RunModeHelper.isSet()) {
boolean isLive = RunModeHelper.isLive(); // Safe after isSet() check
}
Complete Examplesβ
Example 1: Basic Strategy Initializationβ
package com.example.strategy;
import velox.api.layer1.common.RunModeHelper;
import velox.api.layer1.Layer1ApiAdminListener;
import velox.api.layer1.Layer1ApiTradingListener;
import velox.api.layer1.data.ExecutionInfo;
import velox.api.layer1.common.Log;
/**
* Example strategy that adapts behavior based on RunMode
*/
public class AdaptiveStrategy implements
Layer1ApiAdminListener,
Layer1ApiTradingListener {
private int maxPositionSize;
private boolean enableDetailedLogging;
@Override
public void onLoginSuccessful() {
// Wait for RunModeHelper initialization
if (!RunModeHelper.isSet()) {
Log.warn("RunModeHelper not initialized");
useDefaultConfiguration();
return;
}
// Get mode flags
Boolean isLive = RunModeHelper.isLive();
Boolean isRealTrading = RunModeHelper.isRealTrading();
// Configure based on mode
if (Boolean.TRUE.equals(isLive) && Boolean.TRUE.equals(isRealTrading)) {
// LIVE_REAL: Production mode
maxPositionSize = 100;
enableDetailedLogging = false;
Log.info("[PRODUCTION] Strategy initialized");
}
else if (Boolean.TRUE.equals(isLive)) {
// LIVE_SIMULATED: Paper trading
maxPositionSize = 1000;
enableDetailedLogging = true;
Log.info("[PAPER TRADING] Strategy initialized");
}
else {
// REPLAY_SIMULATED: Backtesting
maxPositionSize = 10000;
enableDetailedLogging = true;
Log.info("[BACKTEST] Strategy initialized");
}
}
@Override
public void onOrderExecuted(ExecutionInfo execution) {
// Verify execution type matches mode
Boolean isRealTrading = RunModeHelper.isRealTrading();
if (Boolean.TRUE.equals(isRealTrading) && execution.isSimulated) {
Log.warn("Simulated execution in real trading mode");
}
if (enableDetailedLogging) {
Log.info("Execution: " + execution.size + " @ " + execution.price
+ " (simulated=" + execution.isSimulated + ")");
}
}
private void useDefaultConfiguration() {
maxPositionSize = 100; // Conservative default
enableDetailedLogging = false;
}
// Other required interface methods...
@Override public void onLoginFailed(velox.api.layer1.data.LoginFailedReason reason, String message) {}
@Override public void onConnectionLost(velox.api.layer1.data.DisconnectionReason reason, String message) {}
@Override public void onConnectionRestored() {}
@Override public void onSystemTextMessage(String message, velox.api.layer1.data.SystemTextMessageType type) {}
@Override public void onUserMessage(Object data) {}
@Override public void onOrderUpdated(velox.api.layer1.data.OrderInfoUpdate update) {}
@Override public void onStatus(velox.api.layer1.data.StatusInfo status) {}
@Override public void onBalance(velox.api.layer1.data.BalanceInfo balance) {}
}
Example 2: Four-Mode Strategy with Distinct Behaviorsβ
package com.example.strategy;
import velox.api.layer1.common.RunModeHelper;
import velox.api.layer1.Layer1ApiAdminListener;
import velox.api.layer1.common.Log;
/**
* Strategy that handles all four RunMode combinations
*/
public class MultiModeStrategy implements Layer1ApiAdminListener {
private enum StrategyMode {
LIVE_REAL,
LIVE_SIMULATED,
REPLAY_REAL,
REPLAY_SIMULATED,
UNKNOWN
}
private StrategyMode currentMode = StrategyMode.UNKNOWN;
@Override
public void onLoginSuccessful() {
currentMode = detectMode();
switch (currentMode) {
case LIVE_REAL:
initializeProductionMode();
break;
case LIVE_SIMULATED:
initializePaperTradingMode();
break;
case REPLAY_SIMULATED:
initializeBacktestMode();
break;
case REPLAY_REAL:
Log.error("CRITICAL: REPLAY_REAL mode detected - this is dangerous!");
// Consider refusing to run
break;
case UNKNOWN:
Log.warn("Could not detect RunMode");
useDefaultConfiguration();
break;
}
}
private StrategyMode detectMode() {
if (!RunModeHelper.isSet()) {
return StrategyMode.UNKNOWN;
}
boolean isLive = Boolean.TRUE.equals(RunModeHelper.isLive());
boolean isRealTrading = Boolean.TRUE.equals(RunModeHelper.isRealTrading());
if (isLive && isRealTrading) return StrategyMode.LIVE_REAL;
if (isLive && !isRealTrading) return StrategyMode.LIVE_SIMULATED;
if (!isLive && isRealTrading) return StrategyMode.REPLAY_REAL;
return StrategyMode.REPLAY_SIMULATED;
}
private void initializeProductionMode() {
Log.info("=== PRODUCTION MODE ===");
// Strict risk controls
// Minimal logging
// Real-time performance critical
}
private void initializePaperTradingMode() {
Log.info("=== PAPER TRADING MODE ===");
// Moderate risk controls
// Detailed logging
// Test execution logic
}
private void initializeBacktestMode() {
Log.info("=== BACKTEST MODE ===");
// Relaxed risk controls
// Full diagnostics
// Collect performance metrics
}
private void useDefaultConfiguration() {
// Conservative defaults when mode unknown
}
// Other required interface methods...
@Override public void onLoginFailed(velox.api.layer1.data.LoginFailedReason reason, String message) {}
@Override public void onConnectionLost(velox.api.layer1.data.DisconnectionReason reason, String message) {}
@Override public void onConnectionRestored() {}
@Override public void onSystemTextMessage(String message, velox.api.layer1.data.SystemTextMessageType type) {}
@Override public void onUserMessage(Object data) {}
}
Example 3: Risk Management Based on Modeβ
package com.example.risk;
import velox.api.layer1.common.RunModeHelper;
/**
* Risk manager that adjusts limits based on RunMode
*/
public class AdaptiveRiskManager {
private final int basePositionLimit;
public AdaptiveRiskManager(int basePositionLimit) {
this.basePositionLimit = basePositionLimit;
}
/**
* Get maximum position size based on current RunMode
*/
public int getMaxPositionSize() {
if (!RunModeHelper.isSet()) {
// Most conservative default
return basePositionLimit;
}
Boolean isLive = RunModeHelper.isLive();
Boolean isRealTrading = RunModeHelper.isRealTrading();
// Production: strictest limits
if (Boolean.TRUE.equals(isLive) && Boolean.TRUE.equals(isRealTrading)) {
return basePositionLimit;
}
// Paper trading: moderate limits (10x base)
if (Boolean.TRUE.equals(isLive)) {
return basePositionLimit * 10;
}
// Backtesting: generous limits (100x base)
return basePositionLimit * 100;
}
/**
* Check if order size is within limits for current mode
*/
public boolean isOrderSizeAllowed(int size) {
return Math.abs(size) <= getMaxPositionSize();
}
/**
* Get appropriate stop loss distance based on mode
*/
public double getStopLossDistance(double entryPrice) {
if (!RunModeHelper.isSet()) {
return entryPrice * 0.02; // 2% default
}
Boolean isRealTrading = RunModeHelper.isRealTrading();
if (Boolean.TRUE.equals(isRealTrading)) {
// Real trading: tighter stops (1%)
return entryPrice * 0.01;
} else {
// Simulation: wider stops (3%)
return entryPrice * 0.03;
}
}
/**
* Determine if circuit breaker should be enabled
*/
public boolean shouldEnableCircuitBreaker() {
if (!RunModeHelper.isSet()) {
return true; // Safe default
}
Boolean isRealTrading = RunModeHelper.isRealTrading();
// Enable circuit breaker only in real trading mode
return Boolean.TRUE.equals(isRealTrading);
}
}
Example 4: Data Handler with Mode-Specific Logicβ
package com.example.data;
import velox.api.layer1.common.RunModeHelper;
import velox.api.layer1.common.Log;
import velox.api.layer1.data.TradeInfo;
/**
* Data handler that processes trades differently based on mode
*/
public class AdaptiveDataHandler {
private long lastTradeTime = 0;
private static final long STALENESS_THRESHOLD_MS = 5000;
public void onTrade(double price, int size, TradeInfo tradeInfo) {
if (!RunModeHelper.isSet()) {
return; // Skip processing before initialization
}
Boolean isLive = RunModeHelper.isLive();
if (Boolean.TRUE.equals(isLive)) {
handleLiveTrade(price, size, tradeInfo);
} else {
handleReplayTrade(price, size, tradeInfo);
}
}
private void handleLiveTrade(double price, int size, TradeInfo tradeInfo) {
long currentTime = System.currentTimeMillis();
// Check for stale data (important in live mode)
if (lastTradeTime > 0) {
long gap = currentTime - lastTradeTime;
if (gap > STALENESS_THRESHOLD_MS) {
Log.warn("Data gap detected: " + gap + "ms");
}
}
lastTradeTime = currentTime;
// Process with latency awareness
processTrade(price, size);
// Minimal logging in live mode
logTradeSummary(price, size);
}
private void handleReplayTrade(double price, int size, TradeInfo tradeInfo) {
// No need to check for staleness in replay mode
// Process without latency concerns
processTrade(price, size);
// Detailed logging in replay mode
logTradeDetails(price, size, tradeInfo);
}
private void processTrade(double price, int size) {
// Common trade processing logic
}
private void logTradeSummary(double price, int size) {
Log.info(String.format("Trade: %d @ %.2f", size, price));
}
private void logTradeDetails(double price, int size, TradeInfo tradeInfo) {
Log.debug("=== Trade Details ===");
Log.debug(" Price: " + price);
Log.debug(" Size: " + size);
Log.debug(" isBidAggressor: " + tradeInfo.isBidAggressor);
Log.debug(" isOtc: " + tradeInfo.isOtc);
}
}
Utility Wrapperβ
For cleaner code and better null safety, consider using this utility wrapper:
package com.example.util;
import velox.api.layer1.common.RunModeHelper;
/**
* Null-safe wrapper around RunModeHelper with convenient utility methods.
*
* This wrapper provides:
* - Primitive boolean returns (never null)
* - Mode enum for cleaner switch statements
* - Formatted mode descriptions
* - Null-safe helper methods
*/
public final class RunModeUtil {
/**
* Enumeration of the four possible run modes
*/
public enum Mode {
LIVE_REAL("Production Trading", "Live data + Real trading"),
LIVE_SIMULATED("Paper Trading", "Live data + Simulated trading"),
REPLAY_REAL("Replay Real", "Historical data + Real trading (DANGEROUS)"),
REPLAY_SIMULATED("Backtesting", "Historical data + Simulated trading"),
NOT_INITIALIZED("Not Initialized", "RunModeHelper not yet set");
private final String displayName;
private final String description;
Mode(String displayName, String description) {
this.displayName = displayName;
this.description = description;
}
public String getDisplayName() { return displayName; }
public String getDescription() { return description; }
}
// Private constructor - utility class
private RunModeUtil() {}
/**
* Check if RunModeHelper is initialized
*/
public static boolean isInitialized() {
return RunModeHelper.isSet();
}
/**
* Get the current mode as an enum
*/
public static Mode getCurrentMode() {
if (!RunModeHelper.isSet()) {
return Mode.NOT_INITIALIZED;
}
boolean isLive = isLiveMode();
boolean isRealTrading = isRealTradingMode();
if (isLive && isRealTrading) return Mode.LIVE_REAL;
if (isLive && !isRealTrading) return Mode.LIVE_SIMULATED;
if (!isLive && isRealTrading) return Mode.REPLAY_REAL;
return Mode.REPLAY_SIMULATED;
}
/**
* Check if currently in live mode (data from provider)
*
* @return true if live, false if replay or not initialized
*/
public static boolean isLiveMode() {
Boolean result = RunModeHelper.isLive();
return result != null && result;
}
/**
* Check if currently in replay mode (data from Bookmap files)
*
* @return true if replay, false if live or not initialized
*/
public static boolean isReplayMode() {
Boolean result = RunModeHelper.isLive();
return result != null && !result;
}
/**
* Check if currently in real trading mode (orders to provider)
*
* @return true if real trading, false if simulated or not initialized
*/
public static boolean isRealTradingMode() {
Boolean result = RunModeHelper.isRealTrading();
return result != null && result;
}
/**
* Check if currently in simulated trading mode (orders simulated by Bookmap)
*
* @return true if simulated, false if real or not initialized
*/
public static boolean isSimulatedTradingMode() {
Boolean result = RunModeHelper.isRealTrading();
return result != null && !result;
}
/**
* Check if in production mode (live data + real trading)
*/
public static boolean isProductionMode() {
return isLiveMode() && isRealTradingMode();
}
/**
* Check if in paper trading mode (live data + simulated trading)
*/
public static boolean isPaperTradingMode() {
return isLiveMode() && isSimulatedTradingMode();
}
/**
* Check if in backtesting mode (replay data + simulated trading)
*/
public static boolean isBacktestMode() {
return isReplayMode() && isSimulatedTradingMode();
}
/**
* Check if in dangerous mode (replay data + real trading)
*/
public static boolean isDangerousMode() {
return isReplayMode() && isRealTradingMode();
}
/**
* Get formatted string describing current mode
*/
public static String getModeDescription() {
Mode mode = getCurrentMode();
return String.format("%s: %s", mode.getDisplayName(), mode.getDescription());
}
/**
* Get short mode code (e.g., "LIVE|REAL", "REPLAY|SIM")
*/
public static String getModeCode() {
if (!isInitialized()) {
return "NOT_SET";
}
String dataSource = isLiveMode() ? "LIVE" : "REPLAY";
String tradingMode = isRealTradingMode() ? "REAL" : "SIM";
return dataSource + "|" + tradingMode;
}
/**
* Wait for RunModeHelper to be initialized (blocking)
*
* @param timeoutMs Maximum time to wait in milliseconds
* @return true if initialized, false if timeout
*/
public static boolean waitForInitialization(long timeoutMs) {
long startTime = System.currentTimeMillis();
while (!isInitialized()) {
if (System.currentTimeMillis() - startTime > timeoutMs) {
return false;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
return true;
}
}
Usage of RunModeUtil Wrapperβ
import com.example.util.RunModeUtil;
import com.example.util.RunModeUtil.Mode;
import velox.api.layer1.common.Log;
public class MyStrategy {
public void initialize() {
// Wait up to 5 seconds for initialization
if (!RunModeUtil.waitForInitialization(5000)) {
Log.error("RunModeHelper initialization timeout");
return;
}
// Get current mode
Mode mode = RunModeUtil.getCurrentMode();
Log.info("Running in: " + RunModeUtil.getModeDescription());
// Switch on mode enum
switch (mode) {
case LIVE_REAL:
initializeProduction();
break;
case LIVE_SIMULATED:
initializePaperTrading();
break;
case REPLAY_SIMULATED:
initializeBacktest();
break;
case REPLAY_REAL:
Log.error("CRITICAL: Dangerous mode detected!");
break;
case NOT_INITIALIZED:
Log.error("Not initialized");
break;
}
// Simple boolean checks (no null handling needed)
if (RunModeUtil.isProductionMode()) {
enableStrictRiskControls();
}
if (RunModeUtil.isBacktestMode()) {
enableDetailedLogging();
}
}
private void initializeProduction() { /* ... */ }
private void initializePaperTrading() { /* ... */ }
private void initializeBacktest() { /* ... */ }
private void enableStrictRiskControls() { /* ... */ }
private void enableDetailedLogging() { /* ... */ }
}
Document Metadataβ
Sourcesβ
Primary Documentation:
RunModeHelper.md(Javadoc converted to Markdown)
Related Classes Referenced:
Layer1ApiIsRealTradingMessage.md- Real trading flag messageExecutionInfo.md- ContainsisSimulatedfieldOrderInfo.md- ContainsisSimulatedfieldLayer1ApiDataListener.md- Data event callbacksLayer1ApiTradingListener.md- Trading event callbacksLayer1ApiAdminListener.md- Admin callbacks includingonLoginSuccessful()Layer1ApiAdminProvider.md- Lists implementing provider classesLayer1ApiProvider.md- Provider interface hierarchy
Confidence Assessmentβ
| Aspect | Confidence | Reason |
|---|---|---|
| Overall | HIGH | Well-documented API with clear javadoc |
| Method signatures | HIGH | Directly documented in knowledge base |
| Return types | HIGH | Explicitly stated (Boolean vs boolean) |
| Initialization lifecycle | MEDIUM | Inferred from "Once" naming and static design |
| Null handling | HIGH | Boolean object returns clearly nullable |
| Thread safety | MEDIUM | No explicit documentation, inferred from static read-only pattern |
| Four modes | HIGH | Mathematical combination of two boolean flags |
| Related class impact | HIGH | Cross-references found and verified |
| Provider selection | HIGH | ExternalLiveBaseProvider/ExternalReaderBaseProvider listed as implementing classes |
| Use in production | HIGH | Fundamental API design pattern, well-established |
Well-Documented Areasβ
- Γ’Εβ¦ Method signatures and return types
- Γ’Εβ¦ Purpose of each boolean flag
- Γ’Εβ¦ Distinction between live/replay and real/simulated
- Γ’Εβ¦ Relationship to ExecutionInfo/OrderInfo simulation flags
- Γ’Εβ¦ Static utility class pattern
- Γ’Εβ¦ Provider implementation classes
Inferred/Enhanced Areasβ
- Γ°ΕΈβΒ Initialization timing (inferred from "Once" naming)
- Γ°ΕΈβΒ Thread safety characteristics (inferred from static read-only design)
- Γ°ΕΈβΒ Four-mode combinations (derived from 2x2 boolean matrix)
- Γ°ΕΈβΒ Null handling patterns (inferred from Boolean object returns)
- Γ°ΕΈβΒ Best practices and usage patterns (derived from API design)
- Γ°ΕΈβΒ Edge cases and gotchas (inferred from common pitfalls)
Gaps / Unknown Areasβ
- Γ’Ββ Implementation details: No source code showing internal static field structure
- Γ’Ββ Exact initialization timing: When during startup is
setRunModeOnce()called? - Γ’Ββ Duplicate call behavior: Exception, ignore, or error on second
setRunModeOnce()call? - Γ’Ββ Thread safety guarantees: No documentation on synchronization mechanisms
- Γ’Ββ Configuration relationship: How does RunMode relate to
bookmap.xmlor other config files? - Γ’Ββ UI relationship: How does Bookmap UI mode selector map to
setRunModeOnce()parameters? - Γ’Ββ Historical behavior: Has the API changed over Bookmap versions?
- Γ’Ββ Performance: Overhead of frequent static method calls (likely negligible but undocumented)
Recommendations for Future Researchβ
- Test in live Bookmap instance: Verify null return behavior before initialization
- Test duplicate calls: Confirm behavior when
setRunModeOnce()called twice - Review Bookmap source: If available, examine implementation for thread safety details
- Check Bookmap forums: Look for user discussions about RunMode edge cases
- Validate provider relationship: Confirm that
isLive()directly controls provider selection
Enrichment Methodologyβ
This documentation was generated using the Bookmap API Documentation Enrichment System:
Phase 1: Evidence Gathering
- Searched knowledge-base for all RunModeHelper references
- Extracted cross-references to related classes
- Compiled usage patterns from Javadoc
Phase 2: Behavioral Inference
- Analyzed method signatures (Boolean vs boolean)
- Inferred lifecycle from naming ("Once")
- Mapped relationships to ExecutionInfo/OrderInfo
Phase 3: Hypothesis Generation
- Formulated testable hypotheses about null returns
- Identified edge cases from type system
- Created verification test cases
Phase 4: Documentation Synthesis
- Produced comprehensive API reference
- Generated complete code examples
- Created utility wrapper for better ergonomics
Changes from Original Versionβ
| Section | Change | Reason |
|---|---|---|
| Lifecycle | Added note about inference | Transparency about confidence level |
| isSet() | Added official return documentation | KB verification |
| isLive() | Added full official return documentation | KB verification |
| isRealTrading() | Added full official return documentation | KB verification |
| onLoginSuccessful() | Fixed signature to no-parameter version | KB shows void onLoginSuccessful() |
| Examples | Updated to use Log.info() | Bookmap convention |
| Examples | Added required interface method stubs | Complete implementations |
| Relationship section | Added KB evidence note | Transparency |
| Provider Selection | Upgraded confidence to HIGH | KB lists implementing classes |
| Metadata | Added change log | Version tracking |
Document Version: 1.1
Generated: 2025-01-21
API Class: velox.api.layer1.common.RunModeHelper
Confidence Level: HIGH
Completeness: ~90% (missing only internal implementation details)