python量化交易第四章

一.数据准备:本地化股票数据

1.1为什么要创建股票数据库

  • 数据费用->按数据量收费,每日更新增量数据

  • 获取速度->本地直接获取>远程访问服务器
    1.2如何创建,更新股票数据库

  • 存储方式->股票代码.csv,MySql,MangoDB等数据库

  • 实现思路: 1.获取股票列表
    2.依次存储股票数据
    3.每天以增量形式更新数据
    每天以增量形式更新数据
    ->

  • 如何追加数据:df.to_csv(mode=‘a’)

  • 重复获取了怎么办:df.drop_duplicates

  • 缺少数据怎么办:startdate=最后一个日期

import time

import pandas as pd
import os
#全局变量:
data_root='D:/python project/pythonProject/data/'
#000002.XSHE 	万 科A 000001.XSHE 平安银行
from jqdatasdk import *
auth('15608617235','Xwt688698')  #账号是申请时所填写的手机号;密码为聚宽官网登录密码
pd.set_option('display.max_rows',1000000)
pd.set_option('display.max_columns',10000)
import datetime
def init_db():
    """
    初始化股票数据库
    :return:
    """
    #1.获取所有股票代码
    stocks=get_stock_list()
    #2.存储到csv文件中
    for code in stocks:
        df=get_single_stock_Price(code,'daily')
        export_data(df,code,'price')
        print(code)
        print(df.head())
def get_stock_list():
    """
     获取所有A股股票列表
    :return: stock_list
    """
    stocks_list= list(get_all_securities(['stock']).index)
    return stocks_list
def get_single_stock_Price(code,time_freq,start_date=None,end_date=None):
    """
    获取当个股票行情数据
    :param code:
    :param time_freq:
    :param start_date:
    :param end_date:
    :return:
    """
    #如果start_date=None,默认从上市日期开始
    if start_date is None:
        start_date=get_security_info(code).start_date
    if end_date is None:
        end_date=datetime.datetime.today()
    #获取行情数据
    data = get_price(code,start_date=start_date, end_date=end_date, frequency=time_freq, panel=False)
    return data

def export_data(data,filename,type,mode=None):
    """
    导出股票相关数据
    :param data:
    :param type:股票数据类型,可以是:price,finance
    :param filename:
    :param mode:a代表追加,none代表默认写入
    :return:
    """
    file_root=data_root+type+'/'+filename+'.csv'
    data.index.names=['date']
    if mode=='a':
        data.to_csv(file_root,mode=mode,header=False)
        #删除重复值
        data=pd.read_csv(file_root)#读取数据
        data=data.drop_duplicates(subset=['date'])#以日期列为准
        data.to_csv(file_root)#重新写入
    else:
        data.to_csv(file_root)#判断一下file是否存在>存在:追加/不存在:保持
    print('已成功存储至:',file_root)
def get_csv_data(code,type):
    file_root=data_root+type+'/'+code+'.csv'
    return pd.read_csv(file_root)
def transfer_price_freq(data,time_freq):
    """
    将数据转换为指定周期:周期开盘价(周期第一天),收盘价(周期最后一天),最高价(周期内),最低价(周期内)

    :param data:
    :param time_freq:
    :return:
    """
    #获取周K(当周的):开盘价(当周第一天),收盘价(当周最后一天),最高价(当周),最低价(当周)
    df_trans=pd.DataFrame()
    df_trans['open']=data['open'].resample(time_freq).first()
    df_trans['close']=data['close'].resample(time_freq).last()
    df_trans['high']=data['high'].resample(time_freq).max()
    df_trans['low']=data['low'].resample(time_freq).min()
    return df_trans
def get_signle_finance(code,date,statDate):
    """
    获取单个股票财务指标
    :param code:
    :param date:
    :param statDate:
    :return:
    """
    data = get_fundamentals(query(indicator).filter(indicator.code==code), date=date,statDate=statDate)  # 获取财务指标数据
    return data
def get_single_valuation(code,date,statDate):
    """
    获取单个股票估值指标
    :param code:
    :param date:
    :param statDate:
    :return:
    """
    data = get_fundamentals(query(valuation).filter(valuation.code==code), date=date,statDate=statDate)  # 获取财务指标数据
    return data
