问题描述
解决方案
在聚宽(JoinQuant)平台中,获取股票的主力资金净流入数据主要使用 get_money_flow 函数。该函数提供了基于逐笔成交数据计算的资金流向信息。
以下是关于如何获取该数据、字段说明以及一个完整的基于主力资金流入的交易策略示例。
1. 核心API说明
函数名:get_money_flow
关键字段:
net_amount_main: 主力净额(万)。这是最核心的指标,计算公式为:超大单净额 + 大单净额。- 正值表示主力资金净流入。
- 负值表示主力资金净流出。
net_pct_main: 主力净占比(%)。计算公式为:主力净额 / 成交额。用于衡量主力资金流入的强度。
2. 在研究环境中获取数据
如果你需要在“研究”模块中分析某只股票的历史主力资金情况,可以使用以下代码:
# -*- coding: utf-8 -*-
from jqdata import *
import pandas as pd
# 设置股票代码和时间范围
security = '000001.XSHE'
start_date = '2023-01-01'
end_date = '2023-02-01'
# 获取资金流数据
# fields参数指定我们需要的主力净额(net_amount_main)和主力净占比(net_pct_main)
df = get_money_flow(
[security],
start_date=start_date,
end_date=end_date,
fields=['date', 'sec_code', 'close', 'net_amount_main', 'net_pct_main']
)
# 打印前5行
print(df.head())
# 简单分析:计算这段时间内主力资金净流入的天数
positive_days = df[df['net_amount_main'] > 0].shape[0]
print("主力资金净流入天数: %d" % positive_days)
3. 策略示例:主力资金跟随策略
下面是一个完整的策略代码,可以直接在聚宽的回测环境中运行。
策略逻辑:
- 股票池:沪深300成分股。
- 买入条件:选取昨日“主力资金净占比”最高的前10只股票,且主力资金必须为净流入(大于0)。
- 卖出条件:如果持仓股票不在今日的买入列表中,则卖出。
- 调仓频率:每日调仓。
# -*- coding: utf-8 -*-
from jqdata import *
def initialize(context):
# 设定基准为沪深300
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 过滤掉order系列API产生的比error级别低的log
log.set_level('order', 'error')
# 设定每日交易费用
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# 每天开盘前运行
run_daily(before_market_open, time='before_open')
# 每天开盘时运行
run_daily(market_open, time='open')
def before_market_open(context):
# 获取沪深300成分股
g.security_list = get_index_stocks('000300.XSHG')
def market_open(context):
# 1. 获取资金流数据
# 注意:在回测中,get_money_flow 如果不指定 end_date,默认获取的是截止到昨天的历史数据
# 我们获取过去1天的数据
q = get_money_flow(
g.security_list,
end_date=context.previous_date,
count=1,
fields=['sec_code', 'net_amount_main', 'net_pct_main']
)
# 2. 数据清洗与筛选
if len(q) > 0:
# 筛选出主力净额大于0的股票
df_positive = q[q['net_amount_main'] > 0]
# 按照主力净占比(net_pct_main)从大到小排序
df_sorted = df_positive.sort_values(by='net_pct_main', ascending=False)
# 取前10只股票作为目标买入列表
target_list = df_sorted['sec_code'].head(10).tolist()
else:
target_list = []
# 3. 交易操作
# 获取当前持仓
current_holdings = list(context.portfolio.positions.keys())
# 卖出:如果持仓股票不在目标列表中,则卖出
for stock in current_holdings:
if stock not in target_list:
order_target_value(stock, 0)
# 买入:对目标列表中的股票进行等权重买入
if len(target_list) > 0:
# 将资金平分成几份
value_per_stock = context.portfolio.available_cash / len(target_list)
for stock in target_list:
order_target_value(stock, value_per_stock)
# 打印日志方便观察
# log.info("今日目标持仓: %s" % target_list)
4. 注意事项
- 数据滞后性:
get_money_flow获取的是日级别数据。在回测中,如果在handle_data或run_daily中调用且不指定日期,通常获取的是前一交易日的数据(因为当天的资金流数据在收盘后才能结算完成)。 - 未来函数:如果在回测中使用了
datetime.date.today()或context.current_dt作为end_date来获取当日的资金流数据并用于当日交易,会包含未来函数(因为实盘中盘中无法获取全天结算后的资金流),这会导致回测结果虚高。上述策略示例中使用了context.previous_date来确保数据的安全性。 - 数据范围:该数据提供2010年至今的数据。
Q&A
Q: 主力资金净流入(net_amount_main)是如何定义的?
A: 在聚宽的数据定义中,主力净额 = 超大单净额 + 大单净额。其中,超大单通常指大于等于50万股或者100万元的成交单,大单指大于等于10万股或者20万元且小于超大单标准的成交单。
Q: get_money_flow 函数能否获取实时的盘中资金流数据?
A: 不能。get_money_flow 提供的是日频数据,通常在收盘后结算更新。如果需要盘中实时数据,通常需要处理 Tick 数据或分钟数据自行计算,或者使用 Level-2 相关的高频接口(如果平台支持)。
Q: 为什么有时候查询到的数据为空?
A: 可能的原因包括:1. 查询的日期是非交易日;2. 股票在该日期停牌;3. 股票在查询日期尚未上市;4. 数据尚未更新(如在当日收盘后立即查询当日数据,可能需要等待系统结算完成)。