System Architecture
OTM-Agent wraps a three-stage operational pipeline with an LLM-orchestrated agent layer comprising a planner, executor, four-tier memory, Bayesian persona vectors, and multi-objective reward.
High-Level Data Flow
┌──────────────────────────────────────────────────────────────────────┐
│ OTM Production Pipeline │
│ Stage 1 (SAR → Hub State) · Stage 2 (Features + ML Models) │
│ Stage 3 (Signals + Paper Trading) · BigQuery │
│ Runs daily on Cloud Run, scheduled at 02:00 / 03:00 / 04:00 UTC │
└────────────────────────────────┬─────────────────────────────────────┘
│
┌──────────────┴──────────────┐
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ OTM-Agent API │ │ Dashboard API │
│ (Cloud Run Service) │ │ otm-api-dev │
│ Planner + Executor │ │ Live SAR data │
└──────────┬──────────┘ └─────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────┐ ┌──────────┐ ┌──────────┐
│ Memory │ │ Persona │ │ Reward │
│ 4-tier │ │ 64-d │ │ Multi- │
│ System │ │ Bayesian │ │ objective│
└─────────┘ └──────────┘ └──────────┘
Base Pipeline: Three Stages
Stage 1: SAR Processing & State Estimation
Raw Sentinel-1 SAR observations are processed through confidence scoring (quality weights based on acquisition geometry, weather, temporal recency), z-score normalization, and Kalman filtering to produce daily hub-state estimates — a tightness index (0 = empty, 1 = full) with associated uncertainty.
Observations
5,124
Sentinel-1 SAR for Cushing
Hub-State Days
309
daily estimates produced
Kalman Convergence
0.066→0.045
variance reduction
Stage 2: Feature Engineering & ML Models
Market data (WTI prices, calendar spreads, COT positions, EIA releases) is joined with Stage 1 hub-state output to produce linkage features. Three LightGBM classifiers consume these features:
| Model | Accuracy | Baseline | Δ | Top Feature |
| Regime Classifier | 65.35% | 52.9% | +12.4 pp | tightness_mean |
| Spread Forecaster | 51.4% | 50.0% | +1.4 pp | wti_settle |
| EIA Surprise | 51.5% | 50.0% | +1.5 pp | tightness_mean |
Stage 3: Signal Generation & Governance
A signal generator combines model outputs into daily composite trading signals (long/short/flat) with confidence. A paper trading module executes simulated trades, and a governance scorecard tracks prediction accuracy.
Agent Layer
┌──────────────────────────────────────────────────────┐
│ OTM-Agent │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │ Planner │ → │ Executor │ → │ Reward / Eval │ │
│ │ (LLM) │ │ (Skills) │ │ (Multi-obj.) │ │
│ └────┬─────┘ └──────────┘ └───────────────┘ │
│ │ ↑ │
│ ┌────▼─────┐ ┌────┴─────┐ │
│ │ Memory │ │ Persona │ │
│ │ (4-tier) │ │ (64-d) │ │
│ └──────────┘ └──────────┘ │
└───────────────────────────────────────────────────────┘
Turn Flow
A single agent turn proceeds through 9 steps:
- Context assembly — populate WorkingMemory with query + context
- Persona retrieval — load 64-d persona vector for current user
- State signature — MD5 hash of regime × volatility × persona mode
- Memory retrieval — 3 episodic + 5 semantic + 2 procedural sequences
- Plan generation — LLM produces structured JSON plan (goal, rationale, skill steps)
- Plan validation — skill registry checks preconditions, costs, DAG constraints
- Execution — dispatch skills, track effects, replan on failure (up to 3 replans)
- Response generation — synthesize natural-language response from skill outputs
- Memory persistence — record episodic entry, extract semantic facts, update persona
Skill Library — 20 Skills, 7 Categories
BigQuery Queries (6)
sense_tank_state
Current tank state from SAR observations
BigQuery Queries
fetch_tank_history
Historical tank observations over time window
BigQuery Queries
fetch_region_signal
Regional aggregate signal for a hub
BigQuery Queries
fetch_trade_log
Paper trading execution log
BigQuery Queries
fetch_tightness
Hub tightness index from Kalman filter
BigQuery Queries
fetch_market_data
WTI prices, spreads, COT positions
Compute / Analytics (5)
compute_fill_signal
Fill level from radar backscatter
Compute / Analytics
compute_tightness
Hub tightness from tank-level data
Compute / Analytics
compute_zscore
Z-score normalization of signal
Compute / Analytics
compute_delta
Day-over-day delta computation
Compute / Analytics
compute_goii
Global Oil Inventory Index
ML Models (3)
predict_regime
Contango vs backwardation classification
ML Models
predict_spread_direction
Next-period spread movement direction
ML Models
predict_eia_surprise
EIA inventory report direction/magnitude
Cloud Run Jobs (2)
trigger_sar_pipeline
Trigger Stage 1 SAR processing
Cloud Run Jobs
trigger_market_ingest
Trigger Stage 2 market data ingest
LLM Reasoning (2)
explain_market_state
Natural language market interpretation
LLM Reasoning
summarize_episode
Summarize a completed episode for memory
Trade Operations (1)
place_paper_trade
Execute paper trade with position sizing
Alerts (1)
alert_on_threshold
Anomaly detection and notification
Skill Contract Example
{
"name": "predict_regime",
"category": "ML Models",
"preconditions": ["linkage_features_available"],
"effects": ["regime_prediction_available"],
"failure_modes": ["insufficient_data", "model_load_error"],
"avg_latency_ms": 850,
"avg_cost_usd": 0.001,
"retention_probes": [
"What regime did the model predict?",
"What was the classification confidence?",
"Which feature contributed most?"
]
}
Four-Tier Memory System
| Tier | Stores | Retrieval | Lifetime |
| Working | Current turn state, intermediate outputs | Direct access | Single turn |
| Episodic | Complete turn records (query, plan, results, reward) | Top-3 by embedding similarity | Persistent (BigQuery) |
| Semantic | Domain facts with support/contradiction counts | Top-5 by relevance | Persistent (BigQuery) |
| Procedural | Skill sequences indexed by state signature | Top-2 by reward for current state | Persistent (BigQuery) |
State signatures are 8-character MD5 hashes of (regime × volatility × persona mode), enabling transfer across sessions with comparable market conditions.
Persona Module — 64-Dimensional Bayesian Vectors
Each analyst's preferences are represented as a 64-dimensional vector maintained as a Bayesian posterior (mean + 64×64 covariance). Two anchor directions define the primary axis:
| Mode | Bias Toward | Example Skills |
| Execution | Action-oriented | fetch_tank_features, compose_signal, place_paper_trade |
| Analysis | Investigation-oriented | compare_to_history, explain_decision, predict_regime |
After each interaction, the persona vector is updated via Kalman-style Bayesian inference. Over multiple turns, the covariance shrinks and behavior becomes increasingly specialized for the individual analyst.
Infrastructure
| Resource | Value |
| GCP Project | oil-tank-monitoring-123 |
| Region | northamerica-northeast1 |
| Cloud Run Jobs | 7 (daily SAR, SAR download, backfill, Stage 1–3) |
| Cloud Run Services | 3 (Dashboard API, Signal API, GOII API) |
| BigQuery Tables | 31 across 6 datasets |
| GCS Buckets | 5 (raw, processed, curated, model, downloads) |
| Schedulers | 3 daily triggers (02:00, 03:00, 04:00 UTC) |