def calculate_change_pct(data):
    """
    涨跌幅=(当期收盘价-前期收盘价)/前期收盘价
    :param data:dataframe,带有收盘价
    :return:datafram,带有涨跌幅
    """
    data['close_pct']=(data['close']-data['close'].shift(1))/data['close'].shift(1)
    return data
def update_daily_price(stock_code,type):
    # 3.1是否存在文件:不存在-重新获取,存在->3.2
    file_root=data_root+type+'/'+stock_code+'.csv'
    if os.path.exists(file_root):#如果存在对应文件
        # 3.2获取增量数据(code.startdate=对应股票csv中最新日期。enddate=今天)
        startdate=pd.read_csv(file_root,usecols=['date'])['date'].iloc[-1]

        df=get_single_stock_Price(stock_code,'daily',startdate,datetime.datetime.today())
        # 3.3追加到已有文件中
        export_data(df,stock_code,'price','a')
    else:
        #重新获取该股票行情数据
        df=get_single_stock_Price(stock_code,'daily')
        export_data(df,stock_code,'price')




import data.stock as st
import pandas as pd
#调用一只股票的行情数据
# code='000002.XSHG'
# data=st.get_single_stock_Price(code=code,time_freq='daily',start_date='2021-01-01',end_date='2021-02-01')
# # # 存入csv
# st.export_data(data=data,filename=code,type='price')

#从csv中获取数据
# data=st.get_csv_data(code=code,type='price')
# print(data)
#1.获取所有股票代码
# stocks=st.get_stock_list()
#2.存储到csv文件中
# for code in stocks:
#     df=st.get_single_stock_Price(code,'daily')
#     st.export_data(df)
#1+2.
st.init_db()

#3.每日更新数据
#3.1是否存在文件:不存在-重新获取,存在->3.2
#3.2获取增量数据(code.startdate=对应股票csv中最新日期。enddate=今天)
#3.3追加到已有文件中
# for code in stocks:
#     st.update_daily_price(code,'price')

二.数据准备:从本地读取数据

import time

import pandas as pd
import os
#全局变量:
data_root='D:/python project/pythonProject/data/'
#000002.XSHE 	万 科A 000001.XSHE 平安银行
from jqdatasdk import *
auth('15608617235','Xwt688698')  #账号是申请时所填写的手机号;密码为聚宽官网登录密码
pd.set_option('display.max_rows',1000000)
pd.set_option('display.max_columns',10000)
import datetime
def init_db():
    """
    初始化股票数据库
    :return:
    """
    #1.获取所有股票代码
    stocks=get_stock_list()
    #2.存储到csv文件中
    for code in stocks:
        df=get_single_stock_Price(code,'daily')
        export_data(df,code,'price')
        print(code)
        print(df.head())
def get_stock_list():
    """
     获取所有A股股票列表
    :return: stock_list
    """
    stocks_list= list(get_all_securities(['stock']).index)
    return stocks_list
def get_single_stock_Price(code,time_freq,start_date=None,end_date=None):
    """
    获取当个股票行情数据
    :param code:
    :param time_freq:
    :param start_date:
    :param end_date:
    :return:
    """
    #如果start_date=None,默认从上市日期开始
    if start_date is None:
        start_date=get_security_info(code).start_date
    if end_date is None:
        end_date=datetime.datetime.today()
    #获取行情数据
    data = get_price(code,start_date=start_date, end_date=end_date, frequency=time_freq, panel=False)
    return data

def export_data(data,filename,type,mode=None):
    """
    导出股票相关数据
    :param data:
    :param type:股票数据类型,可以是:price,finance
    :param filename:
    :param mode:a代表追加,none代表默认写入
    :return:
    """
    file_root=data_root+type+'/'+filename+'.csv'
    data.index.names=['date']
    if mode=='a':
        data.to_csv(file_root,mode=mode,header=False)
        #删除重复值
        data=pd.read_csv(file_root)#读取数据
        data=data.drop_duplicates(subset=['date'])#以日期列为准
        data.to_csv(file_root)#重新写入
    else:
        data.to_csv(file_root)#判断一下file是否存在>存在:追加/不存在:保持
    print('已成功存储至:',file_root)

