1.3计算均线突破策略的sharpe比率, 最大回撤

编程入门 行业动态 更新时间:2024-10-09 18:21:03

1.3计算均线突破策略的sharpe<a href=https://www.elefans.com/category/jswz/34/1762959.html style=比率, 最大回撤"/>

1.3计算均线突破策略的sharpe比率, 最大回撤

前言: 采用新的策略, 简单均线突破策略, 以5日均线和10日均线判断标准, 5日均线向上突破10日均线的时候买入, 5日均线向下突破10日均线的时候卖出.

代码如下:

import numpy as np
import pandas as pd
import datetime
from matplotlib import pyplot as plt#读取股票数据, 格式为Stkcd,Trddt,Opnprc,Hiprc,Loprc,Clsprc,Dretwd,Adjprcwd,一共10784个数据
data = pd.read_csv("TRD_Dalyr.csv")
#将时间转换为标准格式xx-xx-xx
data.Trddt = pd.to_datetime(data.Trddt, format = "%Y%m%d")
#print(data)cls = data[data['Stkcd'] == 1]['Clsprc']
adjcls = data[data['Stkcd'] == 1]['Adjprcwd']
adjcls = adjcls / (adjcls.iloc[-1] / cls.iloc[-1])#plt.plot(cls)
#plt.plot(adjcls)
#plt.show()stk = data['Stkcd']
#剔除重复的代码
stk = stk.drop_duplicates()
for row in stk:print(row)#cls代表取股票代码为000001(其实是stk的第一行)的股票交易日期和收盘价
cls = data[data['Stkcd'] == stk.iloc[0]][['Trddt', 'Clsprc']]
#构建一个pandas数据结构DataFrame,将交易日期作为行、股票代码作为列
cls2 = pd.DataFrame(cls['Clsprc'].tolist(), index = cls['Trddt'].tolist(), columns = [stk.iloc[0]])
print(cls2)#如法炮制,取股票代码stk第二行的代码对应的数据
cls3 = data[data['Stkcd'] == stk.iloc[1]][['Trddt', 'Clsprc']]
cls4 = pd.DataFrame(cls3['Clsprc'].tolist(), index = cls3['Trddt'].tolist(), columns = [stk.iloc[1]])
print(cls4)#将两个合并, axis = 1表示列对齐。
df = pd.concat([cls2, cls4], axis = 1)
print(df)#查找空值,并且填补空值, np.where返回的是一个list,其中第一个元素为空值所处的行号
nan_fill = np.where(np.isnan(df))[0][0]
print(nan_fill)
print(df.iloc[nan_fill])
print(df.iloc[nan_fill - 2: nan_fill + 1])#用pad的方式填补空值,即取空值后的第一个数字,填补以前的空值
df = df.fillna(method = 'pad')
print(df.iloc[nan_fill - 2: nan_fill + 1])df.plot()
#plt.show()
#重新拷贝一份df, 可以用bool变量赋予参数deep, 默认为True, 即temp_df改变不影响df的值, 如果是false则会影响df的值
temp_df = df.copy()
params = [5, 10, 20]
for p in params:#以window长度为p, 计算移动平均值, 也就是计算均线temp_df["ma" + str(p)] = temp_df[stk.iloc[0]].rolling(p).mean()
#截取2017年9月1日之后的数据
temp_df = temp_df[temp_df.index >= np.datetime64(datetime.date(2017, 9, 1))]
figure, axis = plt.subplots()
param_colors = [(1, 0.7, 0.2), (0, 0.7, 0.9), (0.9, 0.5, 0.9)]for (i, p) in enumerate(params):temp_df[['ma' + str(p)]].plot(kind = 'line', ax = axis, color = param_colors[i], use_index = True)
#plt.show()def back_test(p, stk):result = pd.DataFrame(index = [p.index])result['Position'] = 0result['Action'] = np.nanresult['Profit'] = 0result['Accumulate_profit'] = 0result['Net_value'] = 0result['Daily_return'] = 0performance = {'Count': 0,'Win_rate': 0,'Return': 0,'Sharpe': 0,#最大回撤'Max_drawdown': 0}#len(p)指的是DataFrame的行数, 引用DataFrame的列标号, 可以用p.ma5, 也可以用p["ma5"]row_index = p.index.strftime("%Y-%m-%d")#print("begin")#print(result)#print(p)#print(len(row_index))for index in range(len(p)):if index == 0:continue#从index = 1开始#print(len(p), index,  result.loc[row_index[index - 1], "Position"])result.loc[p.index[index], "Position"] = result.loc[row_index[index - 1], "Position"]ma5 = p.ma5[index]ma10 = p.ma10[index]prema5 = p.ma5[index - 1]prema10 = p.ma10[index - 1]#如果index = p的长度 - 1, 那么index就是最后一个元素的下标if index == len(p) - 1:if result['Position'][index] == 1:result["Position"][index] = 0result['Action'][index] = 1else:if result['Position'][index] == 0:#判断5日均线是否上穿10日均线, 如果是, 那么position = 1, action = 1if ma5 > ma10 and prema5 < ma10:result['Position'][index] = 1result['Action'][index] = 1else:#position != 0, 说明已经持仓, 那么只有在5日均线下穿10日均线的时候, 才会卖出if ma5 < ma10 and prema5 > ma10:result.loc[row_index[index], "Position"] = 0result.loc[row_index[index], "Action"] = -1#至此,已经得出了该投资策略的买入、卖出信号点,可以依据这个1、-1、0的变化,确定是否买卖#p[stk][1 : -1].values表示从stk = 1, 即000001上证综指下标为1的项开始,一直到倒数第二项为止(-1)print(result)print(p[stk][1:-1].values)print(p[stk][0:-2].values)print()c = list(map(lambda x: x[0] - x[1], zip(p[stk][1:-1].values,p[stk][0:-2].values)))print(c)print(np.array(c))print(result['Position'][0:-2].values)c = np.multiply(np.array(c), np.array(result['Position'][0: -2].values)).tolist()print(c)result.loc[1 : -1, 'Profit'] = cresult["Accumulate_profit"] = result["Profit"].values.cumsum()result["Net_value"] = (result["Accumulate_profit"].values + p[stk][0]) / p[stk][0]result.loc[1 : -1, 'Daily_return'] = (result['Net_value'][1 : -1].values - result["Net_value"][0 : -2].values) / result['Net_value'][1 : -1].valuesperformance['Count'] = (result['Action'] == 1).sum()performance['Return'] = sharpe_ratio(result['Daily_return'].values)performance['Max_drawdown'] = Max_drawdown(result['Net_value'].values)return result, performancedef sharpe_ratio(return_list):#计算sharpe比率average_return = np.mean(return_list)annual_return = average_return * 252return_stdev = np.std(return_list)annual_volume = return_stdev * np.sqrt(252)#默认一共有252个工作日, 无风险利率为0.02sharpe_ratio = (annual_return - 0.02) / annual_volumereturn sharpe_ratiodef Max_drawdown(value_list):print(value_list)#计算最大回撤i = np.argmax((np.maximum.accumulate(value_list) - value_list) / np.maximum.accumulate(value_list))  # 结束位置#开始位置j = np.argmax(value_list[:i])return(value_list[j] - value_list[i]) / (value_list[j])print(back_test(temp_df, stk.iloc[0]))

更多推荐

1.3计算均线突破策略的sharpe比率, 最大回撤

本文发布于:2024-02-06 09:02:42,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1748121.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:比率   均线   策略   sharpe

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!