关于 kalshi-api
kalshi-api 是一项 Kalshi 交易 API 的集成指南,面向需要通过 REST 或 WebSocket 读取市场数据、管理订单的开发者。它重点说明 RSA-PSS 请求认证、YES/NO 订单簿解释及美元字符串订单格式等容易出错的细节。
主要功能
- 01说明 RSA-PSS 请求签名
- 02覆盖账户、订单和市场端点
- 03解释 YES/NO 买盘与报价换算
- 04详述订单字段及格式要求
- 05提供订单簿辅助脚本
适用场景
- 01实现 Kalshi API 请求认证
- 02读取市场数据和历史蜡烛图
- 03提交、修改、撤销或批量处理订单
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ agiprolabs/ claude-trading-skills --skill kalshi-api安装后在 Claude Code 中输入/kalshi-api确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/auth-and-orders.mdendpoints-and-marketdata.mdwebsocket.mdscripts/kalshi_orderbook.py详细介绍
Kalshi API
受 CFTC 监管的美国事件交易所。以 USD 计价的二元合约结算金额为 $1.00(YES 获胜)或 $0.00(NO 获胜)。提供 REST + WebSocket,每次请求均使用 RSA-PSS 身份验证。
有关合约语义和结算规则,请参阅 kalshi-weather-markets 和 kalshi-crypto-index-markets 技能。有关策略、仓位规模和回测,请参阅 prediction-market-strategy。
编码前务必验证。 Kalshi API 曾破坏向后兼容性:主机发生过变更(旧的
trading-api.kalshi.com已失效),订单架构也发生过变更(整数美分 → 美元字符串)。发布前,务必针对实时响应进行签名和订单请求体的冒烟测试。权威来源:
- API 参考文档:https://docs.kalshi.com(旧版镜像:https://trading-api.readme.io)
- 官方 Python 入门代码:https://github.com/Kalshi/kalshi-starter-code-python
概览
- 基础 URL:
https://api.elections.kalshi.com/trade-api/v2 - 身份验证: 每次请求均使用 RSA-PSS — 没有公开/无需身份验证的端点
- 演示环境不等同于正式环境: 演示环境(
demo-api.kalshi.co)的订单簿几乎为空;即使是只读拉取,也请使用正式环境 - 合约: 每份合约 $0.01–$0.99;YES 获胜时支付价格,NO 获胜时损失价格;最高赔付 = $1.00
快速入门
1. 凭据
KALSHI_KEY_ID=<your-key-uuid>
KALSHI_PRIVATE_KEY_PATH=~/.kalshi/private.pem
在 Kalshi 控制面板中生成密钥。将机密存储在环境变量或机密管理器中 — 切勿写入代码。
2. 安装
pip install httpx cryptography
3. 主机 + 身份验证(最容易出错的部分)
主机和签名格式是实现出错的主要原因。三种常见错误:
- 使用旧的
trading-api.kalshi.com主机 → 401 - 在签名路径中包含查询字符串 → 401
- 使用秒而不是毫秒进行签名 → 401
import os, time, base64, httpx
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
BASE = "https://api.elections.kalshi.com/trade-api/v2"
KEY_ID = os.environ["KALSHI_KEY_ID"]
with open(os.environ["KALSHI_PRIVATE_KEY_PATH"], "rb") as f:
PRIV = serialization.load_pem_private_key(f.read(), password=None)
def _headers(method: str, path: str) -> dict:
"""path must include /trade-api/v2 prefix and exclude query string."""
ts = str(int(time.time() * 1000)) # milliseconds
msg = f"{ts}{method}{path}".encode()
sig = PRIV.sign(
msg,
padding.PSS(mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.DIGEST_LENGTH),
hashes.SHA256(),
)
return {
"KALSHI-ACCESS-KEY": KEY_ID,
"KALSHI-ACCESS-TIMESTAMP": ts,
"KALSHI-ACCESS-SIGNATURE": base64.b64encode(sig).decode(),
}
def get(path: str, params=None):
# Sign the path only — query goes into params, not the signature
r = httpx.get(BASE + path, params=params,
headers=_headers("GET", "/trade-api/v2" + path))
r.raise_for_status()
return r.json()
def post(path: str, body: dict):
r = httpx.post(BASE + path, json=body,
headers=_headers("POST", "/trade-api/v2" + path))
r.raise_for_status()
return r.json()
# Example: open markets in a series
markets = get("/markets", params={"series_ticker": "KXHIGHNY", "status": "open"})
签名规范: RSA-PSS,基于 SHA-256 的 MGF1,盐长度 = PSS.DIGEST_LENGTH。待签名字符串:{timestamp_ms}{METHOD}{path},其中 path 包含 /trade-api/v2,但不包含查询字符串。
请求头:KALSHI-ACCESS-KEY(UUID)、KALSHI-ACCESS-TIMESTAMP(毫秒)、KALSHI-ACCESS-SIGNATURE(base64)。
4. K 线历史记录
# Returns OHLC for yes_bid / yes_ask + volume + open_interest
# Values are dollar strings: {"close": "0.42"}
candles = get(
f"/series/KXHIGHNY/markets/{ticker}/candlesticks",
params={"start_ts": start_epoch, "end_ts": end_epoch, "period_interval": 60},
)
period_interval 的单位是分钟:1、60 或 1440。
YES/NO 订单簿约定
在 Kalshi 上,yes 和 no 都是挂单买价梯队 — 没有单独的卖价订单簿。要选择另一方,需吃掉相反方向的买价:
no_ask = 1 − best_yes_bid # cost to buy NO right now (lift YES bids)
yes_ask = 1 − best_no_bid # cost to buy YES right now (lift NO bids)
P(YES) mid = (best_yes_bid + (1 − best_no_bid)) / 2
如果弄反,会在不知不觉中反转所有信号。请使用 scripts/kalshi_orderbook.py 中的辅助函数。
订单簿响应根据 API 层级有两种形式 — 使用前请先规范化:
{"orderbook": {"yes": [[price, size], ...], "no": [[price, size], ...]}}
如果价格值 > 1.0,则该值是整数美分 — 请除以 100。
订单架构
POST /trade-api/v2/portfolio/orders 使用定点美元字符串,而不是整数。旧架构(整数美分、count、yes_price)会返回 400 invalid_parameters。
{
"ticker": "KXHIGHNY-26JUN02-B75.5",
"action": "buy",
"side": "yes",
"count_fp": "1.00",
"yes_price_dollars": "0.01",
"client_order_id": "my-strategy-001",
"time_in_force": "good_till_canceled"
}
关键字段规则 — 违反任一规则都会返回 400:
| 字段 | 规则 | 常见的 400 错误 |
|---|---|---|
count_fp | 定点字符串 "1.00" | 整数 count: 1 |
{side}_price_dollars | 美元字符串 "0.01" | 整数美分 yes_price: 1 |
time_in_force | 必填:good_till_canceled | immediate_or_cancel | fill_or_kill | 未填写 |
client_order_id | 仅允许 [A-Za-z0-9-] | 字符串中含有 . 或 : — 带方括号的行情代码包含 .,因此切勿直接复制行情代码 |
type | 不要发送 | "type": "limit" |
完整的订单生命周期(修改、减少、取消、批量操作)以及 strike_type 的注意事项,请参阅 references/auth-and-orders.md。
端点摘要
| 类别 | 端点 | 备注 |
|---|---|---|
| 余额 | GET /portfolio/balance | — |
| 持仓 | GET /portfolio/positions | — |
| 订单 | GET /portfolio/orders | ?status=resting|canceled|executed |
| 下单 | POST /portfolio/orders | 使用上文的美元字符串架构 |
| 取消 | DELETE /portfolio/orders/{id} | 返回 {"order": {...status: "canceled"}} |
| 修改 | POST /portfolio/orders/{id}/amend | 请求体中必须包含 ticker |
| 减少 | POST /portfolio/orders/{id}/decrease | {"reduce_by_fp": "1.00"} |
| 批量 | POST /portfolio/orders/batched | {"orders": [...]} |
| 成交 | GET /portfolio/fills | ?limit=N |
| 结算 | GET /portfolio/settlements | ?limit=N |
| 市场 | GET /markets | ?series_ticker=&status=open&limit=500 |
| 订单簿 | GET /markets/{ticker}/orderbook | ?depth=N |
| K 线 | GET /series/{series}/markets/{ticker}/candlesticks | ?start_ts=&end_ts=&period_interval=60 |
| 交易 | GET /markets/trades | 最近的交易记录 |
完整端点列表、市场元数据字段和速率限制:references/endpoints-and-marketdata.md。
WebSocket 发现流程:references/websocket.md。
文件
参考资料
references/auth-and-orders.md— RSA-PSS 规范、美元字符串订单架构、time_in_force、client_order_id清理、修改/减少/取消生命周期、strike_type注意事项、费用references/endpoints-and-marketdata.md— 完整端点表、订单簿变体、市场元数据字段(result、open_time、close_time、series_ticker)、K 线、速率限制references/websocket.md— WS 主机、发现流程、通道、WS 升级签名
脚本
scripts/kalshi_orderbook.py— YES/NO 买单阶梯辅助工具(no_ask、yes_ask、p_yes_mid、overround、kalshi_fee)。仅使用 Python 标准库,无需密钥,可离线运行。