Enterprise quant teams face a recurring problem: generic market data tools solve generic problems. When your trading infrastructure requires domain-specific data enrichment, custom alerting logic, or proprietary risk calculations, you either bolt on fragile workarounds or build from scratch.

The TickDB SKILL protocol changes this calculus. SKILL (Structured Capability Integration for Language-model Loops) provides a standardized extension mechanism that lets enterprise teams embed TickDB's real-time market data capabilities directly into their own tooling—without forking the core product or maintaining fragile middleware.

This article dissects the SKILL protocol from the inside out. We cover development specifications, function extension patterns, authentication flows, and private deployment strategies for teams that need more than the standard TickDB API provides.

The SKILL Protocol: Architecture Overview

What SKILL Actually Is

SKILL is not a plugin system. It is a structured JSON-based protocol for defining callable capabilities that an AI agent can invoke on behalf of a user. Each SKILL is a self-contained capability bundle that declares:

  • Name and version: The identifier the AI agent uses to route requests
  • Function signatures: JSON Schema definitions of what the SKILL can execute
  • Runtime configuration: Credentials, endpoints, and environment-specific parameters
  • Execution contracts: Input/output contracts that the AI runtime validates
SKILL Definition Schema (simplified)
{
  "name": "tickdb-market-data",
  "version": "1.0.0",
  "description": "Real-time and historical market data via TickDB",
  "functions": [...],
  "runtime": {
    "baseUrl": "https://api.tickdb.ai",
    "auth": {
      "type": "api-key",
      "header": "X-API-Key"
    }
  }
}

Why This Architecture Matters for Enterprise

The critical insight is that SKILL operates at the capability layer, not the transport layer. Your custom SKILL does not replace TickDB's API—it wraps TickDB's capabilities with your business logic.

Consider two deployment patterns:

Pattern Description Enterprise fit
Pre-processing SKILL Enriches raw TickDB data before delivery Custom normalization, currency conversion, symbol mapping
Post-processing SKILL Applies business logic after data retrieval Risk calculation, alert filtering, P&L attribution
Composite SKILL Chains multiple data sources with custom logic Multi-vendor aggregation with TickDB as primary

The flexibility to position your logic at any point in the data pipeline is what makes SKILL enterprise-appropriate. You are not constrained to the features TickDB ships; you are building on top of a capability interface.

SKILL Development Specifications

Project Structure

A production SKILL project follows a standardized layout:

tickdb-enterprise-skill/
├── skill.json           # SKILL manifest (the descriptor)
├── functions/
│   ├── get_realtime_quote.js
│   ├── query_historical.js
│   └── calculate_position.js
├── config/
│   ├── development.json
│   ├── staging.json
│   └── production.json
├── tests/
│   └── integration.test.js
└── package.json

The skill.json manifest is the contract between your SKILL and the AI runtime. Every function you expose must have a complete JSON Schema definition.

Function Definition Schema

Each function in your SKILL requires three components:

  1. Metadata: Name, description, and version
  2. Parameters: JSON Schema defining required and optional inputs
  3. Handler: The execution logic (Node.js or Python runtime)

Here is a complete function definition for a custom position-sizing function:

// functions/calculate_position_size.js

/**
 * Calculates position size based on risk parameters and current volatility.
 * Used for real-time risk management in volatility-adjusted strategies.
 *
 * @param {object} params
 * @param {number} params.account_equity - Current account equity in USD
 * @param {number} params.risk_percent - Maximum risk per trade (0.01 = 1%)
 * @param {number} params.stop_loss_pct - Stop loss percentage (0.02 = 2%)
 * @param {string} params.symbol - Target symbol (e.g., "NVDA.US")
 * @param {object} params.context - Runtime context (auth, config, logger)
 *
 * @returns {object} { size: number, risk_amount: number, adjusted_stop: number }
 */
