Quasar-Executo / DEPLOYMENT_GUIDE.md
KarlQuant's picture
Upload 13 files
e5b81b3 verified

QUASAR System β€” Deployment Guide

v2.0 Architecture-Strict | 2026-03-25


Overview

The refactored system enforces a strict one-way data pipeline:

Asset Spaces (V75, V100_1s, Crash500)
        β”‚  WebSocket PUBLISH  (send-only)
        β–Ό
Central WebSocket Hub   ←── ingest, normalize, broadcast
        β”‚  WebSocket SUBSCRIBE  (read-only)
        β–Ό
Ranker Space (Quasar_axrvi_ranker.py)
        β”‚  REST / Dashboard outputs
        β–Ό
  Rankings  β€’  REST API  β€’  Dashboard

No feedback loop exists. The Ranker never writes back to the Hub or Asset Spaces.


File Reference

File Role Deploy As
websocket_hub.py Central Hub β€” ingest, normalize, broadcast Standalone FastAPI service
websocket_client.py Publisher β€” Asset Space send-only client Imported in each Asset Space
Quasar_axrvi_ranker.py Ranker Space β€” subscriber + neural ranker + trading Standalone process

1. Requirements

pip install fastapi uvicorn websockets websocket-client torch numpy pydantic

For Hugging Face Spaces, add to requirements.txt:

fastapi
uvicorn[standard]
websockets
websocket-client
torch
numpy
pydantic
nest_asyncio

2. Deploy the Central Hub

# Local
python websocket_hub.py

# With explicit port
PORT=7860 python websocket_hub.py

# Production (Hugging Face Space)
# Set Space SDK to "Docker" or use app.py entry with:
uvicorn websocket_hub:app --host 0.0.0.0 --port 7860

Hub endpoints:

Endpoint Protocol Role
/ws/publish/{space_name} WebSocket Publisher (Asset Spaces connect here)
/ws/subscribe WebSocket Subscriber (Ranker connects here)
/rankings GET Latest snapshots for all assets
/metrics/{space_name} GET Single-asset snapshot
/health GET Hub health and connection stats

3. Integrate the Publisher into an Asset Space

Each asset space (V75, V100_1s, Crash500) imports AssetSpacePublisher:

from websocket_client import AssetSpacePublisher, TrainingMetrics, VotingMetrics

# ── Create and start (once, at startup) ──────────────────────────────────────
publisher = AssetSpacePublisher(
    space_name = "V75",
    hub_url    = "ws://your-hub-host:7860/ws/publish/V75",
)
publisher.start()

# ── In your training loop ──────────────────────────────────────────────────
# After each training update:
publisher.publish_training(TrainingMetrics(
    training_steps = step,
    actor_loss     = actor_loss,
    critic_loss    = critic_loss,
    avn_loss       = avn_loss,
    avn_accuracy   = avn_accuracy,
))

# After each agent vote:
publisher.publish_voting(VotingMetrics(
    dominant_signal = "BUY",   # "BUY" | "SELL" | "NEUTRAL"
    buy_count       = 7,
    sell_count      = 3,
))

# Or publish both together (preferred β€” fewer messages):
publisher.publish_combined(
    training = TrainingMetrics(...),
    voting   = VotingMetrics(...),
)

Reminder: The publisher is send-only. Any unexpected message from the hub is logged as a warning and discarded. No callbacks are invoked.


4. Deploy the Ranker Space

# Point at your hub's subscribe endpoint
python Quasar_axrvi_ranker.py \
    --hub   ws://your-hub-host:7860/ws/subscribe \
    --assets V75 V100_1s CRASH1000 \
    --bandit ucb \
    --reward simple \
    --model  deriv_axrvi_model.pt

# Sync/thread mode (e.g., inside a Jupyter notebook or larger process)
python Quasar_axrvi_ranker.py --sync --hub ws://...

# Component tests (no network required)
python Quasar_axrvi_ranker.py --test

5. Ranking Formula

