信号 API

在自己的程序里接收策略信号:用 REST 接口拉取,或由 Webhook 推送。

1. 准备

  1. 购买 SOXL 策略即可开通 API。
  2. 在我的账户里生成 API Key。Key 只显示一次,丢了就重新生成(旧的立刻作废)。
  3. 可选:填写 Webhook URL(必须 https、公网地址),保存时会给出签名密钥。

2. 信号什么时候产生

每个交易日美东约 16:45 收盘后计算一次。开仓、平仓指令都在下一交易日执行(或在 effective_date 当天执行),所以有一整晚时间准备。

3. 拉取(REST)

基础地址: https://api.qqqwatcher.com/api/v1 · 认证: X-API-Key: qw_… · 限流 120 次 / 10 分钟

接口说明
GET /me当前 Key 有哪些策略权益
GET /signals?strategy=soxl&since_id=0&limit=100按 id 升序返回 id > since_id 的信号;把返回的 next_since_id 存下来,下次接着拉
GET /positions?strategy=soxl信号簿当前持仓(含待开仓)
curl -H "X-API-Key: qw_your_key" "https://api.qqqwatcher.com/api/v1/signals?strategy=all&since_id=0"

4. 信号格式

{
  "id": 42,
  "strategy": "soxl_signal",
  "kind": "entry",                      // entry | fill | exit | closed | notice
  "symbol": "SOXL",
  "side": "long",                       // long | short
  "action": "buy_at_open",              // buy_at_open | sell_at_close | entered | exited
  "effective_date": "2026-10-15",       // the session the instruction applies to
  "price": null,                        // fill/closed: actual price used
  "created_at": "2026-10-14T20:46:03Z",
  "details": {
    "signal_date": "2026-10-14", "planned_exit_date": "2026-10-22",
    "stop_loss": null, "take_profit": null
  }
}

5. Webhook 推送

每条信号一个 POST,JSON 正文 {"type":"signal","attempt":1,"signal":{…}}。返回 2xx 视为送达;否则按 1 / 5 / 30 / 120 / 360 分钟重试,共 6 次。同一条信号可能送达不止一次,请按 signal.id 去重。

签名头: X-QW-Signature: t=<unix>,v1=<hex>,v1 = HMAC-SHA256(secret, t + "." + raw_body)。请校验签名并拒绝 5 分钟以前的 t。

// Node.js (Express)
const crypto = require('crypto');
app.post('/qw', express.raw({ type: 'application/json' }), (req, res) => {
  const [t, v1] = req.get('X-QW-Signature').split(',').map(x => x.split('=')[1]);
  const mac = crypto.createHmac('sha256', process.env.QW_SECRET).update(t + '.' + req.body).digest('hex');
  if (mac !== v1 || Date.now() / 1000 - t > 300) return res.sendStatus(400);
  const { signal } = JSON.parse(req.body);
  // ... place your order
  res.sendStatus(200);
});
# Python (Flask)
import hmac, hashlib, time, json
@app.post("/qw")
def qw():
    t, v1 = [x.split("=")[1] for x in request.headers["X-QW-Signature"].split(",")]
    mac = hmac.new(SECRET.encode(), (t + ".").encode() + request.get_data(), hashlib.sha256).hexdigest()
    if not hmac.compare_digest(mac, v1) or time.time() - int(t) > 300:
        return "", 400
    signal = json.loads(request.get_data())["signal"]
    return "", 200

仅为规则输出,不构成投资建议。过往表现(无论实盘或模拟)不代表未来。