Complete guide for the NIJA trading bot’s KPI monitoring, automated performance tracking, and risk alarm systems.
The NIJA KPI Dashboard provides comprehensive monitoring and risk management capabilities:
✅ Real-time Metrics
✅ Automated Monitoring
✅ Proactive Risk Alarms
bot/kpi_tracker.py)Purpose: Calculate and track key performance indicators
Key Classes:
KPISnapshot: Point-in-time KPI dataKPITracker: Main tracking engineget_kpi_tracker(): Singleton accessorTracked KPIs:
# Return Metrics
- Total Return %
- Daily/Weekly/Monthly Returns
- CAGR (Compound Annual Growth Rate)
# Risk Metrics
- Sharpe Ratio (risk-adjusted returns)
- Sortino Ratio (downside-only risk)
- Maximum Drawdown %
- Current Drawdown %
# Trade Statistics
- Total Trades
- Win Rate %
- Profit Factor
- Average Win/Loss
# Position Metrics
- Active Positions
- Total Exposure %
# Account Metrics
- Account Value
- Cash Balance
- Unrealized P&L
- Realized P&L
bot/automated_performance_tracker.py)Purpose: Continuous background monitoring
Key Features:
bot/risk_alarm_system.py)Purpose: Proactive risk monitoring and alerts
Alarm Types:
MAX_DRAWDOWN_EXCEEDEDDAILY_LOSS_LIMITCONSECUTIVE_LOSSESLOW_WIN_RATEPOSITION_SIZE_EXCEEDEDTOTAL_EXPOSURE_EXCEEDEDACCOUNT_BALANCE_LOWSHARPE_DEGRADATIONPROFIT_FACTOR_LOWAlarm Levels:
INFO - InformationalWARNING - Attention neededCRITICAL - Action requiredEMERGENCY - Immediate action requiredbot/kpi_dashboard_api.py)Purpose: RESTful API for dashboard access
Endpoints:
GET /api/kpi/current - Current KPI snapshot
GET /api/kpi/history - Historical KPI data
GET /api/kpi/summary - KPI summary
GET /api/performance/status - Performance tracker status
GET /api/alarms/active - Active risk alarms
GET /api/alarms/history - Alarm history
GET /api/dashboard/overview - Complete dashboard overview
GET /api/health - Health check
from bot.kpi_tracker import get_kpi_tracker
from bot.automated_performance_tracker import get_performance_tracker
from bot.risk_alarm_system import get_risk_alarm_system
# Initialize components
kpi_tracker = get_kpi_tracker(initial_capital=10000.0)
performance_tracker = get_performance_tracker(
update_interval=60, # Update every 60 seconds
report_interval=3600 # Report every hour
)
alarm_system = get_risk_alarm_system()
# Set callbacks to get account state
performance_tracker.set_account_callbacks(
account_value_fn=broker.get_account_value,
cash_balance_fn=broker.get_cash_balance,
positions_fn=broker.get_positions,
unrealized_pnl_fn=broker.get_unrealized_pnl,
realized_pnl_fn=broker.get_total_realized_pnl
)
# Start automated tracking
performance_tracker.start()
# When a trade completes
kpi_tracker.record_trade(
symbol='BTC-USD',
entry_price=50000.0,
exit_price=51000.0,
quantity=0.1,
side='long',
pnl=100.0,
entry_time=entry_time,
exit_time=exit_time,
fees=1.50
)
# Manually check all risks
alarm_system.check_all_risks()
# Get active alarms
active_alarms = alarm_system.get_active_alarms()
for alarm in active_alarms:
print(f"🚨 {alarm.level}: {alarm.message}")
print(f" Action: {alarm.recommended_action}")
# Update KPIs with current state
snapshot = kpi_tracker.update(
account_value=12500.0,
cash_balance=5000.0,
positions=[
{'symbol': 'BTC-USD', 'value': 5000.0},
{'symbol': 'ETH-USD', 'value': 2500.0}
],
unrealized_pnl=500.0,
realized_pnl_total=2500.0
)
print(f"Total Return: {snapshot.total_return_pct:.2f}%")
print(f"Sharpe Ratio: {snapshot.sharpe_ratio:.2f}")
print(f"Win Rate: {snapshot.win_rate_pct:.1f}%")
# Get latest snapshot
current = kpi_tracker.get_current_kpis()
if current:
print(f"Account Value: ${current.account_value:,.2f}")
print(f"Total Return: {current.total_return_pct:.2f}%")
print(f"Max Drawdown: {current.max_drawdown_pct:.2f}%")
print(f"Win Rate: {current.win_rate_pct:.1f}%")
print(f"Profit Factor: {current.profit_factor:.2f}")
summary = kpi_tracker.get_kpi_summary()
# Returns structured dictionary
{
'status': 'active',
'timestamp': '2026-01-30T10:30:00',
'returns': {
'total': 25.5,
'daily': 1.2,
'weekly': 5.3,
'monthly': 18.7
},
'risk_metrics': {
'sharpe_ratio': 1.8,
'sortino_ratio': 2.1,
'max_drawdown': 8.3,
'current_drawdown': 2.1
},
'trade_stats': {
'total_trades': 50,
'winning_trades': 33,
'losing_trades': 17,
'win_rate': 66.0,
'profit_factor': 1.85
}
}
# Get last 24 hours of KPI history
history = kpi_tracker.get_kpi_history(hours=24)
# Plot equity curve
import matplotlib.pyplot as plt
timestamps = [kpi.timestamp for kpi in history]
values = [kpi.account_value for kpi in history]
plt.plot(timestamps, values)
plt.title('24-Hour Equity Curve')
plt.show()
tracker = get_performance_tracker(
update_interval=60, # Update every minute
report_interval=3600 # Generate report every hour
)
# Configure data source callbacks
tracker.set_account_callbacks(
account_value_fn=get_account_value,
cash_balance_fn=get_cash_balance,
positions_fn=get_positions,
unrealized_pnl_fn=get_unrealized_pnl,
realized_pnl_fn=get_realized_pnl
)
# Start tracking
tracker.start()
# Pause/Resume
tracker.pause()
tracker.resume()
# Force immediate update
tracker.force_update()
# Force immediate report
tracker.force_report()
# Stop tracking
tracker.stop()
status = tracker.get_status()
print(f"Running: {status['running']}")
print(f"Updates: {status['update_count']}")
print(f"Reports: {status['report_count']}")
print(f"Last Update: {status['last_update']}")
from bot.risk_alarm_system import RiskThresholds
# Create custom thresholds
thresholds = RiskThresholds()
# Drawdown limits
thresholds.max_drawdown_pct = 20.0 # Emergency at 20%
thresholds.warning_drawdown_pct = 15.0 # Warning at 15%
# Loss limits
thresholds.daily_loss_limit_pct = 5.0 # Max 5% daily loss
thresholds.consecutive_losses_limit = 5 # Max 5 consecutive losses
# Win rate
thresholds.min_win_rate_pct = 50.0 # Critical below 50%
thresholds.warning_win_rate_pct = 55.0 # Warning below 55%
# Position limits
thresholds.max_position_size_pct = 10.0 # Max 10% per position
thresholds.max_total_exposure_pct = 80.0 # Max 80% total exposure
# Account balance
thresholds.min_account_balance = 100.0 # Emergency below $100
thresholds.warning_account_balance = 500.0 # Warning below $500
# Performance metrics
thresholds.min_sharpe_ratio = 0.5 # Warning below 0.5
thresholds.min_profit_factor = 1.0 # Critical below 1.0
# Create alarm system with custom thresholds
alarm_system = RiskAlarmSystem(thresholds=thresholds)
# Check all risks
alarm_system.check_all_risks()
# Or check against specific snapshot
snapshot = kpi_tracker.get_current_kpis()
alarm_system.check_all_risks(snapshot)
# Get all active alarms
active = alarm_system.get_active_alarms()
for alarm in active:
print(f"🚨 [{alarm.level}] {alarm.alarm_type}")
print(f" {alarm.message}")
print(f" Current: {alarm.current_value:.2f}")
print(f" Threshold: {alarm.threshold_value:.2f}")
print(f" Action: {alarm.recommended_action}")
print()
# Get last 24 hours of alarms
history = alarm_system.get_alarm_history(hours=24)
print(f"Total alarms in last 24h: {len(history)}")
# Group by level
by_level = {}
for alarm in history:
level = alarm.level
by_level[level] = by_level.get(level, 0) + 1
print(f"Emergency: {by_level.get('EMERGENCY', 0)}")
print(f"Critical: {by_level.get('CRITICAL', 0)}")
print(f"Warning: {by_level.get('WARNING', 0)}")
def send_email_notification(alarm):
"""Send email when alarm triggers"""
# Your email sending logic here
print(f"Sending email: {alarm.message}")
def send_webhook_notification(alarm):
"""Send webhook when alarm triggers"""
# Your webhook logic here
import requests
requests.post('https://your-webhook.com/alarm', json=alarm.to_dict())
# Register notification callbacks
alarm_system.add_notification_callback(send_email_notification)
alarm_system.add_notification_callback(send_webhook_notification)
curl http://localhost:5001/api/kpi/current
Response:
{
"success": true,
"data": {
"timestamp": "2026-01-30T10:30:00",
"total_return_pct": 25.5,
"sharpe_ratio": 1.8,
"win_rate_pct": 66.0,
"account_value": 12550.0
}
}
curl "http://localhost:5001/api/kpi/history?hours=24"
curl http://localhost:5001/api/dashboard/overview
Response:
{
"success": true,
"data": {
"timestamp": "2026-01-30T10:30:00",
"kpi": { ... },
"performance_tracking": { ... },
"risk_alarms": {
"active_count": 2,
"has_critical": true,
"has_warning": true,
"active_alarms": [...]
},
"system_health": {
"kpi_tracking": "active",
"performance_tracking": "active",
"risk_monitoring": "active"
}
}
}
curl http://localhost:5001/api/alarms/active
# In your main trading bot file
from bot.kpi_tracker import get_kpi_tracker
from bot.automated_performance_tracker import get_performance_tracker
from bot.risk_alarm_system import get_risk_alarm_system
class TradingBot:
def __init__(self, initial_capital):
# Initialize components
self.kpi_tracker = get_kpi_tracker(initial_capital=initial_capital)
self.performance_tracker = get_performance_tracker()
self.alarm_system = get_risk_alarm_system()
# Configure performance tracker
self.performance_tracker.set_account_callbacks(
account_value_fn=self.get_account_value,
cash_balance_fn=self.get_cash_balance,
positions_fn=self.get_positions
)
# Start automated tracking
self.performance_tracker.start()
def on_trade_close(self, trade):
"""Called when a trade closes"""
# Record trade in KPI tracker
self.kpi_tracker.record_trade(
symbol=trade.symbol,
entry_price=trade.entry_price,
exit_price=trade.exit_price,
quantity=trade.quantity,
side=trade.side,
pnl=trade.pnl,
entry_time=trade.entry_time,
exit_time=trade.exit_time,
fees=trade.fees
)
# Check risk alarms
self.alarm_system.check_all_risks()
# Check for emergency alarms
active_alarms = self.alarm_system.get_active_alarms()
emergency_alarms = [a for a in active_alarms if a.level == 'EMERGENCY']
if emergency_alarms:
logger.critical("🚨 EMERGENCY ALARM - STOPPING BOT")
self.stop_trading()
def get_account_value(self):
"""Get total account value"""
return self.broker.get_account_value()
def get_cash_balance(self):
"""Get cash balance"""
return self.broker.get_cash_balance()
def get_positions(self):
"""Get active positions"""
return self.broker.get_positions()
from flask import Flask
from bot.kpi_dashboard_api import register_kpi_dashboard_routes
app = Flask(__name__)
# Register KPI dashboard routes
register_kpi_dashboard_routes(app)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001)
# KPI Tracker
NIJA_INITIAL_CAPITAL=10000.0
NIJA_KPI_DATA_DIR=./data/kpi
# Performance Tracker
NIJA_PERF_UPDATE_INTERVAL=60
NIJA_PERF_REPORT_INTERVAL=3600
NIJA_PERF_DATA_DIR=./data/performance
# Risk Alarms
NIJA_ALARM_DATA_DIR=./data/risk_alarms
NIJA_MAX_DRAWDOWN=20.0
NIJA_DAILY_LOSS_LIMIT=5.0
NIJA_MIN_WIN_RATE=50.0
All components support customization through initialization parameters:
# Custom KPI tracker
kpi_tracker = KPITracker(
initial_capital=50000.0,
data_dir="./custom/kpi",
history_size=2000,
risk_free_rate=0.03 # 3% risk-free rate
)
# Custom performance tracker
perf_tracker = AutomatedPerformanceTracker(
update_interval=30, # Update every 30 seconds
report_interval=1800, # Report every 30 minutes
data_dir="./custom/performance"
)
# Custom alarm system
thresholds = RiskThresholds()
thresholds.max_drawdown_pct = 15.0 # Stricter limit
alarm_system = RiskAlarmSystem(
thresholds=thresholds,
data_dir="./custom/alarms"
)
# Check dashboard at least daily
summary = kpi_tracker.get_kpi_summary()
if summary['status'] == 'active':
logger.info(f"Daily Performance: {summary['returns']['daily']:.2f}%")
# Always check alarms after major events
alarm_system.check_all_risks()
active = alarm_system.get_active_alarms()
if any(a.level in ['CRITICAL', 'EMERGENCY'] for a in active):
# STOP TRADING
bot.pause_trading()
logger.critical("Trading paused due to critical alarms")
# Let performance tracker run continuously
tracker.start()
# Only pause during maintenance
# tracker.pause()
# ... maintenance ...
# tracker.resume()
All components automatically save state to disk. Ensure data directories are:
When deploying the API:
# Check if tracker is initialized
tracker = get_kpi_tracker()
current = tracker.get_current_kpis()
if current is None:
# Need to update with data first
tracker.update(
account_value=initial_capital,
cash_balance=initial_capital,
positions=[]
)
# Check status
status = tracker.get_status()
if not status['running']:
# Check if callbacks configured
if not status['callbacks_configured']:
# Configure callbacks first
tracker.set_account_callbacks(...)
# Then start
tracker.start()
# Manually check risks
alarm_system.check_all_risks()
# Check threshold configuration
thresholds = alarm_system.thresholds
print(f"Max Drawdown Threshold: {thresholds.max_drawdown_pct}%")
# Check cooldown (alarms won't re-trigger within cooldown period)
print(f"Cooldown: {alarm_system.alarm_cooldown_minutes} minutes")
For issues, questions, or feature requests:
./data/ directoriesNIJA Trading Systems - Professional Grade Trading Infrastructure