一直想做python本地量化,找不到合适的资料,好多视频都是在第三方平台的(确实第三方方便很多,什么回测啊,还有很多东西),下载本地的很少,反正我是小白,那就自己从头弄了找资料吧
我只有晚上偶尔做,到目前做了两天的晚上,合并一起发了吧(其实今天是第三天了)
先说自己,python会一些,量化的pandas和NumPy不是很熟,股票也有接触快8年了
自己有一些自己的策略,但是不好回顾好不好,哪里好(坏),为什么好(坏),本来同一个指标的不可能永远有效,所以多策略就很重要,觉得还是要自己量化,才能更好的复盘和统计
数据获取方法有很多,爬虫和第三方的也不细说,对于我偏技术的来说,年报,板块对我都没意义,跟庄就行,没庄家就没意义,而且我目前以复盘为主,就日线级别的足够,我选择了tushare
tushare是两个版本,最新是tushare.pro,用日线的话,还是免费的,就他了吧
第一天,
小目标:先说思路,一步一步来,那就先找一个股票数据。
想办法获取某个股票的数据,找了好久,找到的资料是这位大神的,写得很细
001 用python和tushare获取股票数据_python tushare获取股票数据_wxyczhyza的博客-CSDN博客
我就一步一步来,先获取单个的股票数据,画图我也不擅长,先不管,把第一步做好,就下载数据吧
import datetime
import os.path
import threading
import requests.exceptions
import tushare as ts
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#画图用
import seaborn as sns
#token 是tushare.pro 的
token_str ='自己官网获取的token'
pro = ts.pro_api(token_str)
start = datetime.date(2013,1,1).strftime('%Y%m%d')
end = datetime.date.today().strftime('%Y%m%d')
stock_code = '300474.SZ'
dfdemo = ts.pro_bar(ts_code='{}'.format(stock_code),adj='qfq',freq='D',start_date=start,end_date=end)
dfdemo = dfdemo.sort_index(ascending=False)
root_path = r'J:\Python\django_projects\liangHua\gupiao\database'
发现没有保存,我觉得保存的话,可能更好
又找了一会儿,找到这篇
【手把手教你如何从Tushare库下载股票数据,并保存在硬盘当中。第二篇下载存储数据】_tushare下载_Mike_Leigh的博客-CSDN博客
就用to_csv就把数据保存了
def save_csv(stock,csv_file):
paths = {
"stdev":root_path + "\\stdev\\",
"tester":root_path + "\\tester\\"
}
for name,path in paths.items():
csv_file.to_csv(path + "%s.csv" % stock,encoding="GBK",index = False)
# csv_file.to_csv(root_path + r"\tester2" + "%s.csv" % os.path.splitext(stock)[0],encoding="GBK",index = False)
第一天遇见一些小问题,就是不知道为什么要放stdev,tester以及tester2三个文件,数据都是一样的,难道其中一个是备份?到现在不是特别清楚
后面就单独只保存
第一天做好已经12点了,就休息了
中间还有两个小问题,1是我明明设置起始时间很早,但是300474.SZ就只有2016年之后的,后面测试画图(后期应该暂不考虑作图)的时候才反应过来,人家2016才上市,所以就没得2016年之前的数据了、2是to_csv不熟,用成tocsv,没有下划线,本来没提示,找了半天才知道原因
**********分隔符**********
第二天,自己定了一个目标,那就是找到所有的股票,并下载
感觉不难吧,就做了
获取所有股票相信有两个方法,我看了下就用了其中一个,博客地址忘了,贴代码吧
all_stock_data = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')
print(all_stock_data)
获取了就保存,但是一般不会有新股,再说我考虑新股,所以对我来说,所有的列表,几个月更新一次我都没问题,就做了一个判断
def all_stock():
all_stocks_file = os.path.join(root_path,f'toAll','all_stocks.csv')
print(all_stocks_file)
if os.path.exists(all_stocks_file):
print("所有列表已存在")
all_stock_data = pd.read_csv(all_stocks_file,encoding="GBK",converters={'symbol': str})
print(all_stock_data)
else:
all_stock_data = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')
print(all_stock_data)
print("所有列表重新下载")
all_stock_data.to_csv(all_stocks_file,encoding="GBK",index = False)
return all_stock_data
但是发现有问题了,保存的文件,打开是这的.
00开头的,就看不见了,我勒个去,那还了得,保存前Pycharm打印了,是有的,网上搜了半小时多,什么to_csv参数和QUOTE_MINIMALl参数,找不到合适的方法,中间狂搜了半小时
后面边搜边想问题在哪儿,看见说read_csv一下,好吧,还是被省略了,没得前面的0开头的
再后来有评论说用文本打开保存的csv文件,结果notepad打开,居然是在的,有000001,那看来WPS读取的时候自动省略了,那为什么read_csv不行呢,后面发现要带一个参数,就是converters={'symbol': str}
然后就OK了
接下来就是保存所有股票了,用的多线程,其实第二天没保存完,下载了十几分钟样子吧,才下载1000个左右,总共5000个票,感觉下载有点慢,而且还是比较好奇之后每天怎么更新
先给多线程代码吧,这个挺简单的
def duoxiancheng_download():
tasks = []
thread_num = 5
for tn in range(thread_num):
tn = threading.Thread(target=save_all_stock(),name=f"线程{tn}正在运行……")
tn.start()
tasks.append(tn)
for task in tasks:
task.join()
今天其实是第三天了,先把文章写了,避免后面代码改的面目全非。
昨天用的5个线程,记得tushare积分低的有限制,我就120标准分,线程多了也是被限制的,后面想想怎么优化吧,毕竟后期应该是爬取某天开始的,而不是每次从头开始获取数据
昨天大概14分钟1089个文件,大概是1min保存77个吧,但是昨天是保存两个目录
今天试了最多100个线程(其实应该跑不到,具体多少后面再看,得看服务器允许的线程),今天就保存在一个目录了,毕竟同时保存,还不如我最后copy文件夹内容更快,现在平均1min大概保存是191个csv文件,其实688开头的我也用不上,没研究,后面可能股票更少一点吧,后面想办法再优化
PS:现在过了20min了,下载还是在1200个左右,看来是跟昨天一样的效率,之后还是5个线程吧
每日更新的追加数据还没弄,应该不难,但是得提升日程,主要是csv排序,到底最新时间在第一行还是最后一行好,抽空研究吧
我觉得后面的目标还是先从单个股票研究下把,例如MACD,金叉买死叉卖,对比股票软件,对得上时间点就行,然后做个统计的,这些就是后面的目标吧
现在都接近10点了,写了一个多小时,哎,贴上所有代码,闪人
import datetime
import os.path
import threading
import requests.exceptions
import tushare as ts
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#画图用
import seaborn as sns
#token 是tushare.pro 的
token_str ='省略号,需要自己的API的token'
#https://tushare.pro/register?reg=458230 我分享链接,从这里注册一个吧
pro = ts.pro_api(token_str)
start = datetime.date(2013,1,1).strftime('%Y%m%d')
end = datetime.date.today().strftime('%Y%m%d')
stock_code = '300474.SZ'
dfdemo = ts.pro_bar(ts_code='{}'.format(stock_code),adj='qfq',freq='D',start_date=start,end_date=end)
dfdemo = dfdemo.sort_index(ascending=False)
root_path = r'J:\Python\django_projects\liangHua\gupiao\database'
def save_csv(stock,csv_file):
paths = {
"stdev":root_path + "\\stdev\\",
# "tester":root_path + "\\tester\\"
}
for name,path in paths.items():
csv_file.to_csv(path + "%s.csv" % stock,encoding="GBK",index = False)
# csv_file.to_csv(root_path + r"\tester2" + "%s.csv" % os.path.splitext(stock)[0],encoding="GBK",index = False)
def stock4show():
dfdemo.index = dfdemo['trade_date']
dfdemo['close'].plot(figsize=(12,6))
plt.ylabel("close price")
plt.show()
def all_stock():
all_stocks_file = os.path.join(root_path,f'toAll','all_stocks.csv')
print(all_stocks_file)
if os.path.exists(all_stocks_file):
pass
print("所有列表已存在")
all_stock_data = pd.read_csv(all_stocks_file,encoding="GBK",converters={'symbol': str})
print(all_stock_data)
else:
all_stock_data = pro.stock_basic(exchange='', list_status='L', fields='ts_code,symbol,name,area,industry,list_date')
print(all_stock_data)
# df = pd.DataFrame(all_stock_data)
print("所有列表重新下载")
all_stock_data.to_csv(all_stocks_file,encoding="GBK",index = False)
return all_stock_data
def save_all_stock():
all_stock_data = all_stock()
for stock_code in all_stock_data["ts_code"]:
try:
df = ts.pro_bar(ts_code='{}'.format(stock_code), adj='qfq', freq='D', start_date=start, end_date=end)
save_csv(stock_code,df)
except requests.exceptions.ProxyError:
print("Log:{}保存有误".format(stock_code))
continue
def duoxiancheng_download():
tasks = []
thread_num = 100
for tn in range(thread_num):
tn = threading.Thread(target=save_all_stock(),name=f"线程{tn}正在运行……")
tn.start()
tasks.append(tn)
for task in tasks:
task.join()
if __name__ == '__main__':
# save_csv(stock_code,dfdemo)
# stock4show()
# all_stock()
# save_all_stock()
duoxiancheng_download()