【Python量化投资系列】使⽤Python从Wind量化接⼝下载全部A股股票历史⾏情
数据
个⼈做股票研究最难得的是数据源的获取,除了从各⼤财经⽹站爬取数据外,从各⼤财经数据供应商提供的相关接⼝爬取或者下载,效率更⾼,数据质量也更有保证。
Wind终端⼀直是国内投资领域机构投资者必备的⼯具,但是对⼩散来说每年动辄⼏万⾄⼏⼗万不等的费⽤往往令我们望⽽却步。好不容易在⼤奖章⽹站到了Wind量化接⼝个
⼈版 API接⼝,虽说没有Wind终端完整的功能,但是从基础数据质量和接⼝易学程度讲,都要⽅便很多。
很早之前研究过,⼀直搁置了,这两天重新捡起来完善后,效率果然⽐从财经⽹站爬取数据效率⾼很多。话不多说,分享下这两天研究的成果。
⾸先从⼤奖章⽹站下载wind量化接⼝个⼈版(免费,这点很难得),根据提⽰安装、注册,然后就可以快乐的玩耍了。
API 接⼝插件(⽆需安装Wind终端)及⽂档:
下⾯上代码,已在代码中作了注释,供需要的朋友参考。
每周get⼀个⼩技能,⼀年后也必是收获满满啊,新年加油!
Python代码:(后续持续完善,⽬标是搭建⼀个本地的量化投资数据库)
# -*- coding:utf-8 -*-
>>>>>>>>>>>>>>>>>>>>>>>#
'''''
程序:Wind股票数据下载
功能:从Wind终端或者Wind资讯量化接⼝个⼈免费版中下载股票相关数据,保存⾄本地MySQL数据库,以进⼀步加⼯处理和分析
创建时间:2016/01/15  V1.01 创建版本,Python2.7
更新历史:2017/01/06  V1.02 从本地⽂件读取股票代码列表;升级到Python3.5版本
2017/01/07  V1.03 封装为函数,便于调试和代码管理
2017/01/08  V1.04 封装为类,为后续完善功能准备。⾃动从Wind中获取股票列表,独⽴运⾏;增加⽇志和参数处理
环境和类库:使⽤Python 3.5及第三⽅库pandas、WindPy、sqlalchemy
数据库:MySQL 5.7.16
Wind资讯量化接⼝个⼈版(免费),可从Wind官⽹或⼤奖章⽹站下载安装,注册即可使⽤
作者:yuzhucu
'''
>>>>>>>>>>>>>>>>>>>>>>>#
import pandas as pd
from WindPy import *
from sqlalchemy import create_engine
import datetime,time
import os
class WindStock():
def getCurrentTime(self):
# 获取当前时间
return time.strftime('[%Y-%m-%d %H:%M:%S]', time.localtime(time.time()))
def AStockHisData(self,symbols,start_date,end_date,step=0):
'''''
逐个股票代码查询⾏情数据
wsd代码可以借助 WindNavigator⾃动⽣成copy即可使⽤;时间参数不设,默认取当前⽇期,可能是⾮交易⽇没数据;
只有⼀个时间参数时,默认作为为起始时间,结束时间默认为当前⽇期;如设置两个时间参数则依次为起⽌时间
'''
CurrentTime(),": Download A Stock Starting:")
for symbol in symbols:
w.start()
try:
#stock=w.wsd(symbol,'trade_code,open,high,low,close,volume,amt',start_date,end_date)
'''''
wsd代码可以借助 WindNavigator⾃动⽣成copy即可使⽤;
时间参数不设,默认取当前⽇期,可能是⾮交易⽇没数据;
只有⼀个时间参数,默认为起始时间到最新;如设置两个时间参数则依次为起⽌时间
'''
stock=w.wsd(symbol, "trade_code,open,high,low,close,pre_close,volume,amt,dealnum,chg,pct_chg,vwap, adjfactor,close2,turn,free_turn,oi,oi_chg,pre_settle,settle,chg_settlement,pct_chg_settlement, lastradeday_s,last_trade_day,re                  index_data = pd.DataFrame()
index_data['trade_date']=stock.Times
stock.Data[0]=symbol
index_data['stock_code']=stock.Data[0]
#index_data['stock_code'] =symbol
index_data['open'] =stock.Data[1]
index_data['high'] =stock.Data[2]
index_data['low']  =stock.Data[3]
index_data['close']=stock.Data[4]
index_data['pre_close']=stock.Data[5]
index_data['volume']=stock.Data[6]
index_data['amt']=stock.Data[7]
index_data['dealnum']=stock.Data[8]
index_data['chg']=stock.Data[9]
index_data['pct_chg']=stock.Data[10]
#index_data['pct_chg']=index_data['pct_chg']/100
index_data['vwap']=stock.Data[11]
index_data['adj_factor']=stock.Data[12]
index_data['close2']=stock.Data[13]
index_data['turn']=stock.Data[14]
index_data['free_turn']=stock.Data[15]
index_data['oi']=stock.Data[16]
index_data['oi_chg']=stock.Data[17]
index_data['pre_settle']=stock.Data[18]
index_data['settle']=stock.Data[19]
index_data['chg_settlement']=stock.Data[20]
index_data['pct_chg_settlement']=stock.Data[21]
index_data['lastradeday_s']=stock.Data[22]
index_data['last_trade_day']=stock.Data[23]
index_data['rel_ipo_chg']=stock.Data[24]
index_data['rel_ipo_pct_chg']=stock.Data[25]
index_data['susp_reason']=stock.Data[26]
index_data['close3']=stock.Data[27]
index_data['pe_ttm']=stock.Data[28]
index_data['val_pe_deducted_ttm']=stock.Data[29]
index_data['pe_lyr']=stock.Data[30]
index_data['pb_lf']=stock.Data[31]
index_data['ps_ttm']=stock.Data[32]
index_data['ps_lyr']=stock.Data[33]
index_data['dividendyield2']=stock.Data[34]
index_data['ev']=stock.Data[35]
index_data['mkt_cap_ard']=stock.Data[36]
index_data['pb_mrq']=stock.Data[37]
index_data['pcf_ocf_ttm']=stock.Data[38]
index_data['pcf_ncf_ttm']=stock.Data[39]
index_data['pcf_ocflyr']=stock.Data[40]
index_data['pcf_ncflyr']=stock.Data[41]
index_data['trade_status']=stock.Data[42]
index_data['data_source']='Wind'
index_data['created_date']=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
index_data['updated_date']=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
index_data = index_data[index_data['open'] > 0]
#index_data.fillna(0)
try:
_sql('stock_daily_data',engine,if_exists='append');
except Exception as e:
#如果写⼊数据库失败,写⼊⽇志表,便于后续分析处理
error_log=pd.DataFrame()
error_log['trade_date']=stock.Times
error_log['stock_code']=stock.Data[0]
error_log['start_date']=start_date
error_log['end_date']=end_date
error_log['status']=None
error_log['table']='stock_daily_data'
error_log['args']='Symbol: '+symbol+' From '+start_date+' To '+end_date
error_log['error_info']=e
error_log['created_date']=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
_sql('stock_error_log',engine,if_exists='append')
print ( CurrentTime(),": SQL Exception :%s" % (e) )
continue
w.start()
except Exception as e:
#如果读取处理失败,可能是⽹络中断、频繁访问被限、历史数据缺失等原因。写⼊相关信息到⽇志表,便于后续补充处理
error_log=pd.DataFrame()
error_log['trade_date']=stock.Times
error_log['stock_code']=stock.Data[0]
error_log['start_date']=start_date
error_log['end_date']=end_date
error_log['status']=None
error_log['table']='stock_daily_data'
error_log['args']='Symbol: '+symbol+' From '+start_date+' To '+end_date
error_log['error_info']=e
error_log['created_date']=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
_sql('stock_error_log',engine,if_exists='append')
print ( CurrentTime(),":index_data %s : Exception :%s" % (symbol,e) )
time.sleep(sleep_time)
w.start()
continue
CurrentTime(),": Downloading [",symbol,"] From "+start_date+" to "+end_date)
CurrentTime(),": Download A Stock Has Finished .")
def getAStockCodesFromCsv(self):
'''''
获取股票代码清单,链接数据库
'''
file_path=os.path.wd(),'Stock.csv')
stock_code = pd.read_csv(filepath_or_buffer=file_path, encoding='gbk')
Code=de
return Code
def getAStockCodesWind(end_date=time.strftime('%Y%m%d',time.localtime(time.time()))):
'''''
通过wset数据集获取所有A股股票代码,深市代码为股票代码+SZ后缀,沪市代码为股票代码+SH后缀。
如设定⽇期参数,则获取参数指定⽇期所有A股代码,不指定⽇期参数则默认为当前⽇期
:return: 指定⽇期所有A股代码,不指定⽇期默认为最新⽇期
'''
w.start()
#加⽇期参数取最指定⽇期股票代码
#stockCodes=w.wset("sectorconstituent","date="+end_date+";sectorid=a001010100000000;field=wind_code")
#不加⽇期参数取最新股票代码
stockCodes=w.wset("sectorconstituent","sectorid=a001010100000000;field=wind_code")
return stockCodes.Data[0]
#return stockCodes
def main():
'''''
主调函数,可以通过参数调整实现分批下载
'''
global engine,sleep_time,symbols
sleep_time=5
windStock=WindStock()
engine = create_engine('mysql://root:root@localhost/invest?charset=utf8')
#start_date='20100101'
#end_date='20131231'
#AStockCodesFromCsv()#通过⽂件获取股票代码
#AStockCodesWind()
#通过Wind API获取股票代码,默认取最新的,可以指定取历史某⼀⽇所有A股代码
#symbols=['000001.SZ', '000002.SZ', '000004.SZ']#通过直接赋值获取股票代码⽤于测试
#print (symbols)
#windStock.AStockHisData(symbols,start_date,end_date)
for i in range(2013,1990,-1):
start_date=str(i)+'0101'
end_date=str(i)+'1231'
print (start_date,end_date,'Starting')
AStockCodesWind()
windStock.AStockHisData(symbols,start_date,end_date)
print (start_date,end_date,'Finished')
def test():
'''''
测试脚本,新增和优化功能时使⽤
'''
symbol='000001.SZ'
start_date='20170101'
python index函数end_date='20170109'
#w.start();
#stock=w.wsd(symbol,'trade_code,open,high,low,close')
#stock=w.wsd(symbol, "trade_status,open,high,low,close,pre_close,volume,amt,dealnum,chg,pct_chg,vwap, adjfactor,close2,turn,free_turn,oi,oi_chg,pre_settle,settle,chg_settlement,pct_chg_settlement, lastradeday_s,last_trade_day,rel_ipo_    #stock=w.wsd("000001.SZ", "pre_close,open,high,low,close,volume,amt,dealnum,chg,pct_chg,vwap,adjfactor,close2,turn,free_turn,oi,oi_chg,pre_settle,settle,chg_settlement,pct_chg_settlement,lastradeday_s,last_trade_day,rel_ipo_chg,rel_ip    #print (stock)
for i in range(2014,1990,-1):
start_date=str(i)+'0101'
end_date=str(i)+'1231'
print (start_date,end_date)
if __name__ == "__main__":
main()
  MySQL建表脚本:
use invest ;
drop TABLE IF  EXISTS stock_daily_data ;
CREATE TABLE IF NOT EXISTS stock_daily_data (
index1 bigint(20) NOT NULL,
trade_date date NOT NULL COMMENT '交易⽇期',
stock_code varchar(100) NOT NULL COMMENT '股票代码',
open double DEFAULT NULL COMMENT '开盘价',
high double DEFAULT NULL COMMENT '最⾼价',
low double DEFAULT NULL COMMENT '最低价',
close double DEFAULT NULL COMMENT ' 收盘价,证券在交易⽇所在指定周期的最后⼀条⾏情数据中的收盘价',
volume double DEFAULT NULL COMMENT '成交量',
amt double DEFAULT NULL COMMENT '成交⾦额',
pct_chg double DEFAULT NULL COMMENT '涨跌幅=(收盘价/前收价-1)*100%',
dealnum double DEFAULT NULL COMMENT '成交笔数',
pre_close double DEFAULT NULL COMMENT '证券在交易⽇所在指定周期的⾸个前收盘价',
chg double DEFAULT NULL COMMENT '涨跌=收盘价-前收价',
swing double DEFAULT NULL COMMENT '振幅=[(最⾼价-最低价)/前收盘价]*100%',
vwap double DEFAULT NULL COMMENT '均价=成交⾦额/成交量',
adj_factor double DEFAULT NULL COMMENT 'Ext=X0*X1*...*Xt-1*Xt  Ext为T⽇分红复权因⼦  X0=1  Xt=Pt-1/Pext,其中Pext为T⽇前收盘价,Pt-1为T⽇前⼀个交易⽇收盘价。',
close2 double DEFAULT NULL COMMENT ' 收盘价,该指标⽀持定点复权,当复权⽅式选择为定点复权时,复权基期传⼊有效;否则⽆效。',
turn double DEFAULT NULL COMMENT '换⼿率=成交量/流通股本*100%',
free_turn double DEFAULT NULL COMMENT ' 换⼿率(⾃由流通股本)=成交量/⾃由流通股本*100%',
ev double DEFAULT NULL COMMENT '上市公司的股权公平市场价值。对于⼀家多地上市公司,区分不同类型的股份价格和股份数量分别计算类别市值,然后加总',
mkt_cap_ard double DEFAULT NULL COMMENT '按指定证券价格乘指定⽇总股本计算上市公司在该市场的估值。该总市值为计算PE、PB等估值指标的基础指标。暂停上市期间或退市后该指标不计算。',
pe_ttm double DEFAULT NULL COMMENT '分⼦=最近交易⽇收盘价*最新普通股总股数分母=归属母公司股东的净利润(TTM)*最近交易⽇转换汇率(记帐本位币转换为交易币种)返回=分⼦/分母',
val_pe_deducted_ttm double DEFAULT NULL COMMENT '扣⾮后的市盈率(TTM)=总市值/前推12个⽉扣除⾮经常性损益后的净利润',
pe_lyr double DEFAULT NULL COMMENT ' 每股股价为每股收益的倍数。可回测的估值指标。总市值2/
归属母公司股东净利润(LYR) 注: 1、总市值2=指定⽇证券收盘价*指定⽇当⽇总股本2、B股涉及汇率转换',
pb_lf double DEFAULT NULL COMMENT '普通股每股市价为每股净资产的倍数。总市值2/指定⽇最新公告股东权益(不含少数股东权益)注: 1、总市值2=指定⽇证券收盘价*指定⽇当⽇总股本2、B股涉及汇率转换',
pb_mrq double DEFAULT NULL COMMENT '每股股价为每股净资产的倍数。可回测的估值指标。总市值2/归属母公司股东的权益(MRQ)如财务报表币种与市值币种不同,则财务报表数据按报告期截⽌⽇汇率转换为市值币种。',  ps_ttm double DEFAULT NULL COMMENT '分⼦=最近交易⽇收盘价*最新普通股总股数 ;分母=销售收⼊(TTM)*最近交易⽇转换汇率(记帐本位币转换为交易币种); 返回=分⼦/分母',
ps_lyr double DEFAULT NULL COMMENT '每股股价为每股营业收⼊(LYR)的倍数。可回测的估值指标。总市值2/营业收⼊(LYR) 注:1、总市值2=指定⽇证券收盘价*指定⽇当⽇总股本 2、B股涉及汇率转换',
dividendyield2 double DEFAULT NULL COMMENT '股息率,也称股票获利率,是近12个⽉分配给股东的股息占股价的百分⽐。',
pcf_ocf_ttm double DEFAULT NULL COMMENT '每股股价为每股经营现⾦流(TTM)的倍数。可回测的估值指标。总市值2/经营现⾦净流量TTM ',
pcf_ncf_ttm double DEFAULT NULL COMMENT '分⼦=最近交易⽇收盘价*最新普通股总股数 ;分母=现⾦及现⾦等价物净增加额(TTM)*最近交易⽇转换汇率(记帐本位币转换为交易币种);返回=分⼦/分母',
pcf_ocflyr double DEFAULT NULL COMMENT ' 每股股价为每股经营现⾦流(LYR)的倍数。可回测的估值指标。总市值2/市现率(经营现⾦流LYR) 注:  1、总市值2=指定⽇证券收盘价*指定⽇当⽇总股本  2、B股涉及汇率转换',  pcf_ncflyr double DEFAULT NULL COMMENT '每股股价为每股净现⾦流(LYR)的倍数。可回测的估值指标。总市值2/现⾦净流量(LYR) 注: 1、总市值2=指定⽇证券收盘价*指定⽇当⽇总股本  2、B股涉及汇率转换',
trade_status varchar(100) DEFAULT NULL COMMENT '指定⽇该证券的市场交易状态,如正常交易、停牌。注:但⽇期参数为最新时,指最新的已收盘交易⽇。',
oi double DEFAULT NULL COMMENT '持仓量',
oi_chg double DEFAULT NULL COMMENT ' 持仓量变化',
pre_settle double DEFAULT NULL COMMENT ' 前结算价',
settle double DEFAULT NULL COMMENT '结算价',
chg_settlement double DEFAULT NULL COMMENT '涨跌(结算价)',
pct_chg_settlement double DEFAULT NULL COMMENT '涨跌幅(结算价)',
lastradeday_s date DEFAULT NULL COMMENT ' 表⽰某证券有交易的最新交易⽇期。',
last_trade_day date DEFAULT NULL COMMENT '表⽰某证券所在市场的最新⼀个交易⽇期。',
rel_ipo_chg double DEFAULT NULL COMMENT '相对发⾏价涨跌=指定交易⽇收盘价-⾸发价格',
rel_ipo_pct_chg double DEFAULT NULL COMMENT ' 相对发⾏价涨跌幅=[(指定交易⽇收盘价-⾸发价格)/⾸发价格]*100% 注:复权计算⽅法参见“⽇⾏情/收盘价”',
susp_reason varchar(200) DEFAULT NULL COMMENT '证券于某交易⽇停牌的原因。',
close3 double DEFAULT NULL COMMENT '指定交易⽇的收盘价,若⽆成交则返回为空。',
data_source varchar(100) NOT NULL DEFAULT 'Wind' COMMENT '数据来源',
created_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建⽇期',
updated_date datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新⽇期',
UNIQUE KEY idx_code_date (stock_code,trade_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `invest`.`stock_daily_data`
CHANGE COLUMN `index1` `index` BIGINT(20) NOT NULL ;

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论