def get_csv_price(code,start_date,end_date):
    #使用update直接更新
    update_daily_price(code)
    #读取数据
    file_root=data_root+'price/'+code+'.csv'
    data=pd.read_csv(file_root,index_col='date')
    #根据日期筛选股票数据
    return data[(data.index>=start_date) & (data.index<end_date)]

def transfer_price_freq(data,time_freq):
    """
    将数据转换为指定周期:周期开盘价(周期第一天),收盘价(周期最后一天),最高价(周期内),最低价(周期内)

    :param data:
    :param time_freq:
    :return:
    """
    #获取周K(当周的):开盘价(当周第一天),收盘价(当周最后一天),最高价(当周),最低价(当周)
    df_trans=pd.DataFrame()
    df_trans['open']=data['open'].resample(time_freq).first()
    df_trans['close']=data['close'].resample(time_freq).last()
    df_trans['high']=data['high'].resample(time_freq).max()
    df_trans['low']=data['low'].resample(time_freq).min()
    return df_trans
def get_signle_finance(code,date,statDate):
    """
    获取单个股票财务指标
    :param code:
    :param date:
    :param statDate:
    :return:
    """
    data = get_fundamentals(query(indicator).filter(indicator.code==code), date=date,statDate=statDate)  # 获取财务指标数据
    return data
def get_single_valuation(code,date,statDate):
    """
    获取单个股票估值指标
    :param code:
    :param date:
    :param statDate:
    :return:
    """
    data = get_fundamentals(query(valuation).filter(valuation.code==code), date=date,statDate=statDate)  # 获取财务指标数据
    return data
def calculate_change_pct(data):
    """
    涨跌幅=(当期收盘价-前期收盘价)/前期收盘价
    :param data:dataframe,带有收盘价
    :return:datafram,带有涨跌幅
    """
    data['close_pct']=(data['close']-data['close'].shift(1))/data['close'].shift(1)
    return data
def update_daily_price(stock_code,type='price'):
    # 3.1是否存在文件:不存在-重新获取,存在->3.2
    file_root=data_root+type+'/'+stock_code+'.csv'
    if os.path.exists(file_root):#如果存在对应文件
        # 3.2获取增量数据(code.startdate=对应股票csv中最新日期。enddate=今天)
        startdate=pd.read_csv(file_root,usecols=['date'])['date'].iloc[-1]

        df=get_single_stock_Price(stock_code,'daily',startdate,datetime.datetime.today())
        # 3.3追加到已有文件中
        export_data(df,stock_code,'price','a')

    else:
        #重新获取该股票行情数据
        df=get_single_stock_Price(stock_code,'daily')
        export_data(df,stock_code,'price')
    print("股票数据已经更新成功:",stock_code)

import data.stock as st
#本地读取数据
data=st.get_csv_price('000001.XSHE','2020-01-01','2020-02-01')
print(data)
exit()
#获取平安银行的行情数据(日K)
data=st.get_single_stock_Price('000001.XSHE','daily','2020-01-01','2020-02-01')
# print(data)

#计算涨跌幅,验证准确性
#data=st.calculate_change_pct(data)
# print(data)#多了一列close_pct
#获取周K
data=st.transfer_price_freq(data,'W')
print(data)

#计算涨跌幅,验证准确性
data=st.calculate_change_pct(data)
print(data)

三.双均线策略

3.1什么是双均线策略
均线->美国投资专家Joseph E.Granville
1962年提出,利用股价和均线择时
->代表过去N日股价平均走势
3.2策略实现思路
1)获取标的行情
2)计算技术指标
3)生成交易信号
4)计算收益率
5)寻找最优参数
6)与市场基准比较
7)策略评估

四.双均线策略:生成交易信号

