A domain-specific configuration language for trading systems
Project description
tradsl
A powerful domain-specific configuration language for trading systems. Define your trading strategy, models, data adapters, and backtest configuration in a single declarative DSL with built-in feature computation and backtesting.
Features
- Declarative DSL - Define timeseries, models, agents, adapters, and parameters in a simple text format
- Parameter Blocks - Reusable parameter sets (
mlparams:,windowparams:) that can be referenced across your config - Data Adapters - Plug in any data source adapter via class path resolution
- Submodels - Use models as inputs to other models for ensemble/hierarchical strategies
- DAG Execution - Automatic topological ordering with cycle detection
- Type Safety - Schema validation for all config blocks
- Feature Engine - Compute features via DAG with support for timeseries functions and model predictions
- Training Scheduler - Rolling/expanding window training with configurable retrain schedules
- Backtest Interpreter - Run full backtests with event-driven feature computation
- Violent Failure - Explicit errors for invalid sizer output, model failures, and data issues
Installation
pip install -e .
Requires: pandas, numpy
Quick Start
import tradsl
from tradsl.utils import TradslInterpreter, load_timeseries, compute_features
from datetime import datetime
# Define your strategy
config_str = """
mlparams:
lr=0.001
epochs=100
:yfinance
type=adapter
class=adapters.YFAdapter
:nvda
type=timeseries
adapter=yfinance
parameters=["nvda"]
:vix
type=timeseries
adapter=yfinance
parameters=["^VIX"]
:nvda_ma30
type=timeseries
function=rolling_mean
inputs=[nvda]
params=mlparams
:signal_model
type=model
class=RandomForest
inputs=[nvda, vix, nvda_ma30]
params=mlparams
dotraining=true
retrain_schedule=weekly
training_window=rolling
training_window_size=500
:agent
type=agent
inputs=[signal_model, vix]
tradable=[nvda]
sizer=kelly_sizer
:backtest
type=backtest
start=2020-01-01
end=2024-01-01
capital=100000
"""
# Define your Python functions/classes
def rolling_mean(data, **kwargs):
window = kwargs.get('window', 30)
return data.rolling(window=window).mean()
class RandomForest:
def __init__(self, lr=0.001, epochs=100, **kwargs):
self.lr = lr
self.epochs = epochs
def train(self, X, y, **kwargs):
# Training logic here
pass
def predict(self, X, **kwargs):
# Return dict of output_name -> values
return {'allocation': [0.5] * len(X)}
def kelly_sizer(signals, tradable):
"""Must return dict mapping each tradable symbol to allocation weight"""
return {sym: 1.0 / len(tradable) for sym in tradable}
# Parse and resolve
config = tradsl.parse(config_str, context={
'rolling_mean': rolling_mean,
'RandomForest': RandomForest,
'kelly_sizer': kelly_sizer,
'adapters.YFAdapter': YourAdapterClass,
})
# Run backtest
interpreter = TradslInterpreter(config)
results = interpreter.run_backtest(
start=datetime(2020, 1, 1),
end=datetime(2024, 1, 1),
frequency='1min'
)
DSL Syntax
Parameter Blocks
mlparams:
lr=0.001
epochs=100
windowparams:
window=30
min_periods=10
Adapters
:yfinance
type=adapter
class=adapters.YFAdapter
Timeseries
:nvda
type=timeseries
adapter=yfinance
parameters=["nvda"]
Or derived timeseries:
:nvda_ma30
type=timeseries
function=rolling_mean
inputs=[nvda]
params=windowparams
Models
:signal_model
type=model
class=RandomForest
inputs=[nvda, vix]
params=mlparams
dotraining=true
retrain_schedule=weekly
training_window=rolling
training_window_size=500
load_from=./models/signal_model.pkl
Submodels (Model Ensemble)
:ensemble
type=model
class=EnsembleModel
inputs=[signal_model, another_model]
Agent
:agent
type=agent
inputs=[signal_model, vix]
tradable=[nvda]
sizer=kelly_sizer
Backtest
:backtest
type=backtest
start=2020-01-01
end=2024-01-01
capital=100000
Output Structure
The parse() function returns a dict with:
- Config blocks - Your timeseries, models, agent with resolved callables
_params- Parameter blocks dict_adapters- Instantiated adapter objects_backtest- Backtest configuration_execution_order- Topological sort of nodes_graph- Dependency graph (deps, reverse_deps)
Utilities
load_timeseries(config, start, end, frequency)
Load historical data from configured adapters:
from tradsl.utils import load_timeseries
from datetime import datetime
df = load_timeseries(config, datetime(2020, 1, 1), datetime(2024, 1, 1))
# Returns DataFrame with columns like nvda_close, vix_volume, etc.
compute_features(config, data)
Compute all features via DAG:
from tradsl.utils import compute_features
features = compute_features(config, raw_data)
# Adds computed columns for timeseries functions and model predictions
TradslInterpreter
Full backtest runner:
from tradsl.utils import TradslInterpreter
interpreter = TradslInterpreter(config)
interpreter.load_data(start, end)
interpreter.compute_initial_features()
interpreter.train_models()
results = interpreter.run_backtest(start, end, frequency='1min')
Context Resolution
When calling tradsl.parse(), pass a context dict with:
- Functions:
rolling_mean,kelly_sizer, etc. - Model classes:
RandomForest,LSTM, etc. - Adapter classes:
adapters.YFAdapter(full class path as key)
config = tradsl.parse(source, context={
'my_function': my_function,
'adapters.YFAdapter': YFAdapterClass,
})
Violent Failure
The system uses violent failure - explicit errors are raised for:
- Sizer output: Wrong keys, None, NaN/Inf, negative values, non-dict returns
- Model prediction: Failures or wrong return types
- Training: Instantiation failures, training errors
- Data loading: Adapter failures or empty data
This prevents silent failures and makes debugging explicit.
Testing
# Run all tests
python -m pytest tradsl/ -v
# Run specific test file
python -m pytest tradsl/test_parser.py -v
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tradsl-0.0.1.tar.gz.
File metadata
- Download URL: tradsl-0.0.1.tar.gz
- Upload date:
- Size: 27.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bcc599a843e4b30c10408c83eb4839285b6ce36b015415160cb71d49bdc2e30a
|
|
| MD5 |
f09623a0820140a650e9df115425235d
|
|
| BLAKE2b-256 |
76a2011146801d1ca61941167463a5122a53b348383c0206822e78078d7e5bbc
|
File details
Details for the file tradsl-0.0.1-py3-none-any.whl.
File metadata
- Download URL: tradsl-0.0.1-py3-none-any.whl
- Upload date:
- Size: 35.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53ffec53d703f551ddce874402f4969870f05c46cfe6baf1e5fc02bc8205d3ca
|
|
| MD5 |
66d2626f6909699770171ec6f45cf2aa
|
|
| BLAKE2b-256 |
ef0fa64b1e4a74970f36dea3ac316a021ca7876f3340301ce183e7995c72474c
|