const calculatePositionSize = (params, context) => {
  const { account_equity, risk_percent, stop_loss_pct, symbol } = params;
  
  // Validate inputs
  if (!account_equity || account_equity <= 0) {
    throw new Error("INVALID_EQUITY: account_equity must be a positive number");
  }
  
  const risk_amount = account_equity * risk_percent;
  const position_value = risk_amount / stop_loss_pct;
  
  // Fetch current price to convert to share count
  const quote = context.tickdb.getQuote(symbol);
  const share_count = Math.floor(position_value / quote.price);
  
  return {
    size: share_count,
    risk_amount: parseFloat(risk_amount.toFixed(2)),
    adjusted_stop: parseFloat((quote.price * (1 - stop_loss_pct)).toFixed(2)),
    notional_value: parseFloat((share_count * quote.price).toFixed(2)),
    risk_reward_ratio: (quote.price - quote.price * (1 - stop_loss_pct)) / 
                       (quote.price * (1 + stop_loss_pct * 2) - quote.price)
  };
};

module.exports = { handler: calculatePositionSize };

The Context Object: Your Bridge to TickDB

The context object is your interface to the underlying TickDB capabilities. It exposes:

Context method Returns Use case
context.tickdb.getQuote(symbol) Real-time quote Pre-trade validation
context.tickdb.getDepth(symbol, levels) Order book snapshot Liquidity assessment
context.tickdb.getKline(symbol, interval, limit) OHLCV candles Historical analysis
context.tickdb.getTrades(symbol, limit) Recent trades Order flow analysis
context.config.get(key) Runtime configuration Environment-specific settings
context.logger.info(message) Log entry Auditing and debugging

The context is injected by the SKILL runtime, so you never handle credentials directly in your function code. This separation is critical for security compliance.

Function Extension Patterns

Pattern 1: Data Enrichment

Transform raw TickDB output into domain-specific formats:

// functions/enrich_us_equity_quote.js

const enrichQuote = (params, context) => {
  const { symbol } = params;
  
  // Fetch raw quote from TickDB
  const raw_quote = context.tickdb.getQuote(symbol);
  
  // Fetch supporting data
  const depth = context.tickdb.getDepth(symbol, 5);
  const recent_trades = context.tickdb.getTrades(symbol, 20);
  
  // Calculate derived metrics
  const buy_volume = recent_trades
    .filter(t => t.side === 'buy')
    .reduce((sum, t) => sum + t.size, 0);
  const sell_volume = recent_trades
    .filter(t => t.side === 'sell')
    .reduce((sum, t) => sum + t.size, 0);
  
  // Order flow imbalance
  const imbalance = (buy_volume - sell_volume) / (buy_volume + sell_volume);
  
  // Depth-weighted spread
  const weighted_spread = depth.reduce((sum, level, i) => {
    return sum + (level.ask - level.bid) / (i + 1);
  }, 0);
  
  return {
    symbol: raw_quote.symbol,
    price: raw_quote.price,
    bid_ask_spread: parseFloat((raw_quote.ask - raw_quote.bid).toFixed(4)),
    order_flow_imbalance: parseFloat(imbalance.toFixed(4)),
    depth_weighted_spread: parseFloat(weighted_spread.toFixed(4)),
    volume_ratio: parseFloat((buy_volume / (sell_volume || 1)).toFixed(2)),
    liquidity_score: raw_quote.volume / weighted_spread,
    timestamp: raw_quote.timestamp
  };
};

module.exports = { handler: enrichQuote };

This pattern is particularly useful for teams running factor models that require normalized input features.

Pattern 2: Multi-Step Workflows

Chain TickDB calls with conditional logic:

// functions/liquidity_regime_detection.js

