SigmaLens

← Briefing

A component, not a destination

A desk that already has an order management system will not keep its positions in a second place, and will not open a second screen to see them. So the scoring is available as something your own systems call, and the signals are available as something that arrives where your team already reads. Nothing here requires anyone to visit this site.

Score a book we do not hold

POST/v1/score

Send the positions on the request. We score them and return them. No holding, weight or label from this call is written to our database, so there is nothing to keep in sync and nothing to delete afterwards. The response says "stored": false because that is the first question a fund asks.

curl -sX POST https://sigmalens.co.uk/v1/score \
  -H "X-API-Key: $SIGMALENS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "holdings": [
          {"ticker": "LMT",  "weight": 12.5},
          {"ticker": "SHEL", "weight": 9.0},
          {"ticker": "TSM",  "weight": 7.25}
        ],
        "include_drivers": true
      }'

Each holding comes back with a signed sentiment on a −10 to +10 scale, the exposures it came through, its coverage state, and - when include_drivers is true - the events behind the number, each carrying the reason it counts as that company's news rather than a story it merely appears in.

Have the signals come to you

POSTyour endpoint

Set alert_webhook_url in settings and material signals are delivered there: a Slack or Teams incoming webhook, a queue, or your own service. Digest mode sends once a day on a fixed schedule whether or not anything breached, which is deliberate - the timing is a publication schedule, not a reaction to your positions.

Every delivery is signed. The headers carry a timestamp and an HMAC-SHA256 over timestamp + "." + body using the secret you set, so your receiver can tell our POST from anyone else's POST to the same address, and can spot a replay.

X-SigmaLens-Timestamp: 1786800000
X-SigmaLens-Signature: 9f2c...  # hex HMAC-SHA256

# verifying, in Python
expected = hmac.new(secret.encode(),
                    timestamp.encode() + b"." + raw_body,
                    hashlib.sha256).hexdigest()
hmac.compare_digest(expected, received_signature)

We deliver only to public https addresses, and we do not follow redirects. An address that resolves inside a private network is refused when you save it and again before each send, because the name can change in between.

Before you rely on it

The record is published as unproven, and the number is on the site. The historical test and the live record are reported separately and are never blended, because they are two different claims: one asks how the engine would have called documented past episodes, the other how it has actually called them since launch. Split the history in half and most of the edge sits in the later years, which is the number we would leave out if we were selling you something. See the record and the method.