DEV Community

Cover image for Building Cryptographic Audit Trails for TradingView Strategies with VCP

Building Cryptographic Audit Trails for TradingView Strategies with VCP

"Verify, Don't Trust." — This principle drives the VeritasChain Protocol (VCP), an open standard for creating tamper-evident audit trails in algorithmic trading systems.

Today, I'm excited to announce the release of vcp-tradingview-rta-reference — a complete reference implementation demonstrating how to integrate VCP v1.1 with TradingView's Pine Script environment.

The Problem: Black Box Trading

When you run an algorithmic trading strategy, how do you prove:

  • What decisions your algorithm actually made?
  • That your trade logs haven't been modified after the fact?
  • That no events were deleted or inserted?

Traditional logging is insufficient. Logs can be edited, timestamps can be forged, and there's no cryptographic guarantee of integrity. This matters for:

  • Prop trading firms evaluating trader performance
  • Regulatory compliance (MiFID II, EU AI Act)
  • Dispute resolution between traders and brokers
  • Algorithm auditing and backtesting validation

The Solution: VCP's Three-Layer Architecture

VCP v1.1 implements a three-layer integrity architecture:

┌─────────────────────────────────────────────────┐
│  Layer 3: External Verifiability                │
│  ├─ OpenTimestamps / Bitcoin anchoring          │
│  └─ RFC 3161 Timestamp Authority                │
├─────────────────────────────────────────────────┤
│  Layer 2: Collection Integrity                  │
│  ├─ RFC 6962 Merkle Tree                        │
│  └─ Append-only log structure                   │
├─────────────────────────────────────────────────┤
│  Layer 1: Event Integrity                       │
│  ├─ SHA-256 content hash                        │
│  ├─ Ed25519 digital signature                   │
│  └─ RFC 8785 canonical JSON (JCS)               │
└─────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Each layer provides specific guarantees:

  1. Event Integrity: Individual events cannot be modified without detection
  2. Collection Integrity: Events cannot be deleted or reordered
  3. External Verifiability: Timestamps are anchored to external systems (Bitcoin, TSA)

Architecture: The Sidecar Pattern

Since TradingView runs in a sandboxed environment, we use a sidecar architecture:

┌─────────────────────────────────────────────────────────────────┐
│  TradingView                                                    │
│  ┌──────────────────────────────────────────────────────┐       │
│  │  Pine Script Strategy (vcp_silver_strategy.pine)     │       │
│  │  - Event capture (Entry/Exit/Position Change)        │       │
│  │  - VCP-compliant JSON payload generation             │       │
│  └──────────────────────┬───────────────────────────────┘       │
└─────────────────────────┼───────────────────────────────────────┘
                          │ Webhook (HTTPS POST)
                          ▼
┌─────────────────────────────────────────────────────────────────┐
│  VCP Sidecar (Python FastAPI)                                   │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐  ┌─────────┐ │
│  │ Webhook     │→ │ Canonical   │→ │ Merkle Tree │→ │ Anchor  │ │
│  │ Receiver    │  │ Transform   │  │ Builder     │  │ Service │ │
│  └─────────────┘  └─────────────┘  └─────────────┘  └─────────┘ │
│        │                                                        │
│        ▼                                                        │
│  ┌─────────────┐                                                │
│  │ Ed25519     │                                                │
│  │ Signature   │                                                │
│  └─────────────┘                                                │
└─────────────────────────────────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

Implementation Deep Dive

1. Pine Script: Generating VCP Events

The Pine Script strategy captures trading events and formats them as VCP-compliant JSON:

//@version=5
strategy("VCP Silver Tier Strategy", overlay=true)

// VCP Configuration
vcpEnabled = input.bool(true, "Enable VCP Logging")
vcpSystemId = input.string("TV-STRATEGY-001", "System ID")
vcpAccountId = input.string("DEMO-ACCOUNT", "Account ID")