const detectLiquidityRegime = (params, context) => {
  const { symbol, lookback_minutes = 5 } = params;
  
  // Step 1: Establish baseline
  const baseline_depth = context.tickdb.getDepth(symbol, 10);
  const baseline_spread = baseline_depth.reduce(
    (sum, l) => sum + (l.ask - l.bid), 0
  ) / baseline_depth.length;
  
  // Step 2: Monitor real-time deviation
  const current_depth = context.tickdb.getDepth(symbol, 10);
  const current_spread = current_depth.reduce(
    (sum, l) => sum + (l.ask - l.bid), 0
  ) / current_depth.length;
  
  // Step 3: Classify regime
  const spread_ratio = current_spread / baseline_spread;
  
  let regime;
  let confidence;
  
  if (spread_ratio > 3.0) {
    regime = 'crisis';        // Spread exploded, likely news event
    confidence = 0.92;
  } else if (spread_ratio > 1.5) {
    regime = 'stressed';      // Elevated but not extreme
    confidence = 0.78;
  } else if (spread_ratio < 0.5) {
    regime = 'collapsed';     // Tight spread, low volume risk
    confidence = 0.65;
  } else {
    regime = 'normal';
    confidence = 0.95;
  }
  
  // Step 4: Fetch regime-specific recommendations
  const recommendations = {
    crisis: { position_sizing: 0.5, require_confirmation: true },
    stressed: { position_sizing: 0.75, require_confirmation: false },
    collapsed: { position_sizing: 1.0, require_confirmation: false },
    normal: { position_sizing: 1.0, require_confirmation: false }
  };
  
  return {
    symbol,
    regime,
    confidence,
    spread_ratio: parseFloat(spread_ratio.toFixed(3)),
    baseline_spread: parseFloat(baseline_spread.toFixed(4)),
    current_spread: parseFloat(current_spread.toFixed(4)),
    recommendations: recommendations[regime],
    detected_at: new Date().toISOString()
  };
};

module.exports = { handler: detectLiquidityRegime };

Pattern 3: Private Data Integration

Blend TickDB data with proprietary internal datasets:

// functions/alpha_signal_composite.js

const buildAlphaComposite = (params, context) => {
  const { symbols, weights = {} } = params;
  
  // Default weights if not provided
  const default_weights = { momentum: 0.3, flow: 0.4, sentiment: 0.3 };
  const final_weights = { ...default_weights, ...weights };
  
  const signals = symbols.map(symbol => {
    // Fetch market data from TickDB
    const quote = context.tickdb.getQuote(symbol);
    const kline = context.tickdb.getKline(symbol, '1h', 24);
    
    // Fetch proprietary signals (from your internal database)
    const internal_signals = context.internal.getSignals(symbol);
    
    // Calculate momentum signal from price series
    const returns = kline.slice(-12).map(
      (k, i, arr) => i > 0 ? (k.close - arr[i-1].close) / arr[i-1].close : 0
    );
    const momentum = returns.reduce((sum, r) => sum + r, 0) / returns.length;
    
    // Calculate flow signal from order imbalance
    const recent_trades = context.tickdb.getTrades(symbol, 50);
    const flow_signal = recent_trades
      .filter(t => t.side === 'buy')
      .reduce((s, t) => s + t.size, 0) / 
      recent_trades.reduce((s, t) => s + t.size, 0);
    
    return {
      symbol,
      momentum: parseFloat(momentum.toFixed(6)),
      flow: parseFloat(flow_signal.toFixed(4)),
      sentiment: internal_signals.sentiment_score,
      composite: (
        momentum * final_weights.momentum +
        flow_signal * final_weights.flow +
        internal_signals.sentiment_score * final_weights.sentiment
      ),
      last_updated: quote.timestamp
    };
  });
  
  // Sort by composite signal strength
  signals.sort((a, b) => b.composite - a.composite);
  
  return {
    signals,
    timestamp: new Date().toISOString(),
    weights_applied: final_weights
  };
};

module.exports = { handler: buildAlphaComposite };

Note that context.internal is a custom integration point. Enterprise SKILLs can declare additional data sources in their manifest and receive them via context injection.

Private Deployment Strategies

Option 1: Self-Hosted SKILL Runtime

For teams with strict data residency requirements, the SKILL runtime can be deployed on-premises:

# docker-compose.yml for self-hosted SKILL runtime

version: '3.8'

