I inherited my own mess once — Pine PnL saying one thing, Python saying another, both "right" under different assumptions. Wasted a weekend. Never again.
### Contract
1. Pine emits **event rows**, not philosophy: `timestamp_et, ticker, signal_id, side, price_ref, extras...`
2. Python owns joins to trades/fills, costs, stats, review plots.
### Pine side discipline
One `signal_id` vocabulary in a comment header. Alert JSON stable — version it (`schema_v1`). Don't recompute strategy PnL in both places with different assumptions. Pick a ledger.
### Example alert payload sketch
Code: Select all
{
"schema": "schema_v1",
"ts": "{{timenow}}",
"ticker": "{{ticker}}",
"signal_id": "OR_BREAK_LONG",
"side": "buy",
"price_ref": "{{close}}",
"or_high": 12.34,
"or_low": 11.90
}
Code: Select all
raw alerts → validate schema → dedupe →
simulate fills with delay/slip model →
store parquet → notebook metrics
Schema version bump when fields change. Golden-file test: 10 known alerts → known rows. Timezone documented once (ET) — stop mixing UTC silently. That last one has bitten me more than I want to admit.
If you can't explain the handoff in one paragraph, the pipeline is already rotting.
What's your alert transport — TradingView webhooks, email bridge, something else?
Schema versioning: do you bump, or overwrite and hope?
Anyone keep golden-file tests for alerts? Worth it after the first silent break?
Where do you apply slip — Pine assumptions, or only in Python?