xtratej is a robust, reactive strategy/rule engine for Java. It provides a flexible framework for defining, testing, and executing trading strategies based on time-series data and event streams.
- Reactive Architecture: Built on a custom
Fiforeactive stream implementation for efficient event processing. - Extensible Rules Engine: define complex logic using a variety of composable rules (
CrossedRule,AndRule,OrRule, etc.). - Subcriber connectors: Support to connect and receive external datas.
- Time-Series Handling: Specialized support for temporal data manipulation and analysis.
- Strategy Management: Organize indicators and logic into cohesive
Strategyunits.
You can define strategies and rules directly in Java. Use StrategyManager to coordinate multiple strategies.
// 1. Create Sources
Subscriber source1 = SourceType.SIMULATED.builder()
.setName("flux1")
.setPublisher("test")
.build();
// 2. Configure Rules
LimitRule limitRule = (LimitRule) RuleType.Limit.build();
limitRule.setMin(2.0).setMax(80.0);
limitRule.watch(source1);
// 3. Define Strategy
IStrategy myStrategy = new Strategy(
"MyStrategy",
"BTC-USD",
IStrategy.StrategyType.ENTER
);
myStrategy.addSource(source1)
.setAggregatorRule(limitRule);
// 4. Manage and Run
Publisher publisher = TargetType.SIMULATED.builder().setName("simulated").build();
StrategyManager manager = new StrategyManager().setPublisher(publisher);
manager.registerStrategy(myStrategy);
manager.run();
// 5. Publisher send to external Trading signal consumer.
// HINT: it's possible monitoring publisher using this:
publisher.subscribe(signal -> {
// buy/sell logic
});Strategies can be loaded from a JSON file for better flexibility.
// 1. Load json
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readTree(new File("strategies.json"));
// 2. Define strategyManager
Publisher publisher = TargetType.SIMULATED.builder().setName("simulated").build();
StrategyManager manager = new StrategyManager().setPublisher(publisher);
// 3. Register strategies from json
Loader.fromJson(json).values()
.forEach(manager::registerStrategy);
// 4. Execute StrategyManager
manager.run();
// 5. Publisher send to external Trading signal consumer.
// HINT: it's possible monitoring publisher using this:
publisher.subscribe(signal -> {
// buy/sell logic
});The Loader class expects a JSON structure as follows:
strategies: (Object) Top-level container.[strategyName]: (Object) Key is the strategy name.symbol: (String) Trading symbol (e.g., "BTC/USD").type: (String) "ENTER" or "EXIT".sources: (Object) Map of data sources.[sourceName]: (Object) Key is the source identifier.type: (String) Source type (e.g., "SIMULATED", "NATS").publisher: (String) Publisher identifier.params: (Object) Source-specific params.
rule: (Object) The root rule definition.type: (String) Rule type (e.g., "And", "Or", "Limit", "Crossed").description: (String) Optional description.params: (Object) Rule params (e.g.,{"min": 10.0, "max": 20.0}).inputs: (Array) data sources name list (string list), declared insourcesattribute, OR nested rule objects.
{
"strategies": {
"enter": {
"symbol": "BTC/USD",
"type": "ENTER",
"sources": {
"flux1": {
"type": "SIMULATED",
"publisher": "local",
"params": {}
},
"flux2": {
"type": "SIMULATED",
"publisher": "local",
"params": {}
},
"flux3": {
"type": "SIMULATED",
"publisher": "local",
"params": {}
}
},
"rule": {
"description": "aggregator",
"type": "And",
"inputs": [
{
"type": "Or",
"inputs": [
{
"type": "Limit",
"description": "limit1",
"params": {
"min": 2.0,
"max": 80.0
},
"inputs": [
"flux1",
"flux2",
"flux3"
]
},
{
"type": "Limit",
"description": "limit2",
"params": {
"min": 0.0,
"max": 50.0
},
"inputs": [
"flux1",
"flux2",
"flux3"
]
}
]
},
{
"type": "Not",
"inputs": [
{
"type": "Limit",
"description": "limit3",
"params": {
"upperSourceId": "flux1",
"lowerSourceId": "flux2"
},
"inputs": [
"flux1",
"flux2",
"flux3"
]
}
]
}
]
}
}
}
}There are two modules/subprojects:
-
event: data flow containers implementations supported by a simple, but "real-time" reactive approach.
- TimeSeries: Optimized storage for temporal data points (prices, signals).
- Fifo: The underlying reactive pipe connecting components.
-
engine: Rule/Strategy engine with external sources connectors.
- Strategy: The central coordinator that manages lifecycle and data flow.
- RuleStream: Abstract base for all logic components. Rules process inputs and emit
BooleanSingleTimeSeriesresults. - Subscriber: Entity to subscribe external data sources.
- Java 25 or higher
- Maven 3.8+
Check issue tracker
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.