signal_confidence = max(buy_count, sell_count) / (buy_count + sell_count)
score             = signal_confidence - avn_accuracy
Scenario Result
High confidence (0.9) + high accuracy (0.8) score = +0.10 β†’ good
High confidence (0.9) + low accuracy (0.3) score = +0.60 β†’ penalized (large gap)
Low confidence (0.5) + any accuracy score ≀ 0.0 β†’ weak

Assets are sorted by score in ascending order (smallest = most balanced = best).


6. Strict Data Schema

The hub enforces and broadcasts only these fields:

training:
  training_steps  (int)
  actor_loss      (float)
  critic_loss     (float)
  avn_loss        (float)
  avn_accuracy    (float, clamped [0,1])

voting:
  dominant_signal  ("BUY" | "SELL" | "NEUTRAL")
  buy_count        (int)
  sell_count       (int)

The following fields are explicitly stripped at the hub ingestion layer and will never reach the Ranker:

  • ❌ rewards (matched, unmatched, duplicates, match_rate)
  • ❌ resource metrics (cpu_percent, memory_percent, memory_used_gb, quasar_memory_gb)
  • ❌ agent-level metrics (q_buy, q_sell, entropy, per-agent data)
  • ❌ buffer_size
  • ❌ any q-values or internal model outputs

7. Hugging Face Spaces Deployment

Hub Space (quasar-hub)

app.py:

from websocket_hub import app  # FastAPI app, ready for uvicorn

README.md front-matter: ```yaml

sdk: docker app_port: 7860


### Asset Space (e.g., `quasar-v75`)

In your existing Space's training entry point:
```python
from websocket_client import AssetSpacePublisher, TrainingMetrics, VotingMetrics
import os

HUB_URL = os.environ.get("HUB_WS_URL", "wss://your-hub-space.hf.space/ws/publish/V75")
publisher = AssetSpacePublisher("V75", HUB_URL)
publisher.start()

Set the environment variable HUB_WS_URL in each Space's settings.

Ranker Space (quasar-ranker)

# main.py (entry point)
import asyncio, os
from Quasar_axrvi_ranker import run_live_trading_system

HUB_SUB = os.environ.get("HUB_SUB_URL", "wss://your-hub-space.hf.space/ws/subscribe")

asyncio.run(run_live_trading_system(
    asset_symbols   = ["V75", "V100_1s", "CRASH1000"],
    hub_ws_url      = HUB_SUB,
))

8. Architecture Constraints (enforced in code)

Constraint Where enforced
Publishers cannot receive data _on_message in AssetSpacePublisher discards all inbound messages
Hub never writes to publishers Publisher WebSocket endpoint is receive-only; no sends
Subscribers are read-only Subscriber endpoint drains inbound messages without processing
No feedback loop HubSubscriber has no send methods
Minimal schema Hub _validate_and_normalize() strips all non-permitted fields
Thread-safe All shared state protected by asyncio.Lock (hub) / threading.Lock (client, ranker)

9. Environment Variables

Variable Used By Description
DERIV_API_KEY Ranker Deriv API key for live trading
PORT Hub FastAPI server port (default 7860)
HUB_WS_URL Asset Spaces Publisher WebSocket URL
HUB_SUB_URL Ranker Subscriber WebSocket URL

10. Quick Smoke Test

# Terminal 1 β€” start hub
python websocket_hub.py

# Terminal 2 β€” ranker tests (no network)
python Quasar_axrvi_ranker.py --test

# Terminal 3 β€” simulate a publisher
python - <<'EOF'
from websocket_client import AssetSpacePublisher, TrainingMetrics, VotingMetrics
import time

pub = AssetSpacePublisher("V75_TEST", "ws://localhost:7860/ws/publish/V75_TEST")
pub.start()
time.sleep(1)
for step in range(10):
    pub.publish_combined(
        TrainingMetrics(training_steps=step*100, avn_accuracy=0.5+step*0.04),
        VotingMetrics(dominant_signal="BUY", buy_count=7, sell_count=3),
    )
    time.sleep(0.5)
print("Done. Check /rankings endpoint.")
EOF

# Terminal 4 β€” verify hub received data
curl http://localhost:7860/rankings | python -m json.tool

End of deployment guide.