[量化-014]计算各时间切片上的波动率选择合适的标的

如果一个股票的k线是一条水平线,没法赚钱。

有波动,才有赚钱机会。

股票A,最近30天,每天的平均波动是5%,股票B,最近30天,每天的平均波动是1%,那么,A比B的赚钱机会要多。

如果一个股票的波动率,从日均1%上升到日均5%,表明交易开始活跃,有一波行情。

因此需要计算股票的波动率,根据波动率选择标的。

一个比较稳妥的方案,是计算上证50或者沪深300的股票,在1、3、7、21、28天的日k平均波动,以及最大波动。

日K波动:今天最高价15块,最低价10块,那么今天日K的最大波动是50%。

日K平均波动:若干天内的“日K波动”的平均值。

日K最大波动:若干天内的最高价除以这些天内的最低价。

代码如下:

import tushare as ts
import numpy as np
import pandas as pd

def test2():
    """
    获取上证50名单,返回值形如:
              date    code  name
    0   2019-12-20  600000  浦发银行
    1   2019-12-20  600009  上海机场
    2   2019-12-20  600016  民生银行
    """
    sz50 = ts.get_sz50s()

    """
    获取沪深300名单,返回值形如:
              date    code  name  weight
    0   2019-11-29  600000  浦发银行    1.12
    1   2019-11-29  600004  白云机场    0.14
    2   2019-11-29  600009  上海机场    0.58
    """
    hs300 = ts.get_hs300s()

    # #一些测试
    # print(hs300)
    # #输出前5个记录
    # print('head:\n', sz50.head(), '\n\n')
    # #输出后3个记录
    # print('tail:\n', sz50.tail(3), '\n\n')
    # #index,每条记录的序号
    # print('index:\n', [i for i in sz50.index], '\n\n')
    # #columns
    # print('columns:\n', [i for i in sz50.columns], '\n\n')
    # #打印一列
    # print(sz50[sz50.columns[0]])
    # #打印一行
    # print(sz50[0:1])
    # #打印特定位置
    # print(sz50.loc[0:3, ['date', 'name']])
    # #打印特定位置,注意,要清楚知道坐标,index必须是整数
    # print(sz50.iloc[0, 1])
    # 获取一只股票最近两年的日K线价格
    """
    获取浦发银行最近2年的日k各指标,形如:
                 open   high  close    ...           v_ma5     v_ma10     v_ma20
    date                               ...                                      
    2019-12-23  12.46  12.46  12.20    ...       385949.64  366221.89  313179.32
    2019-12-20  12.41  12.55  12.42    ...       387825.12  346537.26  307239.01
    2019-12-19  12.40  12.50  12.41    ...       426565.94  327041.55  301929.48
    """
    prices = ts.get_hist_data(sz50.iloc[0, 1])

    """
    print(prices.loc[prices.index[0],:])
    输出日k的各指标,形如:
    open                12.460
    high                12.460
    close               12.200
    low                 12.170
    volume          370338.910
    price_change        -0.220
    p_change            -1.770
    ma5                 12.364
    ma10                12.181
    ma20                12.046
    v_ma5           385949.640
    v_ma10          366221.890
    v_ma20          313179.320
    """

    """
    # 计算价格最大值和最小值
    # print(prices.max().loc['high'])
    # print(prices.min().loc['low'])
    """
    # 取最近30个交易日的开盘,收盘,最大,最小,价格
    prices = prices.iloc[:30, 0:4]
    # 计算每一天的波动率,也就是(最大值/最小值-1)x100%
    for idx in prices.index:
        ff = 100.0 * (prices.loc[idx, 'high'] / prices.loc[idx, 'low'] - 1)
        print('%.2f%%' % ff)


"""
计算一只股票在最近若干天内的最大波动率。
最近1天、3天、7天、14天、21天、28天的波动率。
计算方式:1天、3天、7天、14天、21天、28天内的(最大值/最小值-1)x100%
"""
def get_fluctuation_rate_max(prices, cycles=[1, 3, 7, 14, 21, 28]):
    ret = pd.DataFrame(index=[0])
    #处理多个周期
    for cc in cycles:
        prices_tmp = prices.loc[prices.index[:cc], ['high', 'low']]
        ret['max_rate_cycle_%d_day'%cc] = prices_tmp.max().loc['high']/prices_tmp.min().loc['low']-1
    return ret

"""
计算一只股票在最近若干天内的每日波动率的平均值。
最近1天、3天、7天、14天、21天、28天的波动率。
计算方式:1天、3天、7天、14天、21天、28天内的(最大值/最小值-1)x100%
"""
def get_fluctuation_rate_mean(prices, cycles=[1, 3, 7, 14, 21, 28]):
    ret = pd.DataFrame(index=[0])
    #最近若干天,比如30天,每天的波动(最大值/最小值-1)
    fluctuation_rate_day = [(prices.loc[idx, 'high'] / prices.loc[idx, 'low'] - 1) for idx in prices.index]
    #处理多个周期
    for cc in cycles:
        ret['mean_rate_cycle_%d_day'%cc]=np.mean(fluctuation_rate_day[:cc])
    return ret