import numpy as np
import pandas as pd
import strategy.base as strat
import data.stock as st
import pandas as pd
def ma_stratey(data,short_window=5,long_window=20):
    """
    双均线策略
    :param data:dataframe,投资标的行情数据(必须包含收盘价)
    :param short_window:短期n期移动平均线,默认5
    :param long_window:长期n日移动平均线,默认20
    :return:
    """
    data=pd.DataFrame(data)
    #计算技术指标:ma短期,ma长期
    data['short_ma']=data['close'].rolling(window=short_window).mean()
    data['long_ma']=data['close'].rolling(window=long_window).mean()
    #生成信号:金叉买入,死叉卖出
    data['buy_signal']=np.where(data['short_ma']>data['long_ma'],1,0)
    data['sell_signal'] = np.where(data['short_ma'] < data['long_ma'], -1, 0)
    #过滤信号:st.compose_signal
    data=strat.compose_signal(data)
    #数据预览
   # print(data[['close','short_ma','long_ma','buy_signal','sell_signal','signal']])
    #删除多余的columns
    data.drop(labels=['buy_signal','sell_signal'],axis=1)

    return data
if __name__=='__main__':
    df=st.get_single_stock_Price('000001.XSHE','daily','2021-11-05','2022-01-04')
    df=ma_stratey(df)
    #筛选有信号点
    df=df[df['signal']!=0]
    #数据预览
    print("开仓次数:",int(len(df) / 2))
    print(df[['close','short_ma','long_ma','signal']])

五.双均线策略:计算信号收益率

import numpy as np
import pandas as pd
import strategy.base as strat
import data.stock as st
import pandas as pd
import matplotlib.pyplot as plt

def ma_stratey(data,short_window=5,long_window=20):
    """
    双均线策略
    :param data:dataframe,投资标的行情数据(必须包含收盘价)
    :param short_window:短期n期移动平均线,默认5
    :param long_window:长期n日移动平均线,默认20
    :return:
    """
    data=pd.DataFrame(data)
    #计算技术指标:ma短期,ma长期
    data['short_ma']=data['close'].rolling(window=short_window).mean()
    data['long_ma']=data['close'].rolling(window=long_window).mean()
    #生成信号:金叉买入,死叉卖出
    data['buy_signal']=np.where(data['short_ma']>data['long_ma'],1,0)
    data['sell_signal'] = np.where(data['short_ma'] < data['long_ma'], -1, 0)

    #过滤信号:st.compose_signal
    data=strat.compose_signal(data)

    #计算单次收益率
    data=strat.calculate_prof_pct(data)

    #计算累计收益
    data=strat.calculate_cum_prof(data)

    #数据预览
    #print(data[['close','short_ma','long_ma','buy_signal','sell_signal','signal']])
    #删除多余的columns
    data.drop(labels=['buy_signal','sell_signal'],axis=1)

    return data

if __name__=='__main__':
    #股票列表
    stocks=['000001.XSHE','000858.XSHE','002594.XSHE']
    #存放累计收益率
    cum_profits=pd.DataFrame()

    #循环获取数据
    for code in stocks:
        df=st.get_single_stock_Price(code,'daily','2016-01-01','2021-01-01')
        df=ma_stratey(df)#调用双均线策略
        cum_profits[code] = df['cum_profit'].reset_index(drop=True) # 存储累计收益率
        #折线图
        df['cum_profit'].plot(label=code)
        #筛选有信号点
        # df=df[df['signal']!=0]
        # #数据预览
        print("开仓次数:", int(len(df)))

        # print(df[['close','signal','profit_pct','cum_profit']])
    #预览

    print(cum_profits)
    #可视化
    # cum_profits.plot()
    plt.title('Comparison of Ma Strategy Pofits')
    plt.show()

六.什么是假设检验

双均线策略->基于不同周期平均价格的突破性策略
如何验证策略的可靠性:

  • 评估指标->胜率,年化收益,最大回撤,夏普
  • 假设检验->收益>0是否为大概率事件
  • 先提出一个假设,通过多次实验,计算不同结果出现的频率,来决定是否接受或者拒绝这个假设,从而验证这个现象是否随机(偶然)

假设检验:t-test
H0:样本均值=理论均值->每次收益率的均值=0
H1:样本均值>理论均值->每次收益率>0

七.双均线策略:利用p值检验可靠性

import numpy as np
import pandas as pd
import strategy.base as strat
import data.stock as st
import pandas as pd
import matplotlib.pyplot as plt

