1.在banban网爬取所有A股的股票名称和代码。

观察板板网站的股票,将在深圳上市和上海上市的A股信息爬取并保存到本地文件

2.传入股票代码,利用tushare api提取股票的所有历史数据,对股票数据进行处理。

3.设置双均线,KDJ,MACD等指标辅助量化。

4.设置资金曲线,利用历史数据回测,评估策略效果。

如下是用双均线策略来进行买入卖出交易的模拟得到的预计资金曲线,短线取的时间是5个交易日,长线取的时间是20个交易日,选用的股票是000625 长安汽车:

可以看出我们的预计资金曲线是运用此策略12年买入的话,10000可以涨到19000的样子,看似还不错,但是当我们去和该支股票的波动率进行对比之后会大失所望:

总python运行的数据来看,长安汽车股价翻了接近5倍,而我们的双均线带来的收益连一倍都不到,所以针对长安汽车,双均线策略的策略数值MA_short=5&MA_long=20不适合,可循环遍历找出最适合该支股票的均线策略数值。

源代码如下:

源代码

import pandas as pd
import tushare
import datetime
import numpy as np
from lxml import html
import requests
import re
import time
import pymongo
import threading
import mplfinance as mpf
import matplotlib.pyplot as plt
import talib
import matplotlib
from pyecharts.charts import Grid
from pyecharts import options as opts
import threadingimport queue
#token='69eb8e86b28f824d35309a425404600978c064485417896a59667f66'
#pro=tushare.pro_api(token)
#data=pro.daily(ts_code='600010.SS',start_date='20090101',end_date='20190601')def zeshicelue(daihao,name):
#tushare的api获取包钢股份的数据data=tushare.get_k_data(daihao,start='2011-1-1',end='')#end为空值取当前时间,start为空值取去年今日df=pd.DataFrame(data)#数据预处理df.index=pd.to_datetime(df['date'])df=df.drop(axis=1,columns='date')df['scope']=(df.close/df.open)-1#print(df[abs(df.scope)>=0.11])#不加df时是bool判断,加了df之后是输出df中为true的行#print(df[abs(df.scope)>=0.11].index)#[54,107,859,904,2232,2319]返回的是满足条件的index序列df=df.drop(df[abs(df.loc[:,'scope'])>0.12].index)#按index序列去drop该行数据#定义长短均线,买入卖出信号,仓位信息等ma_short=5ma_long=20df['ma_short']=df['close'].rolling(ma_short,min_periods=1).mean()df['ma_long']=df['close'].rolling(ma_long,min_periods=1).mean()df['ma_short-1']=df['close'].shift(1).rolling(ma_short,min_periods=1).mean()df['ma_long-1']=df['close'].shift(1).rolling(ma_long,min_periods=1).mean()condition1=df['ma_short']-df['ma_long']#当天的短期均线与长期均线的差值condition2=df['ma_short-1']-df['ma_long-1']#上个交易日的短期均线与上个交易日的长期均线的差值df.loc[(condition1>=0)&(condition2<=0),'B|S']=1#买入信号df.loc[(condition1<0)&(condition2>0),'B|S']=0#卖出信号#初始仓位管理df['pos']=df['B|S'].shift(1)#初始化仓位信息#计算ATR值df['ATR14']=talib.ATR(df['high'].values,df['low'].values,df['close'].values,timeperiod=14)df['ATR14'].fillna(method='bfill',inplace=True)# 止盈止损#初始化变量rate1=5/10000#买卖时的手续费rate2=1/1000#卖时的印花税slippage=0.01#买卖时的价格滑点zhangting=(df['open'])-(df['close'].shift(1)*1.097)#开盘即涨停df.loc[zhangting>0,'pos']=np.nandieting=(df['open'])-(df['close'].shift(1)*0.9)#开盘即跌停df.loc[dieting<=0,'pos']=np.nandf['pos'].fillna(method='ffill',inplace=True)#将不能变化和nan的仓位设置为上个仓位的值#print(df.loc[(df['B|S']==1)|(df['B|S']==0)])money_start=10000#定义初始资金1万元#定义资金状况变化df.loc[df.index[0],'hold_num']=0#初始化持股数为0df.loc[df.index[0],'money']=money_start#初始化剩余的钱总数df.loc[df.index[0],'property']=money_start#初始化总资产df['money'].fillna(method='ffill',inplace=True)df['property'].fillna(method='ffill',inplace=True)df['pos'].fillna(0,inplace=True)for i in range(1,df.shape[0]):if df.loc[df.index[i],'pos']>df.loc[df.index[i-1],'pos']:#仓位不够,加仓买入df.loc[df.index[i],'hold_num']=(df.loc[df.index[i],'pos'])*(df.loc[df.index[i-1],'property'])/(df.loc[df.index[i],'open']+slippage)//100*100if (df.loc[df.index[i],'money']<((df.loc[df.index[i],'hold_num']-df.loc[df.index[i-1],'hold_num'])*(df.loc[df.index[i],'open']+slippage))):#加仓的钱不够df.loc[df.index[i],'hold_num']=df.loc[df.index[i],'hold_num']-100#钱不够,自动少买1手if ((df.loc[df.index[i],'hold_num']-df.loc[df.index[i-1],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*rate1)>=5:#手续费超过5块df.loc[df.index[i],'money']=df.loc[df.index[i-1],'property']-((df.loc[df.index[i],'hold_num']-df.loc[df.index[i-1],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*(1-rate1))df.loc[df.index[i],'shouxufei']=((df.loc[df.index[i],'hold_num']-df.loc[df.index[i-1],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*rate1)else:df.loc[df.index[i],'money'] = df.loc[df.index[i-1],'property'] - ((df.loc[df.index[i],'hold_num']-df.loc[df.index[i-1],'hold_num'])*(df.loc[df.index[i],'open']+slippage))-5#开盘就买df.loc[df.index[i],'shouxufei']=5else:df.loc[df.index[i],'hold_num']=df.loc[df.index[i],'hold_num']if ((df.loc[df.index[i],'hold_num']-df.loc[df.index[i-1],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*rate1)>=5:#手续费超过5块df.loc[df.index[i],'money']=df.loc[df.index[i-1],'property']-((df.loc[df.index[i],'hold_num']-df.loc[df.index[i-1],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*(1-rate1))df.loc[df.index[i],'shouxufei']=((df.loc[df.index[i],'hold_num']-df.loc[df.index[i-1],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*rate1)else:df.loc[df.index[i],'money'] = df.loc[df.index[i-1],'property'] - ((df.loc[df.index[i],'hold_num']-df.loc[df.index[i-1],'hold_num'])*(df.loc[df.index[i],'open']+slippage))-5#开盘就买df.loc[df.index[i],'shouxufei']=5df.loc[df.index[i],'property']=df.loc[df.index[i],'money']+(df.loc[df.index[i],'hold_num']*df.loc[df.index[i],'close'])#算资产时用收盘价if df.loc[df.index[i],'pos']==df.loc[df.index[i-1],'pos']:#仓位不变df.loc[df.index[i],'hold_num']=df.loc[df.index[i-1],'hold_num']df.loc[df.index[i],'money']=df.loc[df.index[i-1],'money']df.loc[df.index[i],'property']=df.loc[df.index[i],'money']+(df.loc[df.index[i],'hold_num']*df.loc[df.index[i],'close'])df.loc[df.index[i],'shouxufei']=0if df.loc[df.index[i],'pos']<df.loc[df.index[i-1],'pos']:#仓位过多,减仓卖出if df.loc[df.index[i],'pos']!=0:df.loc[df.index[i],'hold_num']=df.loc[df.index[i-1],'property']*df.loc[df.index[i],'pos']/df.loc[df.index[i],'open']//100*100if ((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*rate1)>=5:#手续费超过5块df.loc[df.index[i],'money']=df.loc[df.index[i-1],'money']+((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']-slippage)*(1-rate1)*(1-rate2))#开盘就卖,卖出加印花税df.loc[df.index[i],'shouxufei']=((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*rate1)+(df.loc[df.index[i],'hold_num']*(df.loc[df.index[i],'open']-slippage)*rate2)else:df.loc[df.index[i],'money']=df.loc[df.index[i-1],'money']+((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']-slippage)*(1-rate2))-5df.loc[df.index[i],'shouxufei']=5+((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']-slippage)*rate2)df.loc[df.index[i],'property']=df.loc[df.index[i-1],'money']+(df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*df.loc[df.index[i],'close']#算资产时用收盘价else:df.loc[df.index[i],'hold_num']=df.loc[df.index[i-1],'property']*df.loc[df.index[i],'pos']/df.loc[df.index[i],'open']//100*100if ((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*rate1)>=5:#手续费超过5块df.loc[df.index[i],'money']=df.loc[df.index[i-1],'money']+((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']-slippage)*(1-rate1)*(1-rate2))  # 开盘就卖,卖出加印花税df.loc[df.index[i],'shouxufei']=((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']+slippage)*rate1)+(df.loc[df.index[i],'hold_num']*(df.loc[df.index[i],'open']-slippage)*rate2)else:df.loc[df.index[i],'money']=df.loc[df.index[i-1],'money']+((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']-slippage)*(1-rate2))-5df.loc[df.index[i],'shouxufei']=5+((df.loc[df.index[i-1],'hold_num']-df.loc[df.index[i],'hold_num'])*(df.loc[df.index[i],'open']-slippage)*rate2)df.loc[df.index[i],'property']=df.loc[df.index[i],'money']#hold_num=0时,资产和money现金相等#print(df['money'],df['property'],df['hold_num'])#df['hold_num']=(money_start*df['pos']/df['open'])//100#持股总数#df['money']=money_start-df['open']*df['hold_num']#剩余的钱总数#df['property']=df['hold_num']*df['close']+df['money']#总资产#df.iloc[0].loc['money']=10000#print(df)#跳空缺口threshold=10#缺口阈值jump_power1=(df['low']-df['high'].shift(1))/threshold#向上跳空jump_power2=(df['high']-df['low'].shift(1))/threshold#向下跳空df.loc[(jump_power1>=1),'th']=1df.loc[(jump_power2<=-1),'th']=-1#观察区间c1=1900c2=2000#画蜡烛图#日Kmpf.plot(df.iloc[c1:c2,],type='candle',mav=(3,6,9),volume=True)#画蜡烛图,颜色改变不了,白涨黑跌#周Kopen=df.iloc[c1:c2]['open'].resample('W-FRI',closed='right',label='right').first()close=df.iloc[c1:c2]['close'].resample('W-FRI',closed='right',label='right').last()high=df.iloc[c1:c2]['high'].resample('W-FRI',closed='right',label='right').max()low=df.iloc[c1:c2]['low'].resample('W-FRI',closed='right',label='right').min()volume=df.iloc[c1:c2]['volume'].resample('W-FRI',closed='right',label='right').sum()dict={'open':open,'high':high,'low':low,'close':close,'volume':volume}df2=pd.DataFrame(dict)df2=df2.dropna(how='any')#print(df2)mpf.plot(df2,type='candle',volume=True)#KDJlow_list=df['low'].rolling(9,min_periods=1).min()high_list=df['high'].rolling(9,min_periods=1).max()RSV=(df['close']-low_list)/(high_list-low_list)*100#根据RSV值的大小可判断市场的超买超卖现象,大超买,小超卖df['K']=RSV.ewm(com=2,adjust=False).mean()df['D']=df['K'].ewm(com=2,adjust=False).mean()df['J']=3*df['K']-2*df['D']#MACDEMA12=df['close'].ewm(span=12,adjust=False).mean()EMA26=df['close'].ewm(span=26,adjust=False).mean()df['MACD_DIF']=EMA12-EMA26df['MACD_DEA']=df['MACD_DIF'].ewm(span=9,adjust=False).mean()df['MACD']=2*(df['MACD_DIF']-df['MACD_DEA'])#print(df['MACD'])#画均线图plt.subplot(221)#print(df.columns.values.tolist())#print(df.iloc[:,9].keys)plt.rcParams['font.sans-serif']='SimHei'#必须设置中文字体格式,不然图例显示不出来,只能作用到单一类图上,两类图的话需要再定义一遍plt.plot(df.iloc[c1:c2].index,df.iloc[c1:c2]['ma_short'],label='短期均线')plt.plot(df.iloc[c1:c2].index,df.iloc[c1:c2]['ma_long'],label='长期均线')#print(df.iloc[c1:c2].loc[df.iloc[c1:c2]['B|S']==0])dict={'facecolor':'black','shrink':0.05}plt.annotate('死叉',df.iloc[c1:c2].loc[df.iloc[c1:c2]['B|S']==0.0].index,df.iloc[c1:c2].loc[df.iloc[c1:c2]['B|S']==0.0]['ma_short'])plt.legend()plt.xticks(rotation=45)#旋转横坐标标签45度#画KDJ线图plt.subplot(222)plt.plot(df.iloc[c1:c2].index,df.iloc[c1:c2]['K'],label='K值线')plt.plot(df.iloc[c1:c2].index,df.iloc[c1:c2]['D'],label='D值线')plt.plot(df.iloc[c1:c2].index,df.iloc[c1:c2]['J'],label='J值线')plt.legend()plt.xticks(rotation=45)#旋转横坐标标签45度#K值线对应均线中的短线,D值线对应均线中的长线,K值线从下上穿D值线时,买入信号;反之则反#画MACD图plt.subplot(223)plt.plot(df.iloc[c1:c2].index,df.iloc[c1:c2]['MACD'],label='MACD')plt.plot(df.iloc[c1:c2].index,df.iloc[c1:c2]['MACD_DIF'],label='MACD_DIF')plt.plot(df.iloc[c1:c2].index,df.iloc[c1:c2]['MACD_DEA'],label='MACD_DEA')bar_red=np.where(df.iloc[c1:c2]['MACD']>0,df.iloc[c1:c2]['MACD'],0)bar_green=np.where(df.iloc[c1:c2]['MACD']<0,df.iloc[c1:c2]['MACD'],0)plt.bar(df.iloc[c1:c2].index,bar_red,facecolor='red',label='hist bar')plt.bar(df.iloc[c1:c2].index,bar_green,facecolor='green',label='hist bar')plt.legend()plt.xticks(rotation=45)#旋转横坐标标签45度#print(df.loc[:,'date'])#print(df['pos'])#print(df['money'])#MACD_DIF线对应短线,MACD_DEA线对应长线,当MACD_DIF线从下上穿MACD_DEA线时,买入信号;反之则反#画资金曲线图plt.subplot(224)plt.plot(df.index,df['property'],label='资金曲线')plt.xticks(rotation=45)plt.legend()plt.show()shouxufei_sum=0for s in range(df.shape[0]):df['shouxufei'].fillna(0,inplace=True)shouxufei_sum=shouxufei_sum+df.loc[df.index[s],'shouxufei']shouxufei_sum=round(shouxufei_sum,3)#手续费保留3位小数print('手续费花费金额:',shouxufei_sum)surge_price_rate=(df.loc[df.index[-1],'close']-df.loc[df.index[0],'open'])/df.loc[df.index[0],'open']#股价从开盘到目前的波动率print('{}股票从开盘到现在的波动价格率:'.format(name),surge_price_rate)surge_money_rate=(df.loc[df.index[-1],'property']-df.loc[df.index[0],'property'])/df.loc[df.index[0],'property']print('{}股票从开盘到现在的投资资金波动率:'.format(name),surge_money_rate)if surge_price_rate>surge_money_rate:print('均线策略系数对此股不合适,没有跑赢大盘,需调整系数')else:print('均线策略系数对此股合适,跑赢了大盘')df.to_csv(r'D:\A股择时策略结果文档\{}.csv'.format(name),mode='w',encoding='utf-8')print('{}股票策略分析完成'.format(name))#grid=Grid()#grid.add(bar1,grid_opts=opts.GridOpts(pos_left="3%", pos_right="1%", height="20%"))#grid.add(bar2,grid_opts=opts.GridOpts(pos_left="3%", pos_right="1%", height="30%",pos_top="50%"))
#爬虫股票信息,传回择时函数中
def getcode(url):#url='https://www.banban.cn/gupiao/list_sz.html'headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36'}response=requests.get(url,headers=headers).contentetree1=html.etree.HTML(response)name_list=[]daihao_list=[]for d in range(1,1483):try:etree2=etree1.xpath('//*[@id="ctrlfscont"]/ul/li[{}]/a/text()'.format(d))name=re.search(r'[\u4e00-\u9fa5]+',str(etree2)).group(0)daihao=re.search(r'\d+',str(etree2)).group(0)name_list.append(name)daihao_list.append(daihao)#gupiao1=zeshicelue(daihao,name)print('第{}支股票完成'.format(d))except:print('网络错误,重试中,请稍候!')d=d-1dict={'name':name_list,'code':daihao_list}dataframe=pd.DataFrame(dict)dataframe.to_csv(r'C:\Users\asus\Desktop\股票代码.csv',mode='ab')
url1='https://www.banban.cn/gupiao/list_sz.html'#深圳上市股票
url2='https://www.banban.cn/gupiao/list_sh.html'#上海上市股票
url_list=[url1,url2]
for i in range(2):if i==0:print('爬取深圳上市股票中')#getcode1=getcode(url_list[i])else:print('爬取上海上市股票中')#getcode1=getcode(url_list[i])#t=threading.Thread(target=getcode,args=(url_list[i],))#t.start()
dataframe2=pd.read_csv(r'C:\Users\asus\Desktop\股票代码.csv')
starttime=time.time()
#print(dataframe2.name)
for i in range(dataframe2.shape[0]):name=dataframe2.name[i]daihao=str(dataframe2.code[i])#excel表格的0开头数字会自动省略,如下处理if len(daihao)==1:daihao='00000'+str(daihao)if len(daihao)==2:daihao='0000'+str(daihao)if len(daihao)==3:daihao='000'+str(daihao)if len(daihao)==4:daihao='00'+str(daihao)if len(daihao)==5:daihao='0'+str(daihao)if len(daihao)==6:daihao=daihao#print(daihao)#zeshicelue1=zeshicelue(daihao,name)
zeshicelue2=zeshicelue('000625','长安汽车')
endtime=time.time()
print('总计时长:',endtime-starttime)
print('运行完成')