"""
波动极值密度
一段时间内,价格在最大最小之间来回波动的密度。如果价格走势是单向的,最大最小也有,但不利于波动赚钱。
方法:
"""
def get_fluctuation_rate_density(prices, cycles=[1, 3, 7, 14, 21, 28]):
    pass

def get_variable_fluctuation_rate_of_one_stock(code, cycles, num):
    prices = ts.get_hist_data(code)
    prices = prices.iloc[:num, :]
    res1 = get_fluctuation_rate_max(prices, cycles)
    # print('res1 = ', res1.iloc[0,:])
    res2 = get_fluctuation_rate_mean(prices, cycles)
    # print('res2 = ', res2.iloc[0,:])

    #把结果拼接起来
    ret = pd.concat([res1,res2], axis=1)
    # print('res = ', res.iloc[0, :])
    #更换idex
    ret.index = pd.Series([code])
    # print('res = \n', res.loc[res.index[0],:])
    # print(res.index)
    return ret

def get_variable_fluctuaion_rate_of_stocks(stock_list, cycles, num):
    """
    输出字段,1~28天波动的最大值,1~28天的每天波动均值
    max_rate_cycle_1_day,
    max_rate_cycle_3_day,
    max_rate_cycle_7_day,
    max_rate_cycle_14_day,
    max_rate_cycle_21_day,
    max_rate_cycle_28_day,
    mean_rate_cycle_1_day,
    mean_rate_cycle_3_day,
    mean_rate_cycle_7_day,
    mean_rate_cycle_14_day,
    mean_rate_cycle_21_day,
    mean_rate_cycle_28_day
    """
    n = 0
    ret = get_variable_fluctuation_rate_of_one_stock(stock_list.loc[stock_list.index[0],'code'],
                                                     cycles, num)
    for code in stock_list.loc[stock_list.index[1:], 'code']:
        res = get_variable_fluctuation_rate_of_one_stock(code, cycles, num)
        ret = pd.concat([ret, res], sort=False)
        n+=1
        # if n >= 2:
        #     break
    return ret




if __name__ == '__main__':
    # 时间阶段
    cycles = [1, 3, 7, 14, 21, 28]
    # 前num个交易记录,如果是日K,就是前num天
    num = 30
    # 注意,一定要有 num > cycles[-1]

    sz50 = ts.get_sz50s()
    hs300 = ts.get_hs300s()

    stocks = sz50
    stocks = hs300

    res = get_variable_fluctuaion_rate_of_stocks(stocks, cycles, num)
    res['code'] = res.index


    res = pd.merge(res, stocks)

    #输出全部记录,不省略
    pd.set_option('display.max_rows', None)
    for i in res.columns:
        if i in ['code', 'name', 'date', 'weight',]:
            continue
        print('\n\n')
        print(i)
        res = res.sort_values(by=i, ascending=False)
        print(res.loc[:, ['code', 'name', i]])
        # break

计算结果示例:

max_rate_cycle_1_day
       code   name  max_rate_cycle_1_day
108  601066   中信建投              0.125447
163  601901   方正证券              0.120261
20   600061   国投资本              0.119609
285  300033    同花顺              0.110267
119  601198   东兴证券              0.108020
202  000596   古井贡酒              0.106462
14   600030   中信证券              0.103656
195  000413   东旭光电              0.094637
147  601688   华泰证券              0.086484
91   600837   海通证券              0.085383
102  600999   招商证券              0.085057
40   600233   圆通速递              0.082927
159  601881   中国银河              0.082484

...

mean_rate_cycle_28_day
       code   name  mean_rate_cycle_28_day
182  603986   兆易创新                0.058799
265  002555   三七互娱                0.054141
270  002624   完美世界                0.052897
179  603799   华友钴业                0.052539
82   600703   三安光电                0.052010
115  601162   天风证券                0.050139
236  002065   东华软件                0.050134
258  002456    欧菲光                0.049248
259  002460   赣锋锂业                0.048495
108  601066   中信建投                0.047841
246  002241   歌尔股份                0.047783
278  002938   鹏鼎控股                0.046844
158  601878   浙商证券                0.045959
285  300033    同花顺                0.044652
269  002602   世纪华通                0.043885
210  000671    阳光城                0.043126
291  300136   信维通信                0.043070
175  603160   汇顶科技                0.042619
260  002466   天齐锂业                0.042314
297  300413   芒果超媒                0.042066
85   600733   北汽蓝谷                0.041399
195  000413   东旭光电                0.041143
298  300433   蓝思科技                0.040816
294  300251   光线传媒                0.040216
280  002945   华林证券                0.040192

在有价值的标的里,寻找波动率高的标的,进行后续操作。

发布了448 篇原创文章 · 获赞 115 · 访问量 53万+

猜你喜欢

转载自blog.csdn.net/u011539200/article/details/103783911