services:
  skill-runtime:
    image: tickdb/skill-runtime:1.2.0
    container_name: enterprise-skill-runtime
    environment:
      - TICKDB_API_KEY=${TICKDB_API_KEY}
      - SKILL_CONFIG_PATH=/app/config/skill.json
      - LOG_LEVEL=info
      - METRICS_ENABLED=true
      - INTERNAL_DATA_ENDPOINT=${INTERNAL_DATA_ENDPOINT}
    volumes:
      - ./skills:/app/skills
      - ./config:/app/config
      - ./logs:/app/logs
    ports:
      - "8080:8080"
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 4G
        reservations:
          cpus: '0.5'
          memory: 1G

The self-hosted runtime provides:

  • Data residency: All function execution stays within your network boundary
  • Custom data source integration: Point to internal databases, proprietary feeds
  • Audit logging: Every function call is logged to your SIEM
  • Latency optimization: Co-locate with your trading infrastructure

Option 2: Cloud-Native Enterprise Deployment

For teams prioritizing scalability over data residency:

// enterprise-skill.config.js

module.exports = {
  runtime: {
    provider: 'aws',          // aws | gcp | azure
    region: 'us-east-1',
    instance_type: 'm5.xlarge',
    auto_scaling: {
      min: 2,
      max: 20,
      target_cpu_utilization: 70,
      scale_in_cooldown: 300,
      scale_out_cooldown: 60
    }
  },
  
  skills: {
    'tickdb-enterprise-skill': {
      version: '1.0.0',
      functions: [
        'get_realtime_quote',
        'query_historical',
        'calculate_position_size',
        'detect_liquidity_regime',
        'build_alpha_composite'
      ],
      rate_limit: {
        requests_per_minute: 1000,
        burst: 200
      }
    }
  },
  
  security: {
    authentication: {
      type: 'oauth2',
      provider: 'okta',
      audience: 'tickdb-enterprise'
    },
    encryption: {
      at_rest: true,
      in_transit: true,
      key_rotation_days: 90
    },
    audit: {
      enabled: true,
      sink: 'cloudwatch-logs',
      retention_days: 365
    }
  },
  
  monitoring: {
    datadog_integration: true,
    error_rate_threshold: 0.01,
    p99_latency_threshold_ms: 200
  }
};

Option 3: Hybrid Deployment

Many enterprise teams require a hybrid approach—low-latency functions co-located with trading systems, while batch processing runs in the cloud:

┌─────────────────────────────────────────────────────────────┐
│                    Enterprise Network                       │
│                                                             │
│   ┌─────────────────────┐      ┌─────────────────────────┐  │
│   │  Colocation Cluster  │      │     Cloud Environment    │  │
│   │                      │      │                         │  │
│   │  SKILL Runtime (HFT) │      │  SKILL Runtime (Batch)  │  │
│   │  - Real-time quotes  │      │  - Historical analysis  │  │
│   │  - Order routing     │      │  - Factor computation   │  │
│   │  - Risk management   │      │  - Backtesting          │  │
│   │                      │      │                         │  │
│   │  Latency: < 5ms      │      │  Latency: < 500ms       │  │
│   │  Data: Hot cache     │      │  Data: TickDB + S3      │  │
│   └─────────────────────┘      └─────────────────────────┘  │
│              │                         │                    │
│              └────────┬────────────────┘                    │
│                       ▼                                     │
│            ┌─────────────────────┐                          │
│            │  TickDB API (cloud)  │                          │
│            │  - Historical klines │                          │
│            │  - Symbol metadata   │                          │
│            │  - Rate limiting    │                          │
│            └─────────────────────┘                          │
└─────────────────────────────────────────────────────────────┘

Production Considerations

Error Handling and Resilience

Every production SKILL function must implement proper error handling:

// functions/get_realtime_quote_with_retry.js

