Skip to content

21 - Admin Section

Overview

The Admin section provides system configuration and management capabilities including freeze quantity management, market holidays, market timings, and security monitoring.

admin_bp is registered with url_prefix="/admin" and now exposes JSON endpoints only. The former server-rendered page routes (/admin/, /admin/freeze, /admin/holidays, /admin/timings) are commented out in blueprints/admin.py; the pages themselves are React routes.

Architecture Diagram

┌───────────────────────────────────────────────────────────────────────────────┐
│                          Admin Section Architecture                           │
└───────────────────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────────────────┐
│                               React Admin Pages                               │
│                                                                               │
│  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐   │
│  │ Freeze        │  │ Holiday       │  │ Market        │  │ Diagnostics,  │   │
│  │ quantities    │  │ calendar      │  │ timings       │  │ Remote MCP    │   │
│  └───────┬───────┘  └───────┬───────┘  └───────┬───────┘  └───────┬───────┘   │
│          │                  │                  │                  │           │
│          └──────────────────┴────────┬─────────┴──────────────────┘           │
│                                      │                                        │
│                                      ▼                                        │
│               ┌────────────────────────────────────────────┐                  │
│               │ blueprints/admin.py, url_prefix /admin     │                  │
│               │ JSON only, every route is /admin/api/*     │                  │
│               └────────────────────────────────────────────┘                  │
└───────────────────────────────────────────────────────────────────────────────┘

┌───────────────────────────────────────────────────────────────────────────────┐
│                             Monitoring Dashboards                             │
│                                                                               │
│  ┌──────────────────────┐  ┌──────────────────────┐  ┌──────────────────────┐ │
│  │ Security             │  │ Traffic              │  │ Latency              │ │
│  │ /security            │  │ /traffic             │  │ /latency             │ │
│  │                      │  │                      │  │                      │ │
│  │ - IP bans            │  │ - HTTP logs          │  │ - Order RTT          │ │
│  │ - 404 tracking       │  │ - Requests per second│  │ - Percentiles        │ │
│  │ - API-key abuse      │  │ - Error rates        │  │ - SLA buckets        │ │
│  └──────────────────────┘  └──────────────────────┘  └──────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────────┘

Freeze Quantity Management

Purpose

Manage F&O freeze quantity limits for automatic order splitting.

API Endpoints

MethodEndpointDescription
GET/admin/api/freezeList all freeze quantities
POST/admin/api/freezeAdd new entry
PUT/admin/api/freeze/<id>Update entry
DELETE/admin/api/freeze/<id>Delete entry
POST/admin/api/freeze/uploadBulk CSV upload

Database Schema

┌─────────────────────────────────────────────────────┐
│                  qty_freeze table                   │
├────────────┬─────────────┬──────────────────────────┤
│ Column     │ Type        │ Description              │
├────────────┼─────────────┼──────────────────────────┤
│ id         │ INTEGER PK  │ Auto-increment           │
│ exchange   │ VARCHAR(10) │ NFO, BFO, CDS, MCX       │
│ symbol     │ VARCHAR(50) │ Trading symbol           │
│ freeze_qty │ INTEGER     │ Max order quantity       │
└────────────┴─────────────┴──────────────────────────┘

Example Request

json
// POST /admin/api/freeze
{
    "exchange": "NFO",
    "symbol": "NIFTY",
    "freeze_qty": 1800
}

Common Freeze Quantities

SymbolExchangeFreeze Qty
NIFTYNFO1800
BANKNIFTYNFO900
FINNIFTYNFO1800
SENSEXBFO1000

Market Holidays Management

Purpose

Maintain trading holidays calendar for all exchanges.

API Endpoints

MethodEndpointDescription
GET/admin/api/holidays?year=2024Get holidays for year
POST/admin/api/holidaysAdd new holiday
DELETE/admin/api/holidays/<id>Delete holiday

Database Schema

┌──────────────────────────────────────────────────────────────┐
│                    market_holidays table                     │
├──────────────┬─────────────┬─────────────────────────────────┤
│ Column       │ Type        │ Description                     │
├──────────────┼─────────────┼─────────────────────────────────┤
│ id           │ Integer PK  │ Auto-increment                  │
│ holiday_date │ Date        │ Holiday date, not null, indexed │
│ description  │ String(150) │ Holiday name, not null          │
│ holiday_type │ String(30)  │ Default TRADING_HOLIDAY         │
│ year         │ Integer     │ Not null, indexed               │
└──────────────┴─────────────┴─────────────────────────────────┘

┌────────────────────────────────────────────────────────────────────┐
│                   market_holiday_exchanges table                   │
├───────────────┬────────────┬───────────────────────────────────────┤
│ Column        │ Type       │ Description                           │
├───────────────┼────────────┼───────────────────────────────────────┤
│ id            │ Integer PK │ Auto-increment                        │
│ holiday_id    │ Integer    │ Holiday reference, not null, indexed  │
│ exchange_code │ String(10) │ Exchange code, not null, indexed      │
│ is_open       │ Boolean    │ Exchange open, defaults to false      │
│ start_time    │ BigInteger │ Session start, epoch millis, nullable │
│ end_time      │ BigInteger │ Session end, epoch millis, nullable   │
└───────────────┴────────────┴───────────────────────────────────────┘

Holiday Types

TypeDescription
TRADING_HOLIDAYFull market closure
SETTLEMENT_HOLIDAYSettlement closed
SPECIAL_SESSIONMuhurat trading

Supported Exchanges

  • NSE (National Stock Exchange)
  • BSE (Bombay Stock Exchange)
  • NFO (NSE F&O)
  • BFO (BSE F&O)
  • MCX (Multi Commodity Exchange)
  • CDS (Currency Derivatives)
  • BCD (BSE Currency Derivatives)

Example Request

json
// POST /admin/api/holidays
{
    "holiday_date": "2024-01-26",
    "description": "Republic Day",
    "holiday_type": "TRADING_HOLIDAY",
    "exchanges": ["NSE", "BSE", "NFO", "BFO", "MCX", "CDS"]
}

Market Timings Configuration

Purpose

Configure trading session timings for each exchange.

API Endpoints

MethodEndpointDescription
GET/admin/api/timingsGet all timings
PUT/admin/api/timings/<exchange>Update timing
POST/admin/api/timings/checkCheck for date

Default Timings

Seeded from DEFAULT_MARKET_TIMINGS in database/market_calendar_db.py when the market_timings table is empty.

ExchangeMarket OpenMarket Close
NSE09:1515:30
BSE09:1515:30
NFO09:1515:40
BFO09:1515:40
CDS09:0017:00
BCD09:0017:00
MCX09:0023:55
NCO09:0023:55
CRYPTO00:0023:59

NFO and BFO close at 15:40, not 15:30: SEBI's Closing Auction Session applies to the cash segment only, and derivatives keep trading past the cash close.

Example Request

json
// PUT /admin/api/timings/NSE
{
    "start_time": "09:15",
    "end_time": "15:30"
}

System Settings

Analyzer Mode Toggle

settings_bp is registered with url_prefix="/settings".

GET  /settings/analyze-mode      Get current mode
POST /settings/analyze-mode/0    Switch to Live mode
POST /settings/analyze-mode/1    Switch to Analyze mode

The setter route is POST /settings/analyze-mode/<int:mode>. Switching to Analyze starts the sandbox execution engine; switching to Live stops it.

Settings Schema

┌────────────────────────────────────────────────────────────────────────────────┐
│                                 settings table                                 │
├────────────────────────────────┬─────────────┬─────────────────────────────────┤
│ Column                         │ Type        │ Description                     │
├────────────────────────────────┼─────────────┼─────────────────────────────────┤
│ id                             │ Integer PK  │ Single row, id = 1              │
│ analyze_mode                   │ Boolean     │ False is Live, True is Analyzer │
│ smtp_server                    │ String(255) │ SMTP host                       │
│ smtp_port                      │ Integer     │ SMTP port                       │
│ smtp_username                  │ String(255) │ SMTP user                       │
│ smtp_password_encrypted        │ Text        │ Fernet ciphertext               │
│ smtp_use_tls                   │ Boolean     │ STARTTLS, defaults to true      │
│ smtp_from_email                │ String(255) │ From address                    │
│ smtp_helo_hostname             │ String(255) │ HELO/EHLO hostname              │
│ security_auto_ban_enabled      │ Boolean     │ Auto-ban, defaults to false     │
│ security_404_threshold         │ Integer     │ 404s per day before ban, 100    │
│ security_404_ban_duration      │ Integer     │ Hours, 0 means permanent        │
│ security_api_threshold         │ Integer     │ Invalid keys per day, 100       │
│ security_api_ban_duration      │ Integer     │ Hours, 0 means permanent        │
│ security_repeat_offender_limit │ Integer     │ Bans before permanent, 2        │
└────────────────────────────────┴─────────────┴─────────────────────────────────┘

Other Admin API Endpoints

All of these live under /admin and require a valid session.

MethodEndpointDescription
GET/admin/api/statsFreeze-entry and holiday counts
GET/admin/api/errorsRecent entries from log/errors.jsonl
POST/admin/api/errors/clientIngest a browser-side error report
GET/admin/api/errors/statsError counts by level
GET/admin/api/errors/groupsErrors grouped by fingerprint
GET/admin/api/systemHost, runtime, hardware, build, config, broker, database snapshot
POST/admin/api/system/diagnosticsRun the fixed latency/connectivity probes
GET/admin/api/system/reportDownload a rendered .md / .txt report
GET/admin/api/oauth/clientsList Remote MCP OAuth clients
POST/admin/api/oauth/clients/<client_id>/approveApprove a client
POST/admin/api/oauth/clients/<client_id>/revokeRevoke a client
GET/admin/api/mcp/auditRead the Remote MCP audit trail
POST/admin/api/mcp/kill-switchToggle the Remote MCP kill switch
GET/admin/api/mcp/settingsRead Remote MCP settings
PUT/admin/api/mcp/settingsUpdate Remote MCP settings

Security Dashboard

Access

/logs/security

Features

┌──────────────────────────────────────────────────────────────────┐
│                        Security Dashboard                        │
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐   │
│  │  IP Bans                                                   │  │
│  │                                                            │  │
│  │  IP Address      │ Reason        │ Expires     │ Actions  │   │
│  │  192.168.1.100   │ 404 abuse     │ 24h         │ Unban    │   │
│  │  10.0.0.50       │ API brute     │ Permanent   │ Unban    │   │
│  └───────────────────────────────────────────────────────────┘   │
│                                                                  │
│  ┌───────────────────────────────────────────────────────────┐   │
│  │  Security Thresholds                                       │  │
│  │                                                            │  │
│  │  Automatic bans: Off by default                            │  │
│  │  404 Errors: 100/day → 0h (permanent) when enabled        │   │
│  │  API Abuse:  100/day → 0h (permanent) when enabled        │   │
│  │  Repeat Offender: 2 bans → Permanent                       │  │
│  └───────────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────┘

Security Tables

ip_bans

Stores banned IP addresses with expiry.

error_404_tracker

Tracks 404 errors per IP. The persisted default threshold is 100 per 24 hours.

invalid_api_key_tracker

Tracks invalid API attempts per IP. The persisted default threshold is 100 per 24 hours.

Traffic Dashboard

Access

/logs/traffic

Features

  • HTTP request logging
  • Request/response metrics
  • Error rate monitoring
  • API endpoint statistics

Latency Dashboard

Access

/logs/latency

Features

  • Order execution latency
  • Round-trip time (RTT)
  • Percentile metrics (P50, P90, P95, P99)
  • SLA compliance tracking

SLA Buckets

OrderLatency.get_latency_stats() reports the share of orders whose total_latency_ms falls under each of three fixed thresholds, alongside the p50/p90/p95/p99 percentiles. The thresholds are hard-coded, not configurable.

FieldMeaning
sla_100msPercent of orders under 100 ms end to end
sla_150msPercent of orders under 150 ms end to end
sla_200msPercent of orders under 200 ms end to end

Access Control

Session Validation

python
@admin_bp.route('/api/freeze')
@check_session_validity
def get_freeze_quantities():
    # Only authenticated users can access
    pass

Rate Limiting

EndpointLimit
Most /admin/api/* routesAPI_RATE_LIMIT env var, default 50 per second
POST /admin/api/freeze/upload10/minute
POST /admin/api/system/diagnostics10/minute
GET /admin/api/system/report10/minute
POST /admin/api/mcp/kill-switch10/minute
PUT /admin/api/mcp/settings30/minute

The shared limiter in limiter.py keys on get_remote_address with in-memory storage and a moving-window strategy.

React Components

File Structure

frontend/src/pages/admin/
├── AdminIndex.tsx      # Main dashboard
├── FreezeQty.tsx       # Freeze quantity UI
├── Holidays.tsx        # Holiday calendar
├── MarketTimings.tsx   # Market timings
├── Diagnostics.tsx     # System snapshot and probes
├── RemoteMcp.tsx       # Remote MCP clients, audit, kill switch, settings
└── index.ts            # Barrel export

API Client

typescript
// frontend/src/api/admin.ts

export const adminApi = {
  getFreezeQuantities: () => api.get('/admin/api/freeze'),
  addFreezeQty: (data) => api.post('/admin/api/freeze', data),
  updateFreezeQty: (id, data) => api.put(`/admin/api/freeze/${id}`, data),
  deleteFreezeQty: (id) => api.delete(`/admin/api/freeze/${id}`),
  uploadFreezeCSV: (file) => api.post('/admin/api/freeze/upload', file),

  getHolidays: (year) => api.get(`/admin/api/holidays?year=${year}`),
  addHoliday: (data) => api.post('/admin/api/holidays', data),
  deleteHoliday: (id) => api.delete(`/admin/api/holidays/${id}`),

  getTimings: () => api.get('/admin/api/timings'),
  updateTiming: (exchange, data) => api.put(`/admin/api/timings/${exchange}`, data)
};

System Snapshot

Endpoint

GET /admin/api/system

Returns a no-store JSON snapshot assembled by _build_system_payload(). There is no file-permission audit anywhere in the codebase.

Payload Sections

KeyContents
modeLive or Analyze
hostOS, release, machine, distro, Docker / Raspberry Pi / Termux flags
runtimePython and dependency runtime details
hardwareCPU, memory, disk snapshot
buildVersion and build metadata
configNon-secret settings plus secret presence and strength booleans
brokersConfigured brokers and the active session broker, never tokens
databasesPer-database file presence, size, and mtime
timeServer time information

Secrets are never emitted as values. config.secrets_present reports set/not-set booleans for APP_KEY, API_KEY_PEPPER, BROKER_API_KEY, BROKER_API_SECRET, BROKER_API_KEY_MARKET, BROKER_API_SECRET_MARKET, and REDIRECT_URL, plus the DB-stored SMTP password and Telegram bot token. config.secret_strength reports whether APP_KEY, API_KEY_PEPPER, and FERNET_SALT are install-specific rather than the published sample placeholders.

Key Files Reference

FilePurpose
blueprints/admin.pyAdmin routes
database/qty_freeze_db.pyFreeze quantities
database/market_calendar_db.pyHolidays/timings
database/settings_db.pySettings table
database/traffic_db.pySecurity tables
utils/security_middleware.pyRequest-time IP enforcement
frontend/src/pages/admin/React components
frontend/src/api/admin.tsAPI client