QMT持仓数据获取后,我是这样用Python做盈亏分析和风险监控的
QMT持仓数据获取后,我是这样用Python做盈亏分析和风险监控的
每次收盘后盯着账户发呆的日子终于结束了。作为一名用量化策略交易的散户,我曾经也经历过手动计算每只股票盈亏、用Excel画饼图的阶段,直到发现QMT的API配合Python能实现全自动分析。现在只需要3分钟,系统就能生成带预警标记的完整报告,这才是数字时代交易者该有的效率。
1. 从原始数据到结构化DataFrame
拿到QMT的持仓数据只是第一步,真正的挑战在于如何把这些零散的信息变成可分析的结构化数据。我习惯用Pandas的DataFrame作为中间容器,这样后续所有操作都会变得异常简单。
import pandas as pd
def get_position_df(account):
raw_data = get_trade_detail_data(account, 'stock', 'position')
position_list = []
for item in raw_data:
position_list.append({
'symbol': f"{item.m_strInstrumentID}.{item.m_strExchangeID}",
'name': item.m_strInstrumentName,
'volume': item.m_nVolume,
'available': item.m_nCanUseVolume,
'cost_price': item.m_dOpenPrice,
'market_value': item.m_dInstrumentValue,
'position_cost': item.m_dPositionCost,
'profit': item.m_dPositionProfit
})
return pd.DataFrame(position_list)
这个转换函数会返回包含8个关键字段的DataFrame。我特别喜欢用 symbol 这个组合字段,它把股票代码和交易所信息合并成了类似 600519.SH 的标准格式,后续对接其他分析库时特别方便。
2. 给原始数据装上"计算引擎"
基础数据清洗完成后,就该上"硬菜"了——计算那些真正影响决策的衍生指标。我的计算清单通常包括:
- 持仓占比 :单票市值/总市值
- 盈亏比例 :盈亏金额/持仓成本
- 累计收益率 :组合整体收益
- 风险敞口 :行业/板块集中度
def enrich_position_data(df):
# 计算总市值作为基准
total_value = df['market_value'].sum()
# 添加衍生字段
df['weight'] = df['market_value'] / total_value
df['profit_ratio'] = df['profit'] / df['position_cost']
df['cost_basis'] = df['position_cost'] / df['volume']
# 添加涨跌标志便于后续可视化
df['is_profit'] = df['profit'] >= 0
return df.sort_values('weight', ascending=False)
这里有个实用技巧:计算完权重后按降序排列,这样在后续可视化时,重要持仓会自动排在前面。我还特意加了 is_profit 这个布尔字段,等会儿画图时就知道为什么了。
3. 让数据自己"说话"的可视化技巧
枯燥的数字表格没人爱看,我摸索出一套固定可视化组合拳:
持仓分布图 用环形图呈现,中间空白处显示总收益率; 盈亏分析 用分组柱状图,红色绿色区分盈亏;再加上一个 风险预警看板 ,三图组合基本覆盖了所有分析需求。
import matplotlib.pyplot as plt
def plot_position_analysis(df, total_profit):
plt.figure(figsize=(15, 5))
# 持仓分布环形图
plt.subplot(131)
plt.pie(df['weight'], labels=df['symbol'],
wedgeprops={'width':0.3}, autopct='%1.1f%%')
plt.title('持仓分布')
# 盈亏柱状图
plt.subplot(132)
colors = ['green' if x else 'red' for x in df['is_profit']]
plt.bar(df['symbol'], df['profit'], color=colors)
plt.xticks(rotation=45)
plt.title('单票盈亏')
# 文本摘要
plt.subplot(133)
plt.axis('off')
summary_text = f"总收益率: {total_profit:.2%}\n"
summary_text += f"持仓数量: {len(df)}\n"
summary_text += f"盈利标的: {df['is_profit'].sum()}"
plt.text(0.1, 0.5, summary_text, fontsize=12)
plt.tight_layout()
return plt
这段代码生成的组合图表可以直接嵌入到日报邮件里。如果追求更炫酷的效果,可以把Matplotlib换成Plotly,但就日常使用而言,轻量级的Matplotlib完全够用。
4. 全天候运行的风险监控系统
单纯的事后分析还不够,我需要实时知道哪些持仓触发了预警规则。我的做法是构建一个可配置的预警引擎:
class RiskMonitor:
def __init__(self):
self.rules = {
'single_loss': {'threshold': -0.1, 'active': True},
'concentration': {'threshold': 0.3, 'active': True},
'liquidity': {'threshold': 0.8, 'active': False}
}
def check_rules(self, position_df):
alerts = []
# 单票亏损预警
if self.rules['single_loss']['active']:
loss_stocks = position_df[
position_df['profit_ratio'] <= self.rules['single_loss']['threshold']
]
for _, row in loss_stocks.iterrows():
alerts.append(f"亏损预警: {row['symbol']} 亏损达{row['profit_ratio']:.2%}")
# 集中度预警
if self.rules['concentration']['active']:
top_holdings = position_df.head(2)
if top_holdings['weight'].sum() > self.rules['concentration']['threshold']:
alerts.append("集中度预警: 前两大持仓占比过高")
return alerts
这个监控类最好的地方在于规则可配置。比如在行情波动大的时期,我会开启流动性检查;而在调仓阶段,则会临时调高集中度阈值。预警信息会通过企业微信机器人推送到手机,确保不错过任何风险信号。
5. 把这些组装成自动化流水线
最后一步是把所有组件串联起来,形成端到端的分析流水线。我习惯用Jupyter Notebook作为执行环境,但核心逻辑完全可以移植到定时任务中:
# 主执行流程
account = '您的资金账号' # 实际使用需要替换
# 数据获取与加工
positions = get_position_df(account)
enriched_df = enrich_position_data(positions)
total_profit = enriched_df['profit'].sum() / enriched_df['position_cost'].sum()
# 可视化分析
chart = plot_position_analysis(enriched_df, total_profit)
chart.savefig('daily_report.png')
# 风险扫描
monitor = RiskMonitor()
alerts = monitor.check_rules(enriched_df)
if alerts:
print("今日风险警报:")
for alert in alerts:
print(f"⚠️ {alert}")
else:
print("✅ 今日无风险警报")
这套系统跑起来后,我每天收盘后要做的就是打开邮箱查收自动生成的报告,再瞄一眼手机确认没有风险警报。曾经需要半小时的手工分析,现在10秒就能获取更全面的洞见。
更多推荐

所有评论(0)