const getRealtimeQuote = async (params, context) => {
  const { symbol, max_retries = 3 } = params;
  const { logger } = context;
  
  let last_error;
  
  for (let attempt = 0; attempt < max_retries; attempt++) {
    try {
      const quote = context.tickdb.getQuote(symbol);
      
      // Validate quote integrity
      if (!quote.price || !quote.timestamp) {
        throw new Error('INVALID_QUOTE: Missing required fields');
      }
      
      // Check data freshness (5 second threshold for real-time)
      const age_seconds = (Date.now() - quote.timestamp) / 1000;
      if (age_seconds > 5) {
        logger.warn(`Stale quote for ${symbol}: ${age_seconds.toFixed(1)}s old`);
      }
      
      return { success: true, data: quote };
      
    } catch (error) {
      last_error = error;
      logger.warn(
        `Attempt ${attempt + 1}/${max_retries} failed for ${symbol}: ${error.message}`
      );
      
      // Exponential backoff
      if (attempt < max_retries - 1) {
        const delay = Math.min(100 * Math.pow(2, attempt), 2000);
        await new Promise(resolve => setTimeout(resolve, delay));
      }
    }
  }
  
  logger.error(`All ${max_retries} attempts failed for ${symbol}: ${last_error.message}`);
  
  return {
    success: false,
    error: last_error.message,
    symbol,
    attempted_at: new Date().toISOString()
  };
};

module.exports = { handler: getRealtimeQuote };

Monitoring and Observability

Deploy SKILL functions with built-in telemetry:

// observability/metrics.js

const recordMetric = (function_name, duration_ms, status, context) => {
  const metrics = {
    function: function_name,
    duration_ms,
    status,
    timestamp: Date.now(),
    instance_id: context.instance_id,
    environment: context.environment
  };
  
  // Push to your metrics sink
  context.metrics.record(metrics);
  
  // Log for debugging
  context.logger.info(
    `${function_name} completed in ${duration_ms}ms with status ${status}`
  );
};

// Usage wrapper for any function
const withMetrics = (handler, function_name) => {
  return (params, context) => {
    const start = Date.now();
    try {
      const result = handler(params, context);
      recordMetric(function_name, Date.now() - start, 'success', context);
      return result;
    } catch (error) {
      recordMetric(function_name, Date.now() - start, 'error', context);
      throw error;
    }
  };
};

module.exports = { withMetrics };

Deployment Recommendations by Scale

Use case Recommended approach Key consideration
Individual quant researcher Standard TickDB API + publicly available SKILLs Start simple; extend when you hit a wall
Small team (2–5 quants) Cloud-hosted SKILL runtime with shared custom functions Collaborative versioning via Git
Growing desk (5–20 quants) Dedicated cloud deployment with isolated function namespaces Team-level rate limits, cost allocation
Enterprise (20+ quants) Hybrid deployment with HFT-optimized on-prem cluster Data residency, regulatory compliance
Multi-strategy fund Federated deployment with centralized SKILL registry Governance, audit trails

Next Steps

If you're an individual quant researcher looking to extend TickDB capabilities, start by reviewing the public SKILL registry at tickdb.ai/skills. Many common use cases are already implemented—only build custom functions when the standard capabilities do not fit your workflow.

If you're a small team building shared tooling, fork the enterprise SKILL template from our GitHub repository (tickdb/enterprise-skill-template) and begin adapting functions for your strategy logic. Use the development configuration (config/development.json) to test against real market data with sandbox credentials.

If you need enterprise-grade features—multi-region failover, custom rate limits, private data source integration, or on-premises deployment—reach out to enterprise@tickdb.ai. Our enterprise team provides white-glove onboarding, dedicated SLAs, and architecture review for high-throughput trading systems.

If you're an AI tooling developer, the SKILL protocol is designed to be AI-agent-native. Search for the tickdb-market-data SKILL in your AI tool's marketplace to get started with zero-configuration integration.


This article does not constitute investment advice. Market data APIs and custom trading tools involve risk; past performance does not guarantee future results. Enterprise deployments should be reviewed by qualified engineering and compliance teams before production use.