A deterministic agent that evaluates whether trades were executed according to a predefined trading plan β conditioned on the current market regime.
- β Rule-based evaluation β No AI/ML, deterministic compliance checking
- π Regime-aware analysis β Validates trades against market regime constraints
- π‘οΈ Stop-loss validation β Ensures stop-loss orders are properly set
- πΎ Persistent memory β Tracks compliance history over time
- π« No external APIs β Fully offline, no OpenAI or external dependencies
- π― Process-focused β Measures discipline, not performance
- Python 3.7+
- pip
-
Clone the repository
git clone <repository-url> cd Execution-Discipline-Agent
-
Install dependencies
pip install -r requirements.txt
-
Run the Streamlit app
streamlit run app.py
-
Open your browser
- The app will automatically open at
http://localhost:8501 - If not, navigate to the URL shown in the terminal
- The app will automatically open at
-
Prepare your files:
- π Trades CSV β Your trade execution log (see format below)
- π Trading Plan JSON β Your trading rules (see format below)
-
Launch the app:
streamlit run app.py
-
Upload files:
- Upload your trades CSV file
- Upload your trading plan JSON file
- Enter the current market regime label (e.g., "Risk-On", "Risk-Off")
-
View results:
- Compliance score (0.0 to 1.0)
- Regime mismatch rate
- Detailed violation list
Your trades CSV must include the following columns:
| Column | Description | Example | Required |
|---|---|---|---|
date |
Trade date | 2025-08-01 |
β |
symbol |
Trading symbol | SPY |
β |
side |
Trade direction | LONG or SHORT |
β |
entry_price |
Entry price | 530.00 |
β |
exit_price |
Exit price | 535.00 |
β |
shares |
Number of shares | 100 |
β |
stop_price |
Stop-loss price | 525.00 |
stop_required: true) |
Example:
date,symbol,side,entry_price,exit_price,shares,stop_price
2025-08-01,SPY,LONG,530,535,100,525
2025-08-02,QQQ,LONG,470,465,120,Your trading plan JSON must include:
{
"risk_per_trade_pct": 0.5,
"max_position_pct": 10,
"allowed_regimes": ["Risk-On", "Risk-Off"],
"stop_required": true,
"max_stop_pct": 2.0,
"account_size": 100000,
"position_limits_by_regime": {
"Risk-On": 10,
"Risk-Off": 3
}
}Required Fields:
allowed_regimes(array): List of market regimes where trading is allowedstop_required(boolean): Whether stop-loss orders are mandatory
Optional Fields:
risk_per_trade_pct: Maximum risk per trade percentagemax_position_pct: Maximum position size percentagemax_stop_pct: Maximum stop-loss percentageaccount_size(number): Total account size in dollars (required for position sizing checks)position_limits_by_regime(object): Dictionary mapping regime names to maximum position size as percentage of account (e.g.,{"Risk-On": 10}means max 10% of account per position in Risk-On regime)
Example:
{
"risk_per_trade_pct": 0.5,
"max_position_pct": 10,
"allowed_regimes": ["Risk-On", "Risk-Off"],
"stop_required": true,
"max_stop_pct": 2.0,
"account_size": 100000,
"position_limits_by_regime": {
"Risk-On": 10,
"Risk-Off": 3
}
}Position Sizing Rule:
- Position size is calculated as
shares Γ entry_price - If
position_limits_by_regimeandaccount_sizeare provided, the agent will check each trade against the regime-specific limit - Violations are flagged when position size exceeds the allowed percentage for the current regime
Enter the current market regime as a text string. Common values:
Risk-OnRisk-OffNeutralVolatile
The agent generates a Discipline Report containing:
-
Compliance Score (0.0 - 1.0)
1.0= Perfect compliance (no violations)0.0= Complete non-compliance- Calculated as:
1.0 - (violations / total_trades)
-
Regime Mismatch Rate (0.0 - 1.0)
- Percentage of trades executed in non-allowed regimes
Each violation includes:
- Trade Index: Which trade violated the rule
- Violation Type:
Regime Mismatchβ Trade executed in non-allowed regimeMissing Stopβ Required stop-loss not providedOversized for Regimeβ Position size exceeds regime-specific limitEarly Exitβ Exited trade with R < 0.5 (didn't let trade run to target)Late Exitβ Hit stop loss after trade likely had >= 1R unrealized gain (should have exited earlier)
- Detail: Human-readable explanation
R-Multiple Calculation:
- R-multiple measures trade performance relative to risk:
R = (exit_price - entry_price) / (entry_price - stop_price) - Only calculated for trades with valid
stop_price - Supports both LONG and SHORT positions
Execution-Discipline-Agent/
βββ app.py # Streamlit web interface
βββ src/
β βββ agent.py # Main agent logic
β βββ rules.py # Compliance rule checkers
β βββ schemas.py # Data models
β βββ memory.py # Persistent state management
βββ data/
β βββ trades.example.csv # Example trades file
β βββ plan.example.json # Example plan file
βββ state/
β βββ memory.json # Persistent compliance history
βββ requirements.txt # Python dependencies
ExecutionDisciplineAgent: Main agent class that orchestrates compliance checkingcheck_regime_allowed(): Validates trades against allowed regimescheck_missing_stops(): Ensures stop-loss orders are present when requiredcheck_position_sizing(): Validates position sizes against regime-specific limitscheck_r_multiple(): Calculates R-multiples and flags Early Exit and Late Exit violations- Memory System: Tracks compliance history in
state/memory.json
import pandas as pd
import json
from src.agent import ExecutionDisciplineAgent
# Load data
trades = pd.read_csv("data/trades.example.csv")
plan = json.load(open("data/plan.example.json"))
# Run agent
agent = ExecutionDisciplineAgent()
report = agent.run(trades, plan, regime_label="Risk-Off")
# View results
print(f"Compliance Score: {report.compliance_score}")
for v in report.violations:
print(f"Trade #{v.trade_index}: {v.violation_type} - {v.detail}")- Run
streamlit run app.py - Upload
data/trades.example.csv - Upload
data/plan.example.json - Enter regime:
Risk-Off - View the compliance report
If you see AxiosError: Request failed with status code 403:
-
Restart Streamlit β Stop the server (Ctrl+C) and restart:
streamlit run app.py
-
Clear browser cache β Hard refresh:
Cmd+Shift+R(Mac) orCtrl+Shift+R(Windows) -
Check config β Ensure
.streamlit/config.tomlhasenableXsrfProtection = false
- Missing columns: Ensure your CSV has all required columns (see Input Formats)
- Invalid data types: Check that prices and shares are numeric
- Empty file: Ensure the CSV has at least one data row (not just headers)
- Invalid JSON: Validate your JSON using a JSON validator
- Missing fields: Ensure
allowed_regimesis present in your plan - Wrong data types:
allowed_regimesmust be an array,stop_requiredmust be boolean
If you see errors about state/memory.json:
- The file is created automatically on first run
- Ensure the
state/directory exists or is writable - Delete
state/memory.jsonto reset history
- Offline Only: This agent does not connect to external APIs or services
- Deterministic: Same inputs always produce the same outputs
- Process Focus: Measures trading discipline, not profitability
- Memory Persistence: Compliance history is saved to
state/memory.json
[Add your license information here]
[Add contribution guidelines here]
Built to diagnose behavior, not generate signals. π―