python量化交易--择时策略相关推荐

  1. Python量化交易03——海龟策略

    参考书目:深入浅出Python量化交易实战 海龟策略也是经典中的经典.其核心要点是:在股价超过过去的N天交易日的最高点时是买入信号,跌破过去的N天交易日的最低点时是卖出信号.最高点和最低点的通道被称为 ...

  2. 4、Python量化交易-双均线策略

    目录 一.数据准备 二.5日均线和30日均线 1 - 均线的概念 2 - 计算5日均线与30日均线 3 - 画出MA5和MA30 三.金叉和死叉 1 - 金叉和死叉概念 2 - 分析所有金叉日期和死叉 ...

  3. python量化交易--因子选股策略

    Fama-French三因子选股策略,三因子分别为  市场因子(股指).市值因子.账面市值比因子 三因子模型的具体步骤: 1.对股票按照市值和账面市值比分组,共计六组,市值按大小市值各50%分,账面市 ...

  4. 6、Python量化交易-单均线策略升级1:T+0限制

    目录 前言 T+0限制实现思路 一.调整买卖比例并统计pnl 1 - 在main中添加统计pnl 2 - 调整买入比例0.98,卖出比例1.02 3 - 获取pnl值 二.策略添加T+0限制 1 - ...

  5. 【Python 量化交易】什么是择时策略

    量化金融:什么是择时策略? 什么是市场择时? 市场择时概要 择时成本 损失机会的代价 交易成本的代价 真实例子 什么是市场择时? 市场择时,也可以叫做市场选时,是一种投资或者交易的策略.是一种基于某种 ...

  6. 量化择时策略入门与实操-笔记(同花顺金融量化实验室python实现)

    文字与代码来源:2022年第三届"大湾区杯"粤港澳金融数学建模竞赛在线讲座-6_哔哩哔哩_bilibili 目录 指数估值择时策略 指数轮动择时策略 基于风险平价模型的仓位管理策略 ...

  7. 添加布林带择时策略有多便捷!股票量化分析工具QTYX-V2.4.7

    前言 布林带通道(Bollinger Bands)是非常经典的技术指标,常用于研判市场中长期运动趋势. 比如我们以[350, 2,2] 这组长线参数来绘制恒瑞医药.贵州茅台10年行情走势的布林带通道, ...

  8. 《深入浅出Python量化交易实战》:散户也能学会的数字化交易策略

    前言 您可能不知道,许多专业的交易机构已经采用设定程序完成自动化交易,通过机器语言,解密盘面的走势,从而实现持续盈利的目的. (文末送读者福利) 这并非什么秘密,他们正是借助了这样的数字化工具进行操作 ...

  9. 使用python量化交易接口有哪些分析指标和策略?

    量化交易有哪些指标可以用于分析呢?主要有技术面和基本面可以用于分析! 来看一下技术面和基本面有什么区别? 技术面更关注具体的价格,比如每天的开盘价.收盘价.以及和开盘价/收盘价/最低价/最高价相关的K ...

