随着沪深港通合作的不断深入,无论你是否在意,北向资金都已经成为影响大盘走势的一个重要因素。本文借助讯投QMT提供的北向分钟级资金流向历史数据,分析其与大盘的相关性,希望能和读者一起挖掘其中的可利用点。 一、历史数据下载和存储
1.1 数据下载这里我们通过xtquant库下载北向资金流向历史数据和大盘指数数据, 首先建立环境: # -*- coding: utf-8 -*-
import datetime, time
import pandas as pd
from xtquant import xtdatacenter as xtdc
import xtquant.xtdata as xtdata
from clickhouse_driver import Client
from tqdm import tqdm
xtdc.set_token('3e6c******5501')
xtdc.set_data_home_dir('/data/qmt')
try:
xtdc.init()
except:
time.sleep(3)
xtdc.init()
xtdata.reconnect('127.0.0.1', 58609)
db_client = Client('**.**.**.**', port=**, password='******', settings={'use_numpy': False})
然后下载历史数据: xtdata.download_history_data('FFFFFF.SGT', 'northfinancechange1m', '', '')
xtdata.download_history_data2(['000001.SH', '399001.SZ', '000016.SH', '000300.SH', '000852.SH', '000905.SH', '399006.SZ', '000688.SH', '399330.SZ'], '1m' , '', '')
1.2 北向资金数据存储至数据库建立Clickhouse数据库表,其中HGT表示沪股通,SGT表示深股通: create table if not exists qmt.northfinancechange1m
(
TradeDate Date,
TradeTime DateTime('Asia/Shanghai'),
TradeMinute UInt16,
HGTNorthBuy Int64 DEFAULT 0 COMMENT 'HGT北向买入资金',
HGTNorthSell Int64 DEFAULT 0 COMMENT 'HGT北向卖出资金',
HGTSouthBuy Int64 DEFAULT 0 COMMENT 'HGT南向买入资金',
HGTSouthSell Int64 DEFAULT 0 COMMENT 'HGT南向卖出资金',
SGTNorthBuy Int64 DEFAULT 0 COMMENT 'SGT北向买入资金',
SGTNorthSell Int64 DEFAULT 0 COMMENT 'SGT北向卖出资金',
SGTSouthBuy Int64 DEFAULT 0 COMMENT 'SGT南向买入资金',
SGTSouthSell Int64 DEFAULT 0 COMMENT 'SGT南向卖出资金',
HGTNorthFlow Int64 DEFAULT 0 COMMENT 'HGT北向资金净流入',
HGTNorthBalance Int64 DEFAULT 0 COMMENT 'HGT北向当日资金余额',
HGTSouthFlow Int64 DEFAULT 0 COMMENT 'HGT南向资金净流入',
HGTSouthBalance Int64 DEFAULT 0 COMMENT 'HGT南向当日资金余额',
SGTNorthFlow Int64 DEFAULT 0 COMMENT 'SGT北向资金净流入',
SGTNorthBalance Int64 DEFAULT 0 COMMENT 'SGT北向当日资金余额',
SGTSouthFlow Int64 DEFAULT 0 COMMENT 'SGT南向资金净流入',
SGTSouthBalance Int64 DEFAULT 0 COMMENT 'SGT南向当日资金余额'
)
ENGINE = ReplacingMergeTree()
ORDER BY (TradeDate, TradeTime)
写入数据: data = xtdata.get_market_data_ex([], ['FFFFFF.SGT'], 'northfinancechange1m', '', '')['FFFFFF.SGT']
data['time'] = pd.to_datetime(data.time, unit='ms') + pd.Timedelta(hours=8)
data['TradeMinute'] = data.time.dt.hour * 60 + data.time.dt.minute
data['TradeDate'] = data.time.dt.date
data = data.rename(columns={'time' : 'TradeTime', 'HGT北向买入资金': 'HGTNorthBuy', 'HGT北向卖出资金': 'HGTNorthSell', 'HGT南向买入资金': 'HGTSouthBuy', 'HGT南向卖出资金': 'HGTSouthSell', 'SGT北向买入资金': 'SGTNorthBuy', 'SGT北向卖出资金': 'SGTNorthSell', 'SGT南向买入资金': 'SGTSouthBuy', 'SGT南向卖出资金': 'SGTSouthSell', 'HGT北向资金净流入': 'HGTNorthFlow', 'HGT北向当日资金余额': 'HGTNorthBalance', 'HGT南向资金净流入': 'HGTSouthFlow', 'HGT南向当日资金余额': 'HGTSouthBalance', 'SGT北向资金净流入': 'SGTNorthFlow', 'SGT北向当日资金余额': 'SGTNorthBalance', 'SGT南向资金净流入': 'SGTSouthFlow', 'SGT南向当日资金余额': 'SGTSouthBalance'})
db_client.insert_dataframe('INSERT INTO qmt.northfinancechange1m VALUES', data, settings={'use_numpy': True})
1.3 指数数据存储至数据库建立数据表: create table if not exists qmt.mainindex1m
(
TradeDate Date,
TradeTime DateTime('Asia/Shanghai'),
TradeMinute UInt16,
IndexCode LowCardinality(String),
open Float32 DEFAULT 0,
close Float32 DEFAULT 0,
high Float32 DEFAULT 0,
low Float32 DEFAULT 0,
volume Int64 DEFAULT 0,
amount Float64 DEFAULT 0,
preClose Float32 DEFAULT 0
)
ENGINE = ReplacingMergeTree()
ORDER BY (TradeDate, TradeTime, IndexCode)
写入数据: index_tickers = ['000001.SH', '399001.SZ', '000016.SH', '000300.SH', '000852.SH', '000905.SH', '399006.SZ', '000688.SH', '399330.SZ']
for index in index_tickers:
print(index)
data2 = xtdata.get_market_data_ex([], [index], '1m', '', '')[index]
data2['time'] = pd.to_datetime(data2.time, unit='ms') + pd.Timedelta(hours=8)
data2['TradeMinute'] = data2.time.dt.hour * 60 + data2.time.dt.minute
data2['TradeDate'] = data2.time.dt.date
data2['IndexCode'] = index
data2 = data2.rename(columns={'time' : 'TradeTime'})
db_client.insert_dataframe('INSERT INTO qmt.mainindex1m VALUES', data2[['TradeDate', 'TradeTime', 'TradeMinute', 'IndexCode', 'open', 'high', 'low', 'close', 'volume', 'amount', 'preClose']], settings={'use_numpy': True})
二、北向资金净流入与日内指数表现分析
2.1 日内收益计算利用with as语法,事先计算指数的5分钟、10分钟内收益 with index_intraday_return as
(
select
TradeDate, IndexCode, TradeMinute, Next2HighRate, Next2LowRate, Next5HighRate, Next5LowRate, Next10HighRate, Next10LowRate
from (
select
TradeDate, IndexCode, TradeMinute,
max(high) OVER (PARTITION BY TradeDate, IndexCode ORDER BY TradeMinute asc ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) as Next2High,
min(low) OVER (PARTITION BY TradeDate, IndexCode ORDER BY TradeMinute asc ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING) as Next2Low,
max(high) OVER (PARTITION BY TradeDate, IndexCode ORDER BY TradeMinute asc ROWS BETWEEN 1 FOLLOWING AND 5 FOLLOWING) as Next5High,
min(low) OVER (PARTITION BY TradeDate, IndexCode ORDER BY TradeMinute asc ROWS BETWEEN 1 FOLLOWING AND 5 FOLLOWING) as Next5Low,
max(high) OVER (PARTITION BY TradeDate, IndexCode ORDER BY TradeMinute asc ROWS BETWEEN 1 FOLLOWING AND 10 FOLLOWING) as Next10High,
min(low) OVER (PARTITION BY TradeDate, IndexCode ORDER BY TradeMinute asc ROWS BETWEEN 1 FOLLOWING AND 10 FOLLOWING) as Next10Low,
round(1000 * (Next2High / close - 1), 2) as Next2HighRate,
round(1000 * (Next2Low / close - 1), 2) as Next2LowRate,
round(1000 * (Next5High / close - 1), 2) as Next5HighRate,
round(1000 * (Next5Low / close - 1), 2) as Next5LowRate,
round(1000 * (Next10High / close - 1), 2) as Next10HighRate,
round(1000 * (Next10Low / close - 1), 2) as Next10LowRate
from
qmt.mainindex1m
where
TradeDate >= '2023-06-01'
)
where TradeMinute >= 9*60 + 31 and TradeMinute <= 14 * 60 + 55
),
2.2 北向资金净流入因子提取这里简单提取分钟级资金流入差作为因子: north_flow_factor as
(
select
TradeDate, TradeMinute, SGTNorthFlow, HGTNorthFlow,
SGTNorthFlow - any(SGTNorthFlow) OVER (PARTITION BY TradeDate ORDER BY TradeMinute asc ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) as Prev1SGTNorthFlow,
SGTNorthFlow - any(SGTNorthFlow) OVER (PARTITION BY TradeDate ORDER BY TradeMinute asc ROWS BETWEEN 5 PRECEDING AND 1 PRECEDING) as Prev5SGTNorthFlow,
SGTNorthFlow - any(SGTNorthFlow) OVER (PARTITION BY TradeDate ORDER BY TradeMinute asc ROWS BETWEEN 10 PRECEDING AND 1 PRECEDING) as Prev10SGTNorthFlow,
HGTNorthFlow - any(HGTNorthFlow) OVER (PARTITION BY TradeDate ORDER BY TradeMinute asc ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) as Prev1HGTNorthFlow,
HGTNorthFlow - any(HGTNorthFlow) OVER (PARTITION BY TradeDate ORDER BY TradeMinute asc ROWS BETWEEN 5 PRECEDING AND 1 PRECEDING) as Prev5HGTNorthFlow,
HGTNorthFlow - any(HGTNorthFlow) OVER (PARTITION BY TradeDate ORDER BY TradeMinute asc ROWS BETWEEN 10 PRECEDING AND 1 PRECEDING) as Prev10HGTNorthFlow
from
qmt.northfinancechange1m
where
TradeDate >= '2023-06-01' and
((TradeMinute >= 9*60 + 30 and TradeMinute <= 11*60 + 30) or (TradeMinute >= 13*60 and TradeMinute <= 15*60))
)
2.3 相关性分析select
round(corr(Prev1HGTNorthFlow, Next2HighRate), 3) as HPrev1Next2HighCorr,
round(corr(Prev1HGTNorthFlow, Next5HighRate), 3) as HPrev1Next5HighCorr,
round(corr(Prev5HGTNorthFlow, Next2HighRate), 3) as HPrev5Next2HighCorr,
round(corr(Prev5HGTNorthFlow, Next5HighRate), 3) as HPrev5Next5HighCorr,
round(corr(Prev10HGTNorthFlow, Next2HighRate), 3) as HPrev10Next2HighCorr,
round(corr(Prev10HGTNorthFlow, Next5HighRate), 3) as HPrev10Next5HighCorr,
round(corr(Prev1HGTNorthFlow, Next2LowRate), 3) as HPrev1Next2LowCorr,
round(corr(Prev1HGTNorthFlow, Next5LowRate), 3) as HPrev1Next5LowCorr,
round(corr(Prev5HGTNorthFlow, Next2LowRate), 3) as HPrev5Next2LowCorr,
round(corr(Prev5HGTNorthFlow, Next5LowRate), 3) as HPrev5Next5LowCorr,
round(corr(Prev10HGTNorthFlow, Next2LowRate), 3) as HPrev10Next2LowCorr,
round(corr(Prev10HGTNorthFlow, Next5LowRate), 3) as HPrev10Next5LowCorr,
round(corr(Prev1SGTNorthFlow, Next2HighRate), 3) as SPrev1Next2HighCorr,
round(corr(Prev1SGTNorthFlow, Next5HighRate), 3) as SPrev1Next5HighCorr,
round(corr(Prev5SGTNorthFlow, Next2HighRate), 3) as SPrev5Next2HighCorr,
round(corr(Prev5SGTNorthFlow, Next5HighRate), 3) as SPrev5Next5HighCorr,
round(corr(Prev10SGTNorthFlow, Next2HighRate), 3) as SPrev10Next2HighCorr,
round(corr(Prev10SGTNorthFlow, Next5HighRate), 3) as SPrev10Next5HighCorr,
round(corr(Prev1SGTNorthFlow, Next2LowRate), 3) as SPrev1Next2LowCorr,
round(corr(Prev1SGTNorthFlow, Next5LowRate), 3) as SPrev1Next5LowCorr,
round(corr(Prev5SGTNorthFlow, Next2LowRate), 3) as SPrev5Next2LowCorr,
round(corr(Prev5SGTNorthFlow, Next5LowRate), 3) as SPrev5Next5LowCorr,
round(corr(Prev10SGTNorthFlow, Next2LowRate), 3) as SPrev10Next2LowCorr,
round(corr(Prev10SGTNorthFlow, Next5LowRate), 3) as SPrev10Next5LowCorr
from (
select TradeDate, TradeMinute, Next2HighRate, Next2LowRate, Next5HighRate, Next5LowRate, Next10HighRate, Next10LowRate
from index_intraday_return
where TradeDate >= '2023-07-01' and TradeDate<'2023-08-01' and IndexCode='000016.SH'
) a
inner join (
select TradeDate, TradeMinute, Prev1SGTNorthFlow, Prev5SGTNorthFlow, Prev10SGTNorthFlow, Prev1HGTNorthFlow, Prev5HGTNorthFlow, Prev10HGTNorthFlow
from north_flow_factor
) b
on a.TradeDate = b.TradeDate and a.TradeMinute = b.TradeMinute
我们分别计算沪深北向资金与未来2/5分钟指数收益的相关系数,并按照月份和指数分别统计:
 - 结果分析
- 北向资金分钟级流入的短时效应强烈,时间越短指数相关性越强
- 近两个月,尤其是12月,大盘指数受北向资金净流入的影响显著变大
- 大盘股(沪深300)受沪股通的影响更大,小盘股(中证1000)受深股通的影响更大
欢迎关注我的公众号“量化实战”,原创技术文章第一时间推送,如有加量化交流群需求,也可在公众号后台留言。
|