2018/10/20~1
接触Python两个周了,对函数的调用还是不大熟悉,得多试试
1、得到数据
可以去大智慧前复权数据上找到需要的数据
也可以用爬虫去爬,不过爬来的东西自己看看就好…股票数据、成分指数名单
到手的数据长这样:
一群txt文本
txt文本里的样子
2015年到现在的信息都在这里啦,我们只要时间和收盘价,收盘价是第三列
这里是指数成分
开始了
1、画出某只股票的价格(以收盘价close为准),均线(包括5,10,20,30,60日均线),并在图中标注买点B1(5日均线上穿10日均线)和卖点S1(5日均线下穿10日均线), 买点B2(30日均线上穿60日均线)和卖点S2(30日均线下穿60日均线)。
准备工作:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
#图例输出中文
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
#数据文件的路径
url='stockdata\\'
先献上main方法:
if __name__=="__main__":
#1、找一股来画图
flieNum=input('请输入票号:\n')
flieNum=flieNum+'.txt'
stockData=getTxt('000002.txt')
stockData_ma=getMa(stockData)
drawingStockData_ma(stockData_ma)
#2、计算每一次交易获得的利润,是短期的高呢还是长期的高
B1,S1,B2,S2=BuySomeAndSellingPoint(stockData_ma)
shortProfits,longProfits=singleTransaction(B1,S1,B2,S2,stockData_ma)
#3、统计每一只股票所有交易次数的总利润,并保存到csv中
grossProfitStatistical()
#4、对所有股票的总利润求平均利润,对比两种交易信号,哪种交易信号获得的平均利润更大
averageProfit()
#5、按照指数成分股名单进行统计平均利润
indexComponent=indexComponent()
读取数据的方法:
def getTxt(fileName):
txt=open(url+fileName,'r', encoding='UTF-8')
t=pd.DataFrame(txt.readlines())
t=t[0].str.split(',')
list=[]
for i in t:
lists=[i[0],float(i[2])]
list.append(lists)
stockData=pd.DataFrame(list,columns=['日期','收盘价'])
return stockData
得到日均线:
#计算5,10,30,60的日均线
#传入stockData,得到各日均线
def getMa(stockData):
#需要得到的日均线集合
ma_list = [5,10,30,60]
# 计算简单算术移动平均线MA - 注意:stock_data['close']为股票每天的收盘价
for ma in ma_list:
#rolling_mean滚动平均值,见https://pandas.pydata.org/pandas-docs/version/0.23/generated/pandas.DataFrame.rolling.html
stockData[str(ma)+'日均线'] = stockData['收盘价'].rolling(ma).mean()
return stockData
因为要画图标点,所以先计算买卖点吧:
个人感觉这里不用这么麻烦,应该是有方法能找到画出的两条线的全部交点,知道第一个交点是上穿点还是下穿点后面的都知道了。。不过呢我没找到这个方法
#计算买卖点,可以缩短优化
def BuySomeAndSellingPoint(stockData):
ser5=stockData['5日均线']
ser10=stockData['10日均线']
ser30=stockData['30日均线']
ser60=stockData['60日均线']
B1=[]
B2=[]
S1=[]
S2=[]
#设置状态值,5日均线高于10日均线为True,反之这False
high1=False
for i in range(len(ser5)):
if i==9:
if ser5[i]>ser10[i]:
high1=True
if i>9:
if ser5[i]>ser10[i]:
if high1==False:
high1=True
B1.append(i)
else:
if high1==True:
high1=False
S1.append(i)
if len(S1)>len(B1):
S1.pop(0)
elif len(S1)<len(B1):
S1.append(len(ser5)-1)
high2=False
for i in range(len(ser30)):
if i==59:
if ser30[i]>ser60[i]:
high2=True
if i>59:
if ser30[i]>ser60[i]:
if high2==False:
high2=True
B2.append(i)
else:
if high2==True:
high2=False
S2.append(i)
if len(S2)>len(B2):
S2.pop(0)
elif len(S2)<len(B2):
S2.append(len(ser5)-1)
return B1,S1,B2,S2
计算出买卖点后,开始画图:
#对各个均线进行绘图,并标注买点bB1、B2,卖点S1、S2
def drawingStockData_ma(stockData_ma):
# stockDatas=pd.DataFrame(list(zip(stockData_ma['收盘价'],stockData_ma['5日均线'],stockData_ma['10日均线'],stockData_ma['30日均线'],stockData_ma['60日均线'])),
# columns = ['收盘价','5日均线','10日均线','30日均线','60日均线'],index=stockData_ma['日期'])
B1,S1,B2,S2=BuySomeAndSellingPoint(stockData_ma)
stockDatas=stockData_ma.set_index('日期',drop=True)
stockDatas.plot(grid=True)
#标点
for i in B1:
plt.annotate("B1",xy = (i, stockData_ma['5日均线'][i]))
for i in B2:
plt.annotate("B2",xy = (i, stockData_ma['30日均线'][i]))
for i in S1:
plt.annotate("S1",xy = (i, stockData_ma['10日均线'][i]))
for i in S2:
plt.annotate("S1",xy = (i, stockData_ma['60日均线'][i]))
plt.show()
到了这差不多就能划出一股股票的图了。。效果如下:
貌似不大清楚。。加个放大的吧
看看5日上传10日的买法赚还是30日上传60日的买法赚:
这里计算的是我们刚才放进来的那一股,不是全部的,嘿嘿
#计算每一次交易获得的利润,有两种交易方法
#传入B1,S1,B2,S2,stockData_ma, 传出短利润集合、长利润集合
def singleTransaction(B1,S1,B2,S2,stockData_ma):
#第一种交易方式
shortProfits=[]
for i in range(len(B1)):
shortProfits.append(stockData_ma['收盘价'][S1[i]]-stockData_ma['收盘价'][B1[i]])
#第二种交易方式
longProfits=[]
for i in range(len(B2)):
longProfits.append(stockData_ma['收盘价'][S2[i]]-stockData_ma['收盘价'][B2[i]])
return shortProfits,longProfits
统计每一只股票所有交易次数的总利润,建议读取文件的时候用下多线程,慢死了。。。
#统计每一只股票所有交易次数的总利润,按两种方法分别统计,结果输出到2个csv文件中,字段包含股票代码,交易次数,总利润。
def grossProfitStatistical():
#得到当前股票文本的目录
files=os.listdir(url)
#遍历目录
#新建一个dataframe
rows_list1 = []
rows_list2 = []
for file in files:
#得到训练集的结果,文件名中‘_'的前面部分
name=file[:file.index('.')]
#得到stockData
stockData=getTxt(file)
#得到日均线
stockData=getMa(stockData)
#得到各个点
B1,S1,B2,S2=BuySomeAndSellingPoint(stockData)
#统计该股股票的利润
shortProfits,longProfits=singleTransaction(B1,S1,B2,S2,stockData)
#将利润合计
shortProfit=sum(shortProfits)
longProfit=sum(longProfits)
rows_list1.append([name,len(B1),shortProfit])
rows_list2.append([name,len(B2),longProfit])
newDF1=pd.DataFrame(rows_list1,columns = ['Stock code','Transaction number','shortProfit'])
newDF2=pd.DataFrame(rows_list2,columns = ['Stock code','Transaction number','longProfit'])
newDF1.to_csv('shortProfit.csv',index=0)
newDF2.to_csv('longProfit.csv',index=0)
导入grossProfitStatistical()得到的csv文件,计算在当前这些数据下哪种交易的方式利润大
#对所有股票的总利润求平均利润,对比两种交易信号,哪种交易信号获得的平均利润更大。
def averageProfit():
#导入grossProfitStatistical()得到的csv文件
shortProfit=pd.read_csv('shortProfit.csv')
longProfit=pd.read_csv('longProfit.csv')
#求和在除以股票总数
averageShortProfit=shortProfit['shortProfit'].sum()/len(shortProfit)
averageLongProfit=longProfit['longProfit'].sum()/len(longProfit)
if averageShortProfit>averageLongProfit:
print('短期交易的方式利润大')
else:
print('长期交易的方式利润大')
还是对比两种交易方式,但是加入了一个指数成分
#按照指数成分股名单进行统计平均利润,看看这2种交易方法在哪种成分指数可以获得最大的平均利润。
def indexComponent():
#得到指数成分股的名单
indexComponent=pd.read_excel('金融数据分析项目实训.xlsx',sheet_name='成分指数名单')
#导入grossProfitStatistical()得到的csv文件
shortProfit=pd.read_csv('shortProfit.csv')
longProfit=pd.read_csv('longProfit.csv')
#输入需要比对的指数成分,如 上证50
index=input('请输入需要比对的指数成分股:\n')
#得到对应的股票id,并删除空值
ser = indexComponent[index].dropna()
#找出对应的股份利润
df1=shortProfit[shortProfit['Stock code'].isin(ser)]
df2=longProfit[longProfit['Stock code'].isin(ser)]
averageShortProfit=df1['shortProfit'].sum()/len(df1)
averageLongProfit=df2['longProfit'].sum()/len(df2)
if averageShortProfit>averageLongProfit:
print(index+'短期交易的方式利润大')
else:
print(index+'长期交易的方式利润大')
return df1
看看结果吧:
导出的csv文件就不看了吧。。
总结
使用了matplotlib和pandas,还是不大熟练,路还长呀。。。
话说,不会有人真拿这东西去炒股吧