SkLearn 对上证50成分股聚类

来源:互联网 发布:淘宝男模特要求 编辑:程序博客网 时间:2024/04/28 14:39

1. 为什么要对股票进行聚类

1.1 投资组合优化理论

股票聚类的基本原因就是从股市中选取一部股票进行投资。哪怕是上证50对一般的投资模型来说50条股票也太多了。
按照投资组合优化理论选取标准为:
(1)资产数越多越好
(2)资产之间相关系数越低越好

以期望收益E来衡量证券收益,以收益的方差δ2表示投资风险
  minδ2(rp)=wiwjcov(ri,rj)

  E(rp)=wiri

  式中:
  rp——组合收益;

  rirj——第i种、第j种资产的收益;

  wiwj——资产i和资产j在组合中的权重;

  δ2(rp)——组合收益的方差即组合的总体风险;

  cov(r,rj)——两种资产之间的协方差。
举个极端的例子:(以后再详细说吧,搞一个简单的例子)
有n个不相关的资产,其收益率都是r,风险都是v,优化后的投资比例应该是均分(还用优化吗……)
那资产组合的
收益:R = r
风险:V = v/n

1.2 聚类

聚类定义就不说了,经过对股票交易数据聚类后,可以将其分为几个类别,然后从每个类别中选一个样本,最后组成的样本可使样本之间的相关系数降至最低。
这样保证在一定的风险下使收益更高。
这里采用sklearn中affinity_propagation算法进行聚类。


2. 读取上证50成分股

dict_stock = {}def ReadStocks(stock_file):    print 'read_stocks...'    f = open(stock_file, 'r')    for line in f.readlines():        # str_line = str(line)        item = line.strip().split(' ')        dict_stock[item[0]] = item[1]    f.close()

3. 读取股票交易数据

用QSTK API获取股票交易数据。
之前的文件已经介绍过了,这里提2点:
(1)验证股票代码是否正确,移除异常股票,不然QSTK会报错

    db = DataAccess.DataAccess('Yahoo')    ls_all_syms = db.get_all_symbols()    ls_bad_syms = list(set(ls_stock_code) - set(ls_all_syms))    print 'Bad Stock Code : ', ls_bad_syms    for sym in ls_bad_syms:        ls_stock_code.remove(sym)

(2)对获取的数据进行清理,不然SKLearn会报错

    # Filling the data for NAN    for s_key in ls_keys:        dict_data[s_key] = dict_data[s_key].fillna(method='ffill')        dict_data[s_key] = dict_data[s_key].fillna(method='bfill')        dict_data[s_key] = dict_data[s_key].fillna(1.0)

4. 聚类

4.1 载入数据

    open = stock_data['open']    close = stock_data['close']    var =  close - open

open, close, var的数据类型都是pandas DataFrame类型。

print type(open)<class 'pandas.core.frame.DataFrame'>print open.iloc[:3, 1:3]                     600837.SS  600000.SS2015-01-02 16:00:00      24.06      15.692015-01-05 16:00:00      23.82      15.942015-01-06 16:00:00      23.30      16.00

关于pandas的使用参考下:
十分钟搞定pandas

4.2 sklearn 聚类

from sklearn import covariance, cluster    x = var/var.std(0)    edge_model = covariance.GraphLassoCV()    edge_model.fit(x)    centers, labels = cluster.affinity_propagation(edge_model.covariance_)

结果输出

    n_labels = labels.max()    print 'Centers : \n', ', '.join( np.array(dict_stock.values())[centers] )    for i in range(n_labels + 1):        print('Cluster %i: %s' %              ((i + 1), ', '.join([dict_stock[key]                                   for key in var.columns[labels == i]])))

5. 聚类因子选择

这里比较了几种因子的聚类结果
(1)x = var*vol*10e-9/var.std(0)

Covariance : 1.26342386383e-04
海螺水泥, 东方明珠, 中国平安, 中国交建, 中航动力, 包钢股份, 民生银行, 青岛海尔
Cluster 1: 大秦铁路, 海螺水泥, 贵州茅台, 华泰证券, 中国太保, 伊利股份, 中国石油, 中国神华
Cluster 2: 东方明珠, 保利地产, 特变电工
Cluster 3: 中国交建, 广汇能源
Cluster 4: 海通证券, 浦发银行, 招商证券, 兴业银行, 中信银行, 中国中车, 中国银行, 光大银行, 农业银行, 中国石化, 北京银行, 中信证券, 招商银行, 交通银行, 包钢股份, 工商银行, 民生银行
Cluster 5: 上港集团, 康美药业, 方正证券, 中国船舶
Cluster 6: 海油工程, 中航动力, 东方证券, 华夏银行, 国电南瑞, 上汽集团
Cluster 7: 北方稀土, 国金证券, 青岛海尔
Cluster 8: 中国中铁, 中国人寿, 中国重工, 中国铁建, 中国联通, 中国建筑
这里写图片描述

(2)x = var*np.sqrt(vol*10e-8)/(var.std(0)*np.log2(close))

Covariance : 1.16200812467e-04
海螺水泥, 东方明珠, 中国平安, 光大银行, 中航动力, 包钢股份, 民生银行, 青岛海尔
Cluster 1: 大秦铁路, 海螺水泥, 华泰证券, 中国太保, 伊利股份, 中国石油, 中信证券, 中国神华
Cluster 2: 东方明珠, 保利地产, 特变电工
Cluster 3: 中国交建, 广汇能源, 中国铁建, 包钢股份
Cluster 4: 浦发银行, 兴业银行, 贵州茅台, 中信银行, 中国银行, 光大银行, 农业银行, 中国石化, 北京银行, 招商银行, 交通银行, 华夏银行, 工商银行, 民生银行
Cluster 5: 上港集团, 康美药业, 方正证券, 中国船舶
Cluster 6: 海通证券, 招商证券, 海油工程, 中航动力, 东方证券, 国电南瑞, 上汽集团
Cluster 7: 北方稀土, 国金证券, 青岛海尔
Cluster 8: 中国中铁, 中国人寿, 中国中车, 中国重工, 中国联通, 中国建筑
这里写图片描述

(3)x = var/var.std(0)

Covariance : 2.42169315704e-04
Cluster 1: 中国中车
Cluster 2: 海油工程, 中国重工, 中航动力, 中国船舶
Cluster 3: 东方明珠, 广汇能源, 特变电工, 国电南瑞
Cluster 4: 北方稀土, 贵州茅台, 伊利股份, 北京银行, 康美药业, 华夏银行, 上汽集团, 青岛海尔
Cluster 5: 中国中铁, 中国交建, 中国铁建, 中国联通, 中国建筑
Cluster 6: 海通证券, 招商证券, 中国人寿, 华泰证券, 中国太保, 中信证券, 方正证券
Cluster 7: 包钢股份, 国金证券
Cluster 8: 东方证券
Cluster 9: 大秦铁路, 浦发银行, 海螺水泥, 兴业银行, 中信银行, 中国银行, 光大银行, 农业银行, 中国石化, 中国石油, 保利地产, 上港集团, 招商银行, 交通银行, 中国神华, 工商银行, 民生银行
这里写图片描述

1 0
原创粉丝点击