// Generate VCP event payload
vcpOrderNewPayload(orderId, side, qty, price) =>
    str.format(
        '{{' +
        '"vcp_version":"1.1",' +
        '"event_id":"{0}",' +
        '"timestamp":"{1}",' +
        '"event_type":"ORDER_NEW",' +
        '"tier":"SILVER",' +
        '"policy_id":"urn:vso:policy:tv-retail:v1",' +
        '"clock_sync":"BEST_EFFORT",' +
        '"system_id":"{2}",' +
        '"account_id":"{3}",' +
        '"payload":{{' +
            '"order_id":"{4}",' +
            '"symbol":"{5}",' +
            '"side":"{6}",' +
            '"quantity":{7},' +
            '"price":{8}' +
        '}}' +
        '}}',
        vcpEventId(), vcpTimestamp(),
        vcpSystemId, vcpAccountId,
        orderId, syminfo.tickerid, side, qty, price)

// Send via webhook on entry
if longCondition
    alert(vcpOrderNewPayload("ORD-001", "BUY", 1.0, close), 
          alert.freq_once_per_bar)
Enter fullscreen mode Exit fullscreen mode

2. Python Sidecar: Canonical Transformation

The sidecar receives webhooks and applies RFC 8785 canonical JSON transformation:

@dataclass
class VCPEvent:
    event_id: str
    timestamp: str
    event_type: str
    tier: str
    policy_id: str
    clock_sync: str
    system_id: str
    account_id: str
    payload: Dict[str, Any]
    vcp_version: str = "1.1"

    def to_canonical_json(self) -> str:
        """RFC 8785 (JCS) canonical JSON serialization."""
        canonical = {
            "account_id": self.account_id,
            "clock_sync": self.clock_sync,
            "event_id": self.event_id,
            "event_type": self.event_type,
            "payload": self._sort_dict(self.payload),
            "policy_id": self.policy_id,
            "system_id": self.system_id,
            "tier": self.tier,
            "timestamp": self.timestamp,
            "vcp_version": self.vcp_version,
        }
        return json.dumps(canonical, sort_keys=True, 
                         separators=(',', ':'), ensure_ascii=True)
Enter fullscreen mode Exit fullscreen mode

Why canonical JSON? Because the same data must always produce the same hash. Without canonicalization, {"a":1,"b":2} and {"b":2,"a":1} would produce different hashes despite being semantically identical.

3. Ed25519 Signing

We use Ed25519 for digital signatures — it's fast, secure, and produces compact 64-byte signatures:

from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey

class VCPSigner:
    def __init__(self, private_key: Ed25519PrivateKey):
        self._private_key = private_key

    def sign(self, message: bytes) -> bytes:
        """Sign message with Ed25519."""
        return self._private_key.sign(message)

    def verify(self, message: bytes, signature: bytes) -> bool:
        """Verify Ed25519 signature."""
        try:
            self._private_key.public_key().verify(signature, message)
            return True
        except Exception:
            return False
Enter fullscreen mode Exit fullscreen mode

4. RFC 6962 Merkle Tree

The Merkle tree provides collection integrity with efficient inclusion proofs:

class MerkleTree:
    LEAF_PREFIX = b'\x00'      # Domain separation
    INTERNAL_PREFIX = b'\x01'

    def _leaf_hash(self, data: bytes) -> bytes:
        """RFC 6962: H(0x00 || data)"""
        return hashlib.sha256(self.LEAF_PREFIX + data).digest()

    def _internal_hash(self, left: bytes, right: bytes) -> bytes:
        """RFC 6962: H(0x01 || left || right)"""
        return hashlib.sha256(self.INTERNAL_PREFIX + left + right).digest()

    def add_leaf(self, data_hash: bytes) -> int:
        """Add leaf and return index."""
        leaf_hash = self._leaf_hash(data_hash)
        self._leaves.append(leaf_hash)
        return len(self._leaves) - 1

    @classmethod
    def verify_proof(cls, data_hash: bytes, proof: List[Tuple[str, bytes]], 
                     expected_root: bytes) -> bool:
        """Verify Merkle inclusion proof."""
        current = hashlib.sha256(cls.LEAF_PREFIX + data_hash).digest()

        for position, sibling_hash in proof:
            if position == 'left':
                current = hashlib.sha256(
                    cls.INTERNAL_PREFIX + sibling_hash + current).digest()
            else:
                current = hashlib.sha256(
                    cls.INTERNAL_PREFIX + current + sibling_hash).digest()

        return current == expected_root