def ma_stratey(data,short_window=5,long_window=20):
    """
    双均线策略
    :param data:dataframe,投资标的行情数据(必须包含收盘价)
    :param short_window:短期n期移动平均线,默认5
    :param long_window:长期n日移动平均线,默认20
    :return:
    """
    print("=======当前周期参数对:",short_window,long_window)

    data=pd.DataFrame(data)
    #计算技术指标:ma短期,ma长期
    data['short_ma']=data['close'].rolling(window=short_window).mean()
    data['long_ma']=data['close'].rolling(window=long_window).mean()
    #生成信号:金叉买入,死叉卖出
    data['buy_signal']=np.where(data['short_ma']>data['long_ma'],1,0)
    data['sell_signal'] = np.where(data['short_ma'] < data['long_ma'], -1, 0)

    #过滤信号:st.compose_signal
    data=strat.compose_signal(data)

    #计算单次收益率
    data=strat.calculate_prof_pct(data)

    #计算累计收益
    data=strat.calculate_cum_prof(data)
    # 删除多余的columns
    data.drop(labels=['buy_signal', 'sell_signal'], axis=1)

    #数据预览
    print(data[['close','short_ma','long_ma','cum_profit','signal']])

    return data

if __name__=='__main__':
    #股票列表
    stocks=['000001.XSHE','000858.XSHE','002594.XSHE']
    #存放累计收益率
    cum_profits=pd.DataFrame()

    #循环获取数据
    for code in stocks:
        df=st.get_single_stock_Price(code,'daily','2016-01-01','2021-01-01')
        df=ma_stratey(df)#调用双均线策略
        cum_profits[code] = df['cum_profit'].reset_index(drop=True) # 存储累计收益率
        #折线图
        df['cum_profit'].plot(label=code)
        #筛选有信号点
        # df=df[df['signal']!=0]
        # #数据预览
        print("开仓次数:", int(len(df)))

        # print(df[['close','signal','profit_pct','cum_profit']])
    #预览

    print(cum_profits)
    #可视化
    # cum_profits.plot()
    plt.title('Comparison of Ma Strategy Pofits')
    plt.show()

八.双均线策略:寻找最优参数

import pandas as pd

import strategy.ma_strategy as ma
import data.stock as st
#参数1:股票池
#stocks=['000001.XSHE']
data=st.get_csv_price('000001.XSHE','2016-01-01','2021-01-01')

#参数2:周期参数


params=[5,10,20,60,120,250]

#存放参数与收益
res=[]

#匹配,并计算不同的周期参数对:5-10,2-20...120-250
for short in params:
    for long in params:
        if long > short:
            data_res=ma.ma_strategy(data=data,short_window=short,long_window=long)
            #获取周期参数,及其对应累计收益率
            cum_profit=data_res['cum_profit'].iloc[-1]#获取累计收益率最终数据
            res.append([short,long,cum_profit])#将参数放入结果里面
#将结果列表转换为df,并找到最优参数
res=pd.DataFrame(res,columns=['short_win','long_win','cum_win'])
#排序
res=res.sort_values(by='cum_profit',ascending=False)#按收益倒序排序
print(res)
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python量化交易是利用Python编程语言和相关的金融库来进行交易策略的开发和执行。在这里,我将介绍一些深入浅出的Python量化交易实战的步骤和技巧。 1. 数据获取:首先,你需要获取市场数据,包括股票、期货或其他金融产品的历史价格数据。你可以使用第三方库如pandas、tushare、quandl等来获取数据。 2. 数据处理:对获取到的数据进行处理和清洗,包括数据的缺失值处理、数据格式转换等。pandas库是一个非常强大且方便的用于数据处理的工具。 3. 策略开发:根据你的交易理念和策略,使用Python编写量化交易策略。这可能涉及到技术指标的计算、信号的生成等。你可以使用一些常用的库如numpy、talib来帮助你进行技术指标的计算。 4. 回测:使用历史数据对你编写的策略进行回测,评估其表现。通过回测可以了解策略在不同市场环境下的盈亏情况,并进行优化和改进。 5. 执行交易:当你满意于自己的策略表现时,你可以选择使用API连接到实际的交易平台,通过Python自动执行你的交易策略。 6. 风险管理:在量化交易中,风险管理是非常重要的一环。你需要考虑风险控制、资金管理等方面,确保你的策略能够长期有效。 以上是一个简要的Python量化交易实战的流程,希望对你有所帮助。如果你有更具体的问题或需要了解更多细节,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值