RiskOfficer技能使用说明
RiskOfficer 投资组合管理
连接 RiskOfficer API 以管理投资组合并计算金融风险指标。
必需条件:一个环境变量 ——RISK_OFFICER_TOKEN(在 RiskOfficer 应用 → 设置 → API 密钥中创建)。无需其他环境变量或二进制文件。

来源:官方技能库:github.com/mib424242/riskofficer-openclaw-skill。产品:riskofficer.tech。该令牌仅由 RiskOfficer 应用颁发;此技能不收集或存储凭证。
凭证和令牌处理
- 此技能不存储或记录您的令牌。令牌仅通过 HTTP
授权请求头发送至api.riskofficer.tech;它不会被写入磁盘、记录或发送到其他地方。您将令牌存储在何处(环境变量或~/.openclaw/openclaw.json) 完全由您掌控。 - 建议将
RISK_OFFICER_TOKEN设置为会话环境变量,而非将其保存在openclaw.json文件中。若您使用openclaw.json文件,请限制其文件权限,并注意有哪些代理或用户可以读取该文件。 - RiskOfficer 目前签发账户级别的令牌(非限定范围的令牌)。请为此技能创建一个命名的令牌(例如 "OpenClaw"),若您停止使用该技能,请在 RiskOfficer 应用中撤销该令牌。
- 令牌范围:该令牌允许此技能访问您的 RiskOfficer 数据(投资组合、风险计算、经纪商同步的头寸,用于只读分析)。若您需要撤销访问权限,请撤销或轮换该令牌。
- 验证链接:请确认github.com/mib424242/riskofficer-openclaw-skill及riskofficer.tech安装或提供令牌前,请先匹配您信任的发行方。
适用范围:仅限分析与研究(虚拟投资组合)
本功能中的所有投资组合数据与操作均在RiskOfficer自有环境中进行。您在此创建、编辑或优化的投资组合均为虚拟组合——仅用于分析与研究。本助手可执行以下操作:
- 读取您的投资组合(包括从经纪商同步的组合)以展示持仓、历史记录与风险指标
- 创建及修改虚拟/手动投资组合,并在RiskOfficer中运行优化分析
- 执行计算(风险价值、蒙特卡洛模拟、压力测试)针对这些投资组合
本功能不会在您的经纪账户中执行任何实际订单操作。经纪商同步功能为只读模式,仅用于分析;实际账户中的任何调仓或交易操作需由您通过经纪商应用程序或RiskOfficer自有流程完成,而非由本助手执行。令牌仅用于访问RiskOfficer的API,以支持此类分析与研究用途。
设置说明
- 打开RiskOfficer应用 → 设置 → API密钥
- 创建名为"OpenClaw"的新令牌
- 设置环境变量:
RISK_OFFICER_TOKEN=ro_pat_...
或在~/.openclaw/openclaw.json中配置:
{
"skills": {
"entries": {
"riskofficer": {
"enabled": true,
"apiKey": "ro_pat_..."
}
}
}
}
API基础URL
https://api.riskofficer.tech/api/v1
所有请求都需要:Authorization: Bearer ${RISK_OFFICER_TOKEN}
货币政策
- 支持的货币: 卢布和美元仅此两种。API合约中不支持欧元、人民币或其他货币作为基础货币或分析货币。
- 外汇来源:所有汇率均来自俄罗斯中央银行通过数据服务(莫斯科交易所/俄罗斯央行)。没有其他替代提供商。
- 每个投资组合仅限单一货币:每个投资组合必须包含单一货币的资产(全部为MOEX或全部为美国资产)。不支持混合货币的投资组合;请创建独立的投资组合。
- 汇总视图:用户选择
基础货币(卢布或美元);其他货币的子投资组合将使用俄罗斯央行汇率进行转换。
可用命令
代码搜索
搜索代码
在创建或编辑任何投资组合之前使用此功能以验证代码符号并获取其货币/交易所信息。当用户提到公司名称而非代码时,也应使用此功能。
curl -s "https://api.riskofficer.tech/api/v1/tickers/search?q=Apple&limit=10&locale=en" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
查询参数:
q(可选):搜索查询——按代码、名称或全名(不区分大小写)。省略此参数将按受欢迎程度排序返回热门代码。limit(可选,默认为20,最大为50):结果数量include_prices(可选,默认为false):是否包含价格当前价格,价格变动百分比,价格绝对变动值,价格日期地区设置(可选,默认值ru):en表示英文名称,ru表示俄文名称交易所(可选):按交易所筛选 ——莫斯科交易所,纽约证券交易所,纳斯达克,加密货币
响应: 股票代码数组,每个包含:股票代码,简称,全称,工具类型,货币,交易所,受欢迎程度评分,国际证券识别编码.
工具类型包括: 股票,债券,交易所交易基金,期货,连续期货(例如莫斯科交易所的BR、SI),货币,加密货币
关键规则:
- 始终使用代码搜索来解析公司名称 → 股票代码(例如:"Apple" → "AAPL", "Sberbank" → "SBER")
- 使用
货币字段来检查货币一致性约束,然后再添加到投资组合中 - 莫斯科交易所期货:搜索"BR"或"SI"返回的是连续合约,而非单个合约(如BRF6, SIM5)
- 使用
include_prices=true当用户询问"X现在值多少钱?"时,显示当前价格
# Search by company name (English)
curl -s "https://api.riskofficer.tech/api/v1/tickers/search?q=Gazprom&locale=en&limit=5" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
# Search by Russian name
curl -s "https://api.riskofficer.tech/api/v1/tickers/search?q=%D0%93%D0%B0%D0%B7%D0%BF%D1%80%D0%BE%D0%BC&locale=ru&limit=5" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
# Get current price for a ticker
curl -s "https://api.riskofficer.tech/api/v1/tickers/search?q=AAPL&include_prices=true" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
# Get popular tickers (no query param)
curl -s "https://api.riskofficer.tech/api/v1/tickers/search?limit=10&include_prices=true" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
# Filter by exchange
curl -s "https://api.riskofficer.tech/api/v1/tickers/search?q=SBER&exchange=MOEX" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
获取历史股票价格
当用户询问特定资产的价格历史、图表数据或趋势时:
curl -s "https://api.riskofficer.tech/api/v1/tickers/historical?tickers=SBER,GAZP,AAPL&days=30" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
查询参数: 股票代码(必填,以逗号分隔,最多50个),天数(可选,默认7天,最多252个交易日)。
响应: 数据对象以股票代码为键,每个包含:
价格数组,元素为{日期, 收盘价}对象当前价格、价格变动百分比、价格绝对变动值
投资组合管理
列出投资组合
当用户要求查看其投资组合或需要概览时:
curl -s "https://api.riskofficer.tech/api/v1/portfolios/list" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
查询参数: 投资组合类型(可选):"生产环境"(手动+实盘券商)、"沙盒环境"(仅限券商沙盒)、"全部"(默认值)。
响应:包含快照ID、名称,总价值,货币,持仓数量,经纪商,沙盒,活动快照ID(UUID 或 null — 如果设置,风险计算将使用此历史快照而非最新快照)。
获取投资组合详情
当用户想要查看特定投资组合中的持仓时:
curl -s "https://api.riskofficer.tech/api/v1/portfolio/snapshot/{snapshot_id}" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
响应:名称,总价值,货币,持仓(数组,包含股票代码,数量,当前价格,价值,权重,平均价格)。
获取投资组合历史
当用户询问其投资组合随时间的变化或希望浏览过去快照时:
curl -s "https://api.riskofficer.tech/api/v1/portfolio/history?days=30" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
查询参数: 天数(可选,默认30,范围1–365)。
响应:快照数组,包含快照ID,时间戳,总价值,持仓数量,sync_source,类型(聚合/手动/经纪商),名称,经纪商,沙盒.
获取快照差异(比较两个投资组合版本)
当用户想要比较两个投资组合状态时(例如,再平衡前后,或两个日期):
curl -s "https://api.riskofficer.tech/api/v1/portfolio/snapshot/{snapshot_id}/diff?compare_to={other_snapshot_id}" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
响应:新增/移除/修改的持仓,总价值变动两个快照都必须属于该用户。
获取聚合投资组合
当用户询问其所有账户的总或合并投资组合时:
curl -s "https://api.riskofficer.tech/api/v1/portfolio/aggregated?type=all" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
查询参数:
type=production— 手动账户 + 券商实盘账户type=sandbox— 仅限券商沙盒账户type=all— 所有账户(默认)
响应:
portfolio.positions— 跨所有投资组合合并的所有持仓portfolio.total_value— 以基准货币计的总价值portfolio.currency— 基准货币(卢布或美元)portfolio.sources_count— 聚合的投资组合数量汇率(可选):美元兑卢布,欧元兑卢布,人民币兑卢布,汇率日期,汇率来源(始终为"俄罗斯中央银行"),基准货币,汇率质量("实时"= 来自俄罗斯中央银行/缓存,"默认"= 俄罗斯中央银行不可用时使用的静态备用值,"无"= 无转换)警告— 例如,混合货币持仓、使用了外汇备用值数据质量(可选):外汇覆盖率(使用实时汇率的外汇查询占比),实时汇率查询次数,默认汇率查询次数,汇率不可用查询次数,包含的投资组合,排除的投资组合——用于聚合和外汇使用的可观测性
示例响应:
{
"portfolio": {
"positions": [
{"ticker": "SBER", "quantity": 150, "value": 42795, "sources": ["T-Bank", "Manual"]},
{"ticker": "AAPL", "quantity": 10, "value": 189500, "original_currency": "USD"}
],
"total_value": 1500000,
"currency": "RUB",
"sources_count": 3
},
"snapshot_id": "uuid-of-aggregated"
}
不同货币的头寸将自动使用俄罗斯中央银行的汇率进行转换。仅支持卢布和美元;每个子投资组合必须持有单一货币的资产。
更改基准货币(聚合投资组合)
当用户希望以不同货币查看聚合投资组合时:
curl -s -X PATCH "https://api.riskofficer.tech/api/v1/portfolio/{aggregated_snapshot_id}/settings" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"base_currency": "USD"}'
支持的货币: 卢布,美元。综合投资组合在变更后会自动重新计算。
用户提示示例:
- "所有内容以美元显示" / "Покажи всё в долларах" →
基础货币:"USD" - "切换到卢布" / "Переведи в рубли" →
基础货币:"RUB"
在综合计算中纳入/排除投资组合
当用户希望从总计算中排除特定投资组合时:
curl -s -X PATCH "https://api.riskofficer.tech/api/v1/portfolio/{snapshot_id}/settings" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"include_in_aggregated": false}'
用户提示示例:
- "从总计中排除沙盒" / "Не учитывай песочницу в общем портфеле"
- "从计算中移除演示投资组合" / "Убери демо-портфель из расчёта"
创建手动投资组合
当用户希望创建具有特定持仓的新投资组合时:
curl -s -X POST "https://api.riskofficer.tech/api/v1/portfolio/manual" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "My Portfolio",
"positions": [
{"ticker": "SBER", "quantity": 100},
{"ticker": "GAZP", "quantity": 50, "avg_price": 148.0},
{"ticker": "YNDX", "quantity": -20}
]
}'
字段:
代码(必填):股票代码。始终首先使用/tickers/search。验证并检查货币。数量(必需):股数。负值 = 空头头寸(例如,-20= 做空20股)。平均价格(可选):用于盈亏跟踪的平均购买/入场价格。如果在新建投资组合时省略 → 使用当前市场价格。如果在编辑时省略 → 继承自之前的快照。
查询参数: 区域设置(可选,默认值ru)— 影响资产名称的解析。
货币政策(全平台):仅支持RUB和USD。所有汇率均来自俄罗斯中央银行,通过数据服务(MOEX/俄罗斯央行)获取。没有汇率提供方的选择 — 始终是俄罗斯央行。
重要提示 — 单一货币规则:一个投资组合中的所有资产必须使用同一种货币。
- 卢布资产(莫斯科交易所):SBER、GAZP、LKOH、YNDX 等。
- 美元资产(纽约证券交易所/纳斯达克):AAPL、MSFT、GOOGL、TSLA 等。 不可在单个投资组合中混合货币!建议创建独立的投资组合。
空头头寸:
- 使用负的
数量来表示空头(例如{"ticker": "GAZP", "quantity": -50}) - 同一投资组合中支持同时持有多头和空头(多空投资组合)
- 优化多空投资组合时,请使用
optimization_mode: "preserve_directions"以保持空头头寸
更新投资组合(添加/移除头寸)
当用户想要修改现有投资组合时:
- 获取当前头寸:
curl -s "https://api.riskofficer.tech/api/v1/portfolio/snapshot/{snapshot_id}" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
- 使用相同的名称和更新后的完整头寸列表重新发布:
curl -s -X POST "https://api.riskofficer.tech/api/v1/portfolio/manual" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"name": "<same name>", "positions": [<complete updated list>]}'
重要提示:在更新前,务必向用户展示即将进行的更改并请求确认。平均价格除非明确指定,否则将沿用先前快照的数据。
删除手动投资组合
当用户希望完全删除/移除一个手动投资组合时:
curl -s -X DELETE "https://api.riskofficer.tech/api/v1/portfolio/manual/My%20Portfolio" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
- 投资组合名称必须进行URL编码
- 归档记录该投资组合的所有快照都将被归档—此操作不可逆
- 删除前务必与用户确认—无法撤销
- 响应内容:
已归档快照数量,投资组合名称,消息
删除经纪账户投资组合快照
当用户希望在不解除经纪账户连接的情况下清除其投资组合历史记录时:
curl -s -X DELETE "https://api.riskofficer.tech/api/v1/portfolio/broker/tinkoff?sandbox=false" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
沙盒模式=true对于沙盒投资组合,sandbox=false对于实盘/生产环境- 仅归档快照;经纪商连接保持活动状态
- 下次同步将创建新快照
- 删除前务必确认
经纪商集成
列出已连接的经纪商
当用户询问其经纪商连接时:
curl -s "https://api.riskofficer.tech/api/v1/brokers/connections" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
列出可用的经纪商提供商
当用户询问支持哪些经纪商时:
curl -s "https://api.riskofficer.tech/api/v1/brokers/available" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
从经纪商同步投资组合
当用户想要从已连接的经纪商刷新/更新其投资组合时:
curl -s -X POST "https://api.riskofficer.tech/api/v1/portfolio/proxy/broker/{broker}/portfolio" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"sandbox": false}'
{broker}:tinkoff或alfasandbox:false对于实盘账户,true适用于Tinkoff沙盒环境
若响应为400且包含missing_api_key错误码,表示券商未连接。请引导用户:
- 从以下链接获取API令牌https://www.tbank.ru/invest/settings/api/
- 打开RiskOfficer应用 → 设置 → 券商账户 → 连接Tinkoff
- 粘贴令牌并完成连接
断开券商连接
当用户需要移除券商连接时:
curl -s -X DELETE "https://api.riskofficer.tech/api/v1/brokers/connections/tinkoff?sandbox=false" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
sandbox=false表示实盘连接,sandbox=true表示沙盒环境- 该操作将移除连接及其保存的API密钥;投资组合快照历史记录将保留
- 若需同时删除快照历史,请先使用
DELETE /portfolio/broker/{broker}?sandbox=false - 断开连接前务必进行确认——重新连接需通过移动端应用操作
两个删除端点的区别:
| 操作 | DELETE /portfolio/broker/{id} | DELETE /brokers/connections/{id} |
|---|---|---|
| 删除快照 | ✅ 是(归档历史记录) | ❌ 否(保留历史记录) |
| 删除连接 | ❌ 否 | ✅ 是 |
| 无需重新连接即可再次同步 | ✅ 是 | ❌ 否 |
活动快照选择
默认情况下,所有风险计算均使用最新快照。您可以将历史快照固定,以基于过去的投资组合状态运行计算——这对于风险回测或比较再平衡前后的情况非常有用。
设置活动快照
当用户希望基于其投资组合的历史版本运行风险计算时:
curl -s -X PATCH "https://api.riskofficer.tech/api/v1/portfolio/active-snapshot" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"portfolio_key": "manual:My Portfolio", "snapshot_id": "{historical_snapshot_id}"}'
portfolio_key格式:
| 投资组合类型 | 格式 | 示例 |
|---|---|---|
| 聚合型 | aggregated | "aggregated" |
| 手动型 | manual:{名称} | "manual:我的投资组合" |
| 券商实盘 | broker:{券商ID}:false | "broker:tinkoff:false" |
| 券商沙盒 | broker:{券商ID}:true | "broker:tinkoff:true" |
工作流程:
GET /portfolio/history?days=90→ 按日期选择快照PATCH /portfolio/active-snapshot并附带选定的snapshot_id+portfolio_key- 运行风险价值 / 蒙特卡洛模拟 — 使用选定的历史快照
- 完成后重置(见下文)
在/portfolios/list: active_snapshot_id字段显示已固定的快照(null = 使用最新快照)。
将活动快照重置为最新
curl -s -X DELETE "https://api.riskofficer.tech/api/v1/portfolio/active-snapshot?portfolio_key=manual:My%20Portfolio" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
用户提示示例:
- "计算我一个月前的投资组合风险" / "Посчитай риски как было месяц назад" → 设置活动快照
- "返回当前投资组合" / "Сбрось на текущий портфель" → 删除活动快照
风险计算
计算 VaR(免费)
当用户要求计算风险、VaR 或风险指标时:
curl -s -X POST "https://api.riskofficer.tech/api/v1/risk/calculate-var" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"portfolio_snapshot_id": "{snapshot_id}",
"method": "historical",
"confidence": 0.95,
"horizon_days": 1,
"force_recalc": false
}'
参数:
method:"historical"(默认,推荐),"parametric",或"garch"置信度置信度水平,默认值0.95(范围 0.01–0.99)horizon_days:预测时间范围,默认值1(范围 1–30 天)force_recalc(可选,默认值false):设置为true以绕过缓存并强制重新计算(当用户说“重新计算”或“刷新”时使用)
响应:
- 如果
reused_existing: true且status: "done"→ 结果已在响应中(var_95、cvar_95、sharpe_ratio),无需轮询 - 否则 → 返回
计算ID,轮询结果:
curl -s "https://api.riskofficer.tech/api/v1/risk/calculation/{calculation_id}" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
等待直到状态:"完成",然后呈现结果。
获取VaR / 风险计算历史
当用户要求查看过去的风险计算时:
curl -s "https://api.riskofficer.tech/api/v1/risk/history?limit=50" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
查询参数: 限制(可选,默认50,最大100)。
响应:计算包含以下字段的数组:计算ID、投资组合快照ID、状态、方法、95% VaR、95% CVaR,夏普比率,创建于,完成于。
运行蒙特卡洛模拟(QUANT — 目前对所有用户免费)
当用户请求进行蒙特卡洛模拟时:
curl -s -X POST "https://api.riskofficer.tech/api/v1/risk/monte-carlo" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"portfolio_snapshot_id": "{snapshot_id}",
"simulations": 1000,
"horizon_days": 365,
"model": "gbm",
"force_recalc": false
}'
参数:
模拟次数:路径数量,默认值1000(范围 100–10000)预测天数:预测时间范围,默认值365(范围 1–365)模型:"gbm"(几何布朗运动 —目前仅实现了此模型)或"garch"(已接受但尚未实现;将表现为GBM)置信度(可选):百分位数数组,默认值[0.05, 0.50, 0.95]强制重新计算(可选,默认值为false):绕过缓存
轮询:GET /api/v1/risk/monte-carlo/{simulation_id}
运行压力测试(QUANT — 目前对所有用户免费)
当用户要求针对历史危机进行压力测试时:
首先,获取可用的危机:
curl -s "https://api.riskofficer.tech/api/v1/risk/stress-test/crises" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
然后运行:
curl -s -X POST "https://api.riskofficer.tech/api/v1/risk/stress-test" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"portfolio_snapshot_id": "{snapshot_id}",
"crisis": "covid_19",
"force_recalc": false
}'
参数:
crisis:危机场景ID,来自/stress-test/crises(例如covid_19、2008_crisis)force_recalc(可选,默认值为假): 绕过缓存
轮询:GET /api/v1/risk/stress-test/{stress_test_id}
投资组合优化(QUANT — 目前对所有用户免费)
风险平价优化
当用户要求优化其投资组合或平衡风险时:
curl -s -X POST "https://api.riskofficer.tech/api/v1/portfolio/{snapshot_id}/optimize" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"optimization_mode": "preserve_directions",
"constraints": {
"max_weight": 0.30,
"min_weight": 0.02
},
"options": {
"risk_measure": "variance",
"turnover_limit": 0.3,
"turnover_penalty": 0.1
}
}'
optimization_mode:
"long_only": 所有权重 ≥ 0(空头头寸在优化前转换为多头)"preserve_directions": 保持多头/空头方向不变(默认)"unconstrained": 权重可自由改变符号
options.risk_measure(可选,默认"variance"):
"variance": 经典ERC(Maillard, Roncalli, Teïletche 2010)"cvar"使用skfolio进行CVaR风险预算(凸优化,CLARABEL求解器)。更适合厚尾分布
换手率约束(可选,需要current_weights在投资组合中):
turnover_limit:硬约束——sum(|w_new - w_old|) <= limit。优化器保持在预算内turnover_penalty:目标函数中的软L1惩罚——权衡改进与换手成本
轮询:GET /api/v1/portfolio/optimizations/{optimization_id}结果:GET /api/v1/portfolio/optimizations/{optimization_id}/result
重要:对于优化,使用active_snapshot_id || snapshot_id来自投资组合列表条目(如果用户设置了选定的历史快照,则予以尊重)。
卡尔玛比率优化
当用户要求最大化卡尔玛比率(年化复合增长率 / |最大回撤|)时:
要求每个股票代码至少需要200个交易日以上的价格历史数据(后端实际请求252天数据)。若投资组合历史数据不足,建议改用风险平价策略。
curl -s -X POST "https://api.riskofficer.tech/api/v1/portfolio/{snapshot_id}/optimize-calmar" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"optimization_mode": "long_only",
"constraints": {
"max_weight": 0.50,
"min_weight": 0.05,
"min_expected_return": 0.0,
"max_drawdown_limit": 0.15,
"min_calmar_target": 0.5
},
"options": {
"turnover_limit": 0.3,
"turnover_penalty": 0.1
}
}'
轮询接口:GET /api/v1/portfolio/optimizations/{optimization_id}(检查optimization_type === "calmar_ratio")。
结果接口:GET /api/v1/portfolio/optimizations/{optimization_id}/result——包含当前指标与优化后指标(年化复合增长率、最大回撤、卡尔玛比率、恢复天数)。
应用接口:与风险平价策略相同→POST /api/v1/portfolio/optimizations/{optimization_id}/apply。
错误处理INSUFFICIENT_HISTORY:当价格历史数据不足时,需说明200天以上数据要求,并建议将风险平价策略作为替代方案。
应用优化
重要提示:在应用前,务必显示完整的再平衡计划,并请求用户明确确认!
curl -s -X POST "https://api.riskofficer.tech/api/v1/portfolio/optimizations/{optimization_id}/apply" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
响应:new_snapshot_id。每次优化只能应用一次。
布莱克-利特曼优化(QUANT)
当用户对特定资产有观点(带有置信度的预期收益)并希望获得最优投资组合时:
curl -s -X POST "https://api.riskofficer.tech/api/v1/portfolio/optimize-bl" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"tickers": ["SBER", "GAZP", "LKOH", "ROSN"],
"views": [
{"ticker": "SBER", "expected_return": 0.15, "confidence": 0.7},
{"ticker": "ROSN", "expected_return": -0.05, "confidence": 0.5}
],
"constraints": { ... },
"options": { "risk_free_rate": 0.16, "tau": 0.05 },
"portfolio_snapshot_id": null,
"currency": "RUB"
}'
参数:
tickers(必需,至少2个):投资标的代码views(必需,至少1个):投资者观点——expected_return为年化值(0.15 = 15%),confidence0.01–1.0(Idzorek方法用于调整Omega)constraints.weight_bound_lower:每项资产的最小权重(负值允许做空,默认值 -0.15)constraints.weight_bound_upper每项资产的最大权重(默认值0.25)constraints.max_gross_exposure:最大总敞口,即 sum(|w_i|) 的最大值(默认值2.0)constraints.target_net_exposure:净敞口目标值,即 sum(w_i) 的精确目标值(例如,全仓投资时为1.0)。与max_net_exposureconstraints.max_net_exposure:最大净敞口,即 |sum(w_i)| 的最大值constraints.turnover_limit/constraints.turnover_penalty:与风险平价(见上文)相同。若要对当前投资组合实施换手率限制,请传入portfolio_snapshot_id(见下文)。options.risk_free_rate:年化无风险利率(MOEX默认值0.16)options.tau:不确定性缩放因子(默认值0.05)portfolio_snapshot_id(可选):用于计算当前权重的投资组合快照UUID。当设置此项时,换手率约束将相对于此投资组合进行计算。若进行绿地优化则省略此项。货币(可选,默认为"RUB"):市场数据范围——"RUB"或"USD"。对在美国上市的股票代码使用美元。响应:
optimization_id ,状态:"pending"。通过GET /portfolio/optimizations/{id}轮询,通过GET /portfolio/optimizations/{id}/result获取结果。结果包含:
target_portfolio (包含权重和方向的股票代码)。(tickers with weights and directions),指标(预期回报、波动率、夏普比率、净/总风险敞口、投资组合类型),BL后验回报。
应用: POST /portfolio/optimizations/{id}/apply——创建一个新的手动投资组合“BL优化组合”。
用户提示示例:
- “我认为Sberbank将实现15%的回报且置信度高,请优化我的投资组合”→ 使用观点的BL模型
- “构建一个多空投资组合:做多银行股,做空石油股”→ 使用正/负面观点的BL模型
- “使用Black-Litterman模型优化”→ 向用户询问观点(每个代码的预期回报+置信度)
交易前检查(免费)
运行交易前风险检查
当用户或AI代理希望在执行前验证目标投资组合时。VaR使用历史方法计算(基于市场数据的经验分布)。
curl -s -X POST "https://api.riskofficer.tech/api/v1/risk/pre-trade-check" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"target_portfolio": {"SBER": 0.15, "GAZP": 0.10, "LKOH": 0.12, "ROSN": -0.08},
"amount": 1000000,
"currency": "RUB",
"constraints": {
"max_var_pct": 5.0,
"weight_bound_upper": 0.25,
"weight_bound_lower": -0.15,
"max_gross_exposure": 2.0,
"max_net_exposure": 0.5,
"max_sector_concentration": 0.35,
"sector_limits": {"Energy": 0.30, "Finance": 0.25}
}
}'
参数:
target_portfolio(必填):字典形式的{ticker: 权重}— 负权重 = 空头金额(必填):用于计算VaR的投资组合名义价值货币(可选,默认"RUB"):投资组合的货币 —"RUB"或"USD"。决定使用哪个市场数据宇宙来计算历史VaR。约束条件(可选):max_var_pct:允许的最大VaR百分比(例如 5.0 = 5%)weight_bound_upper/weight_bound_lower:单头寸权重限制max_gross_exposure/max_net_exposure:敞口限制最大行业集中度:全局最大行业权重(例如0.35表示单一行业权重不超过35%)。行业数据从数据服务获取。如果数据服务不可用,则返回警告而非错误。行业限制:按行业设置的最大权重,格式为{行业名称: 最大权重}(例如{"能源": 0.30})。匹配不区分大小写。可与最大行业集中度结合使用。
响应(同步,无需轮询):
{
"verdict": "pass",
"num_positions": 4,
"max_position_weight": 0.15,
"var_95_pct": 3.21,
"currency": "RUB",
"exposure_metrics": {
"net_exposure": 0.29,
"gross_exposure": 0.45,
"long_exposure": 0.37,
"short_exposure": 0.08
},
"constraint_violations": [],
"sector_exposures": {
"Energy": 0.488889,
"Finance": 0.333333,
"Other": 0.177778
},
"result_hash": "0x...",
"data_quality": {
"tickers_requested": 4,
"tickers_with_data": 4,
"tickers_missing": [],
"total_dates": 252,
"dates_dropped": 0
}
}
行业暴露度(可选字段,当设置最大行业集中度或行业限制时出现):映射行业名称至其总暴露度占比。计算公式:行业暴露度[s] = 行业成分股abs(权重[t])之和 / 总暴露度。对于多空投资组合,取权重绝对值这样使用是为了让多头和空头都能按比例贡献。
数据质量(可选):请求的股票代码、有数据的股票代码、缺失数据的股票代码、总日期数、被剔除的日期数——反映了用于风险价值计算的历史数据对齐情况(按日期内连接;不进行零填充)。如果某些股票代码的行业元数据不可用,也可能包含无行业信息的股票代码。
判定结果: "通过"(一切正常)、"失败"(违反硬性约束)、"警告"(存在软性问题)
用户提示示例:
- "检查这个投资组合是否安全" / "交易前检查投资组合"
- "运行交易前检查:SBER 15%,GAZP 10%,ROSN -8%"
- BL优化后:"应用前检查结果"
批量创建投资组合(免费)
创建多个投资组合
当用户或平台希望一次创建多个投资组合时:
curl -s -X POST "https://api.riskofficer.tech/api/v1/portfolio/manual/batch" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"portfolios": [
{
"name": "Pod Alpha",
"positions": [{"ticker": "SBER", "quantity": 100}, {"ticker": "GAZP", "quantity": -50}],
"currency": "RUB"
},
{
"name": "Pod Beta",
"positions": [{"ticker": "LKOH", "quantity": 30}],
"currency": "RUB"
}
]
}'
响应:数组,包含{名称,快照ID,状态}每个投资组合的信息。部分成功是可能的——一个投资组合失败不会影响其他组合。
跨投资组合相关性分析(量化)
计算投资组合间的盈亏相关性
当用户询问跨投资组合/投资组的分散化或再相关风险时:
curl -s -X POST "https://api.riskofficer.tech/api/v1/portfolio/correlation" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"portfolio_ids": null,
"window_days": 60,
"include_crisis_regime": true,
"analysis_currency": "RUB"
}'
参数:
portfolio_ids(可选):快照UUID列表。null= 用户所有投资组合(每个投资组合的最新快照)window_days(可选,默认值60,范围20–252):用于计算盈亏相关性的滚动窗口include_crisis_regime(可选,默认false):比较常态与危机期间的相关性(危机 = 总体盈亏 < μ-2σ 的日期)analysis_currency(可选,默认"RUB"):在计算相关性之前,将所有盈亏序列归一化为此货币 ——"RUB"或"USD"。当投资组合使用不同货币时使用;汇率为俄罗斯央行历史数据。
响应:异步 —— 通过GET /portfolio/optimizations/{id}轮询,通过GET /portfolio/optimizations/{id}/result获取结果。
结果包含:
{
"result_data": {
"portfolio_names": ["Pod Alpha", "Pod Beta", "T-Bank"],
"correlation_matrix": [[1.0, 0.35, 0.12], [0.35, 1.0, 0.48], [0.12, 0.48, 1.0]],
"pairs": [ ... ],
"avg_pairwise_correlation": 0.317,
"analysis_currency": "RUB",
"fx_source": "CBR",
"fx_coverage": 1.0,
"fx_conversions": { "Pod Alpha": "USD->RUB", "Pod Beta": "RUB" },
"crisis_regime": {
"available": true,
"avg_normal_correlation": 0.25,
"avg_crisis_correlation": 0.72,
"re_correlation_delta": 0.47,
"n_crisis_days": 8,
"n_normal_days": 52
}
}
}
关键指标: re_correlation_delta—— 压力期间相关性增加的程度。> 0.2 = 显著的再相关性风险(投资组合单元在压力下失去分散化效果)。
用户提示示例:
- "我的投资组合之间的相关性如何?" / "Какая корреляция между портфелями?"
- "检查再相关风险" / "中心簿分析"
- "比较正常情况与危机情况下的相关性"
单个投资组合风险设置 (免费)
设置个体风险价值阈值
当用户希望为特定投资组合设置不同的风险警报阈值时:
curl -s -X PATCH "https://api.riskofficer.tech/api/v1/portfolio/{snapshot_id}/settings" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"risk_threshold_var": 5.0}'
参数:
risk_threshold_var:风险价值阈值,以百分比表示 (5.0 = 5%)。当风险价值超过此阈值时,将为此特定投资组合触发推送通知/警报
用户提示示例:
- "为我的保守型投资组合将风险价值警报设置在3%"
- "将激进型投资组合的风险阈值提高到7%"
功能标志
获取功能标志
检查哪些功能已启用:
curl -s "https://api.riskofficer.tech/api/v1/feature-flags" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
响应:
{
"websocket_enabled": true,
"subscription_required_for_quant": false,
"pre_trade_check_enabled": true,
"black_litterman_enabled": true,
"cross_correlation_enabled": true,
"cvar_risk_parity_enabled": true
}
订阅状态
注意:Quant 订阅目前对所有用户免费所有功能无需付费即可使用
curl -s "https://api.riskofficer.tech/api/v1/subscription/status" \
-H "Authorization: Bearer ${RISK_OFFICER_TOKEN}"
目前所有用户返回has_subscription: true。
异步操作
VaR、蒙特卡洛模拟、压力测试和优化均为异步操作。
轮询模式:
- POST端点 → 获取
calculation_id/simulation_id/optimization_id - 每2-3秒轮询GET端点
- 检查
状态:pending或processing→ 持续轮询done→ 呈现结果失败→ 显示错误
典型耗时:
| 操作 | 典型耗时 |
|---|---|
| 风险价值 | 3–10 秒 |
| 蒙特卡洛模拟 | 10–30 秒 |
| 压力测试 | 5–15 秒 |
| 优化 | 10–30 秒 |
用户沟通:
- 启动后立即显示"正在计算..."
- 若轮询耗时 > 10 秒:显示"仍在计算,请稍候..."
- 始终显示最终结果或错误信息
重要规则
-
虚拟/分析范畴:投资组合及所有操作(创建、优化、删除、同步)仅存在于RiskOfficer内部。此技能用于分析与研究;不实际下达或执行经纪商订单。
-
单一货币规则(手动/经纪商投资组合):每个投资组合必须包含相同货币的资产。不能将SBER(卢布)与AAPL(美元)混合。汇总的投资组合是例外——它会使用俄罗斯央行汇率自动转换。
-
空头头寸:负的
数量会创建空头。对于多空投资组合,使用optimization_mode: "preserve_directions"以便在优化时保留空头头寸。 -
务必先搜索代码:在创建或编辑投资组合之前,请使用
/tickers/search来验证代码符号并检查其货币。 -
确认:在以下操作前,务必显示将要更改的内容并请求确认:更新/删除投资组合、应用优化、断开经纪商连接。这些操作可能不可逆。
-
异步:VaR、蒙特卡洛模拟、压力测试和优化是异步操作。请轮询结果。
-
订阅:蒙特卡洛模拟、压力测试和优化是Quant功能(目前免费)。VaR始终免费。
-
经纪商集成:用户必须先通过RiskOfficer移动应用连接经纪商。无法通过聊天连接(出于安全考虑)。
-
错误处理:
401 未授权→ 令牌无效或过期;用户需要重新创建403 需要订阅→ 需要Quant订阅(目前对所有用户免费)400 缺少API密钥→ 经纪商未通过应用连接400 货币不匹配→ 单个投资组合中混合了多种货币400 历史数据不足→ Calmar计算所需的价格历史数据不足(需要200个以上交易日);建议使用风险平价策略400 MVO不可行→ BL约束过紧;建议放宽权重边界或敞口限制404 未找到→ 未找到投资组合或快照(可能已被删除)429 请求过多→ 达到优化请求速率限制(各层级限制:免费版30次/小时,Quant版100次/小时,专业版1000次/小时)
-
活动快照:
active_snapshot_id来自/portfolios/list的优先级高于snapshot_id当执行计算时。在调用优化时使用active_snapshot_id || snapshot_id进行优化调用。 -
result_hash (ERC-8004):优化和VaR响应包含
result_hash——一个用于确定性验证的keccak256哈希值。此信息仅供参考;除非构建链上验证,否则可安全忽略。 -
应用前的交易前检查:对于构建自主交易流程的AI代理,在调用应用之前,始终在BL优化结果上运行
POST /risk/pre-trade-check。这能捕获优化器可能未强制执行(如行业限制、VaR限制)的约束违规。使用currency: "RUB"或"USD"以匹配投资组合货币(默认为RUB)。 -
API中的货币设置:交易前检查接受可选
货币(卢布/美元)。BL模型接受可选货币(市场数据范围)和投资组合快照ID(用于计算相对于当前投资组合的换手率)。相关性分析接受可选分析货币(卢布/美元)——盈亏将使用俄罗斯央行历史汇率折算为该货币。
方法论与参考文献:此技能包含一个参考文献/文件夹,其中包含实施说明和学术资料。当用户询问如何实现风险价值、风险平价、卡尔玛比率、布莱克-利特曼模型、交易前检查、相关性分析或聚合投资组合时,您可以引用对应的文件:methodology-var.md、methodology-risk-parity.md、methodology-calmar.mdmethodology-black-litterman.mdmethodology-pre-trade.mdmethodology-correlation.mdmethodology-aggregation.mdmethodology-hrp.mdmethodology-monte-carlo.mdmethodology-stress-test.mdmethodology-metrics.mdmethodology-auto-portfolio.md
。关于论文和库的完整列表,请参阅references/academic-references.md。示例对话用户想查看他们的投资组合"Show my portfolios" / "Покажи мои портфели"
→,methodology-metrics.md,methodology-auto-portfolio.md. For a consolidated list of papers and libraries, seereferences/academic-references.md.
Example Conversations
User wants to see their portfolios
"Show my portfolios" / "Покажи мои портфели"
→获取 /portfolios/list→ 请按以下格式美观地展示:名称、总价值、持仓数量、货币、最后更新时间
用户希望获取所有账户的总计
"显示投资组合总计" / "所有账户总计" / "Сколько у меня всего?"
→获取 /portfolio/aggregated?type=all→ 显示总价值、合并持仓、来源数量
→ 注意持仓已从其他货币转换
用户希望更改显示货币
"全部用美元显示" / "Покажи в долларах"
→PATCH /portfolio/{aggregated_id}/settings附带{"base_currency": "USD"}→再次获取 /portfolio/aggregated→ 以新货币显示投资组合
用户按公司名称(非股票代码)询问
"将Sberbank添加到我的投资组合" / "Gazprom的股票代码是什么?" / "Добавь Газпром"
→获取 /tickers/search?q=Sberbank&locale=en→ 找到:股票代码SBER,货币俄罗斯卢布,交易所莫斯科交易所→ 与用户确认,然后继续创建/更新投资组合
用户询问当前价格
"特斯拉多少钱?" / "Газпром(俄气)多少钱?"
→GET /tickers/search?q=TSLA&include_prices=true→ 显示当前价格,价格涨跌幅百分比,交易所
用户想要创建一个多空投资组合
"创建投资组合:做多SBER 100股,做空YNDX 50股"
→GET /tickers/search查询两个代码 → 确认两者都是RUB/MOEX(俄罗斯卢布/莫斯科交易所)
→POST /portfolio/manual附带数据[{"ticker":"SBER","quantity":100},{"ticker":"YNDX","quantity":-50}]→ 显示已创建的投资组合及其持仓
用户想要分析投资组合风险
"我的投资组合有哪些风险?" / "分析风险"
→GET /portfolios/list→ 查找投资组合
→POST /risk/calculate-var附带方法:"historical"→ 轮询直至完成
→ 展示VaR(风险价值)、CVaR(条件风险价值)、波动率、各代码的风险贡献度
→ 如果风险集中,提供优化建议
用户希望进行卡尔玛比率优化
"按卡尔玛比率优化" / "最大化每单位回撤的回报" / "Оптимизируй по Калмару"
→ 从投资组合列表中获取snapshot_id(快照ID)→POST /portfolio/{snapshot_id}/optimize-calmar→ 如果INSUFFICIENT_HISTORY(历史数据不足):解释需要200个以上交易日的数据,建议采用风险平价策略
→ 轮询直至完成
→ 展示current_metrics(当前指标)与optimized_metrics(优化后指标)(卡尔玛比率、年复合增长率、最大回撤)的对比
→ 展示再平衡计划,并在应用前请求确认
用户希望进行蒙特卡洛模拟
"运行蒙特卡洛模拟一年" / "Запусти Монте-Карло"
→POST /risk/monte-carlo附带参数模拟次数:1000, 时间跨度天数:365, 模型:"gbm"→ 轮询直到完成
→ 展示百分位预测结果(第5、50、95百分位)
用户想要进行压力测试
"运行压力测试" / "我的投资组合在2008年危机中会表现如何?"
→GET /risk/stress-test/crises→ 显示可用情景
→ 用户选择危机情景(或默认使用最相关的情景)
→POST /risk/stress-test→ 轮询,然后展示结果
用户想要计算一个历史投资组合的风险
"计算我上个月的投资组合风险" / "Посчитай риски как было месяц назад"
→GET /portfolio/history?days=45→ 查找大约30天前的快照
→PATCH /portfolio/active-snapshot使用那个快照ID和投资组合密钥POST /risk/calculate-var→ 轮询 → 呈现结果
→ 提供重置选项:DELETE /portfolio/active-snapshot用户尝试混合货币
"将苹果公司添加到我的卢布投资组合" →
GET /tickers/search?q=AAPL→ 货币:美元,交易所:纳斯达克
→ 投资组合为卢布 → 无法混合
→ 解释单一货币规则,建议创建一个单独的美元投资组合用户想要比较两个投资组合快照
"我的投资组合有什么变化?" / "与上周比较" / "Что изменилось в портфеле?" →
GET /portfolio/history→ 获取两个快照ID
→GET /portfolio/snapshot/{id}/diff?compare_to={other_id}→ 呈现新增/移除/修改的头寸,总价值变化量用户想要删除一个投资组合
"删除我的测试投资组合" / "Удали портфель 'Тест'" → 确认:"这将永久删除'测试'投资组合的所有N个快照。此操作无法撤销。是否继续?" → 确认后:
DELETE /portfolio/manual/Test→ 报告→ Report已存档的快照计数
用户想要断开一个经纪商连接
"断开Tinkoff连接" / "Отключи Тинькофф"
→ 确认:"这将移除Tinkoff连接。投资组合历史将被保留。继续吗?"
→ 确认后:DELETE /brokers/connections/tinkoff?sandbox=false→ 告知重新连接需要使用移动应用程序
用户想要进行布莱克-利特曼优化
"我认为Sber的回报率将是15%,Gazprom是10%" / "Оптимизируй по Блэку-Литтерману"
→ 收集观点:询问股票代码、预期回报率和置信度
→POST /portfolio/optimize-bl附带观点和约束条件
→ 轮询直到完成
→ 显示目标投资组合(股票代码、权重、方向)、指标(夏普比率、预期回报率、波动率)
→ 在以下操作前请求确认:POST /portfolio/optimizations/{id}/apply
用户想在交易前检查投资组合
"在我交易前检查一下这个" / "Проверь портфель перед исполнением"
→POST /risk/pre-trade-check附带目标权重、金额和约束条件
→ 显示判定结果(通过/失败/警告)、风险价值、敞口指标、违规情况
→ 如果"失败" → 解释违反了哪些约束条件
用户希望一次性创建多个投资组合
"创建3个投资组合" / "Создай несколько портфелей"
→POST /portfolio/manual/batch传入投资组合数组
→ 显示每个投资组合的状态(已创建/错误)
用户询问跨投资组合相关性
"我的投资组合分散性如何?" / "Какая корреляция между портфелями?"
→POST /portfolio/correlation参数include_crisis_regime: true→ 轮询直至完成
→ 显示平均配对相关性、矩阵、配对详情
→ 如果危机数据可用:显示正常与危机期间相关性及再相关差值
→ 如果re_correlation_delta > 0.2:警告再相关风险
用户需要CVaR风险平价优化
"使用CVaR优化" / "Оптимизируй по CVaR"
→POST /portfolio/{snapshot_id}/optimize参数options: { risk_measure: "cvar" }→ 解释:CVaR更适用于厚尾分布,能衡量超出VaR的尾部风险


微信扫一扫,打赏作者吧~