Enter fullscreen mode Exit fullscreen mode

The domain separation prefixes (0x00 for leaves, 0x01 for internal nodes) prevent second-preimage attacks.

5. FastAPI Webhook Endpoint

The sidecar exposes a simple REST API:

@app.post("/vcp/event")
async def receive_event(webhook: TradingViewWebhook):
    # 1. Create VCP event
    vcp_event = VCPEvent(
        event_id=webhook.event_id,
        timestamp=webhook.timestamp,
        event_type=webhook.event_type,
        # ... other fields
    )

    # 2. Canonical transformation and hash
    canonical_json = vcp_event.to_canonical_json()
    event_hash = hashlib.sha256(canonical_json.encode()).digest()

    # 3. Sign
    signature = signer.sign(event_hash)

    # 4. Add to Merkle tree
    merkle_index = merkle_tree.add_leaf(event_hash)

    return {
        "event_id": webhook.event_id,
        "event_hash": event_hash.hex(),
        "signature": signature.hex(),
        "merkle_index": merkle_index
    }
Enter fullscreen mode Exit fullscreen mode

Tamper Detection in Action

The beauty of VCP is that any tampering is immediately detectable. Here's a test from our verification suite:

def test_modification_detection():
    """Modify an event and verify detection."""
    # Load events
    events = load_events("vcp_tv_events.jsonl")

    # Tamper with event #5
    events[5]["payload"]["quantity"] = 999  # Changed!

    # Verify
    for event in events:
        computed_hash = compute_hash(event)
        stored_hash = event["event_hash"]

        if computed_hash != stored_hash:
            print(f"[DETECTED] Tampering at {event['event_id']}")
            # Hash mismatch proves modification!
Enter fullscreen mode Exit fullscreen mode

Output:

[DETECTED] Event TV-20250115102500-0005: Hash mismatch
           Computed: c44fcae94fa8cde0fd15df90e43e5d7b...
           Stored:   71619cea5031b6aab37e704db7411324...
Enter fullscreen mode Exit fullscreen mode

Quick Start

# Clone
git clone https://github.com/veritaschain/vcp-tradingview-rta-reference.git
cd vcp-tradingview-rta-reference

# Install
pip install -r requirements.txt

# Generate keys
python -m sidecar.keygen

# Run server
python -m sidecar.main

# Verify evidence pack
python tools/verifier/vcp_verifier.py \
    evidence/01_trade_logs/vcp_tv_events.jsonl \
    -s evidence/04_anchor/security_object.json
Enter fullscreen mode Exit fullscreen mode

VCP Compliance Tiers

VCP defines three compliance tiers for different use cases:

Tier Clock Sync Anchor Interval Use Case
Silver Best-effort 24 hours Retail, MT4/MT5, TradingView
Gold NTP synced 1 hour Prop firms, institutions
Platinum PTP locked 10 minutes HFT, exchanges

This reference implementation targets Silver Tier, making it accessible to individual traders while still providing cryptographic guarantees.

What's Next?

This is just the beginning. The VCP ecosystem is expanding:

  • VCP Explorer: Web-based verification tool
  • MT4/MT5 Bridge: Native MQL integration
  • FIX Protocol Sidecar: Institutional trading support
  • IETF Standardization: draft-kamimura-scitt-vcp

Get Involved

VCP is developed by the VeritasChain Standards Organization (VSO), a vendor-neutral standards body.

We welcome contributions, feedback, and early adopter partnerships.


"AI needs a Flight Recorder." — The algorithmic trading industry is changing. Cryptographic audit trails aren't just nice-to-have; they're becoming essential for compliance, trust, and accountability. VCP provides the open standard to make this a reality.

Star the repo if you find this useful!


Tags: #opensource #python #trading #cryptography #fintech #audit #compliance

Top comments (0)