最新文章

  1. 2022-2028年中国塑料导爆管行业市场调查研究及前瞻分析报告
  2. python loop call soon_从“call\u soon”回调函数执行协同路由
  3. golang中数组和slice作为参数的区别
  4. 命令注入工具Commix
  5. webpack打包html里面img后src为“[object Module]”问题
  6. python安装vpython_VPython:一个Python的3D图形动画库+被忽略的数据可视化功能
  7. Spring boot(七):Spring boot+ mybatis 多数据源最简解决方案
  8. ggplot2 如何控制多个影射Legend 的顺序
  9. python循环遍历把表写入csv_求教python3.5如何把字典循环写入csv?
  10. 3GPP Releases
  11. 牛客网模拟笔试——黑化的牛牛(JavaScript)
  12. Java高级进阶学习资料!Java虚拟机的垃圾回收机制
  13. libtorrent源码分析(三)BT下载相关知识总结
  14. shell中各种括号用法
  15. c语言高效位运算函数之 __builtin_
  16. 阿拉伯数字转化为大写汉字
  17. 考研—计算机网络—应用层
  18. C++入门学习笔记01
  19. acca计算机管理会计,ACCA《管理会计》:Data and information
  20. 51单片机实例学习二 按键中断识别、定时器、利用定时器产生乐曲、数摸转换 ADC0804和DAC0832

热门文章

  1. link: unknown option -- n
  2. EDM邮件营销数据分析技巧分享
  3. 阿里VP贾扬清被曝将离职创业:建大模型基础设施,已火速锁定首轮融资
  4. 亚洲第一人,人肉扫码器,怎样提高记忆力
  5. Java数据库项目之满汉楼
  6. C++PrimerPlus 第五章 循环和关系表达式 - 5.5 循环和文本输入
  7. 【办公类-22-02】周计划系列(2)-生成“主题知识”(提取旧docx指定段落的内容,写入EXCLE模板,再次生成新docx)
  8. Guava之RateLimiter限流
  9. AR AP 重分类和操作 转
  10. Java map去空值