精华帖子

股票盘口价差系列因子

由bq7zuymm创建,最终由bq7zuymm 被浏览 14 用户

这一章我们来加工股票的盘口价差系列因子:时序加权的盘口价差、成交量加权的盘口价差、成交价加权的盘口价差。通过pandas能够将三者同时加工出来, 当然和dai.query的方式相比,前者的代码要稍复杂些但好处是能够同时观测到三个因子值。

数据定义

我们使用到的数据的表格形式如下

日期 买一价 卖一价 买一量 卖一量 成交量
t1 b1 a1 bv1 av1 v1
t2 b2 a2 bv2 av2 v2
tn bn an bvn avn vn

由于加权方式和中间价、订单斜率系列是一致的,我们直接写出被加权项即可:

时间加权盘口价差的权重是分钟内有效快照数分之一, 即每隔快照下的价差是等权的:

n表示的是一分钟内的有效快照数。

成交量加权盘口价差的权重定义与成交量加权净委买比例是一致的,所以我们直接给出公式:

成交价加权的盘口价差的权重定义与成交价加权净委买比例的定义是一致的,我们也是直接给公式:

因子加工代码

import dai
import time
import numpy as np
import pandas as pd

# 我没你以一只票为例
instruments = "('000002.SZ')"
dai.pull_data_to_table(datasource='cn_stock_level2_snapshot', table_name='stock_table', overwrite=True, lookback_time=72*60*60)

sql = f"""
SELECT date_trunc('minute', to_timestamp(datetime * 1.0 / 1000 + 8 * 60 * 60)) as date, instrument, datetime,
ask_price1-bid_price1 AS delta, 
volume, 
LAG(volume, 1) OVER (PARTITION BY instrument ORDER BY datetime) AS lag_volume,
amount, 
LAG(amount, 1) OVER (PARTITION BY instrument ORDER BY datetime) AS lag_amount
FROM stock_table
WHERE instrument in {instruments}
"""

engine = dai.stream_factor(sql, 'test', True, 'datetime ASC')

# 我们提前定义好根据时间和股票代码进行分组聚合计算三个分钟因子值的函数
def time_series_avg(df):
    # 时序均值
    out = df['delta'].mean()

    # 成交量均值
    up = (df['delta'] * (df['volume'] - df['lag_amount'])).sum()
    down = (df['volume'] - df['lag_amount']).sum()
    v_avg = up / down

    # 成交额
    avg_price = (df['amount'] - df['lag_amount']) / (df['volume'] - df['lag_amount'])
    up = (df['delta'] * avg_price).sum()
    down = avg_price.sum()
    amount_avg = up / down

    result = pd.DataFrame(
        {
            "date": [df['date'].iloc[-1]], 
            "instrument": [df['instrument'].iloc[-1]],
            "tavg_bidaskspd":[out], 
            "vavg_bidaskspd":[v_avg], 
            "pavg_bidaskspd":[amount_avg]
        }
    )
    return result
   
# 每隔60s计算一次因子值
while True:
    data = engine.df()
    if len(data) == 0:
        continue
    stream_data = data.groupby(['date', 'instrument']).apply(time_series_avg).reset_index(drop=True)
    time.sleep(60)

结果展示

很显然计算成交量和成交价加权时可能会存在缺失值,当出现成交量不变化(持续涨跌停或者停牌)时就容易产生缺失值,这里是需要大家注意的点。

{link}