- 注册时间
- 2023-2-19
- 最后登录
- 2025-4-29
- 阅读权限
- 200
- 积分
- 3618
- 精华
- 0
- 帖子
- 1037
  
|
"""
Created on Wed Jun 23 14:11:52 2021
#策略为:5日突破50日做多,直到死叉卖出
"""
# ID:451309
import tushare as ts
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['figure.dpi'] = 300 # 分辨率
mytoken = "2be9322682f222cada16f8ae706433204203633d78c08372156a08ee"
ts.set_token(mytoken)
pro = ts.pro_api() # 初始化接口
data = ts.pro_bar(ts_code='000001.SZ', adj='qfq', start_date='2016-05-01', end_date='2021-05-01')
# 处理数据
data = data.loc[:, ['trade_date', 'close']]
# sort_values()by依照某个字段中的数据进行排序,inplace 是否用排序后的数据集替换原来的数据,默认为False,即不替换
data.sort_values(by="trade_date", inplace=True)
# to_datetime()将给定的数据按照指定格式转换成日期格式
data["trade_date"] = pd.to_datetime(data["trade_date"])
# reset_index()重置数据帧的索引
data.reset_index(inplace=True, drop=True)
# 求每日收益率
data['dayreturn'] = data['close'].pct_change()
# 用0填补缺失值NA
data['dayreturn'].fillna(0, inplace=True)
# 计算累积日收益率
data['cum_daily_return'] = (1 + data['dayreturn']).cumprod() - 1
####################################################################
### 沪深300的收益率计算,作为市场的基准收益率
hs300 = pro.index_daily(ts_code='000300.SH', start_date='20160501', end_date='20210501')
hs300 = hs300.loc[:, ['trade_date', 'close']]
hs300.sort_values(by="trade_date", inplace=True)
hs300["trade_date"] = pd.to_datetime(hs300["trade_date"])
# reset_index()重置数据帧的索引
hs300.reset_index(inplace=True, drop=True)
# 求每日收益率
hs300['dayreturn'] = hs300['close'].pct_change()
# hs300['dayreturn'] = dailyreturn #添加dr列
# 用0填补缺失值NA
hs300['dayreturn'].fillna(0, inplace=True)
# 计算累积日收益率
hs300['cum_daily_return'] = (1 + hs300['dayreturn']).cumprod() - 1
# #绘制累积日收益率曲线
# hs300['cum_daily_return'].plot(figsize=(12,8))
##############################################################
# 使用 rolling() 函数,简化操作
data["ma5"] = data["close"].rolling(5).mean()
data["ma50"] = data["close"].rolling(50).mean()
data[['ma5', 'ma50']].plot(grid=True, figsize=(18, 15))
plt.show()
# CASH:现金 STOCKHOLD 持有的股票
CASH = 100000
STOCKHOLD = 0
# 提取index为0,列名为'cash'中的数据赋值
data.loc[0, "cash"] = CASH
data.loc[0, "stock_hold"] = STOCKHOLD
data.loc[1, "cash"] = CASH
data.loc[1, "stock_hold"] = STOCKHOLD
# 第一天不操作,最后一天不买入
for i in range(1, len(data) - 1):
# 短期均线 向上 穿过长期均线,金叉。同时手里有现金可用
if data.loc[i, "ma5"] > data.loc[i, "ma50"] and data.loc[i - 1, "ma5"] < data.loc[i - 1, "ma50"] and data.loc[
i, "cash"] > 0:
stock_temp = data.loc[i, "cash"] // (100 * data.loc[i + 1, "close"]) * 100
data.loc[i + 1, "stock_hold"] = data.loc[i, "stock_hold"] + stock_temp
data.loc[i + 1, "cash"] = data.loc[i, "cash"] - stock_temp * data.loc[i + 1, "close"]
continue
# 短期均线 向下 穿过长期均线,死叉。同时手里有股票可卖
if data.loc[i, "ma5"] < data.loc[i, "ma50"] and data.loc[i - 1, "ma5"] > data.loc[i - 1, "ma50"] and data.loc[
i, "stock_hold"] > 0:
data.loc[i + 1, "stock_hold"] = 0
data.loc[i + 1, "cash"] = data.loc[i, "cash"] + data.loc[i, "stock_hold"] * data.loc[i + 1, "close"]
continue
data.loc[i + 1, "stock_hold"] = data.loc[i, "stock_hold"]
data.loc[i + 1, "cash"] = data.loc[i, "cash"]
# equity 资产净值
data["equity"] = data["stock_hold"] * data["close"] + data["cash"]
data["honding_income"] = data["equity"] - CASH
# 持有收益
honding_income = round(data["honding_income"].iloc[-1], 2)
print("\n持有收益 :", honding_income) # 保留两位小数
# 收益率
print("收益率 :", (round(honding_income / CASH * 100, 2)), "%") # 保留两位小数
# 基准收益率
print("基准收益率:", (round(hs300['cum_daily_return'].iloc[-1] * 100, 2)), "%")
# 股票涨幅
# print("股票涨幅:",(round(data["cum_daily_return"].iloc[-1]*100,2 ) ),"%") #保留两位小数
# 计算最大回撤率
#
# 公式di=max(1-策略当日的价值 / 当日之前的最高价值)
#
# for i in range(1, len(data)):
# data.loc[i, "ddown_rate"]=(data["equity"].iloc-data["equity"].iloc[i-1])/data["equity"].iloc
# for i in range(1, len(data)):
# data.loc[i, "ddown_rate"]=1 - data["equity"].iloc/max(data["equity"].iloc[0:i])
# #第一个数据手动补上0
# data.loc[0, "ddown_rate"] = 0
# #找出最大值
# Max_ddown_rate=max(data["ddown_rate"])
# print("最大回撤率:",(round(Max_ddown_rate*100,2 )),"%")
# 计算夏普率:反映了单位风险基金净值增长率超过无风险收益率的程度。
# SharpeRatio=[ E(Rp)-Rf ] / σp
# E(Rp):变量名E_Rp:投资组合预期报酬率(平均回报率)
# Rf: 无风险利率(通常用国债利率来代替) Rf/ 252 对应日无风险利益
# σp:投资的标准差
##默认252个工作日,无风险利率 RF为 0.05
# 日夏普,波动率要乘以sqrt(252)
return_sr = data["equity"] / data["equity"].shift(1) - 1
RF = 0.05
E_Rp = np.mean(return_sr)
σp = np.std(return_sr)
sharpe = (E_Rp - RF / 252) / σp * np.sqrt(252)
print("夏普率 :", round(sharpe, 2))
# 年化收益率=[(投资内收益 / 本金)/ 投资天数] * 365 ×100%
Annual_rate_of_return = (honding_income / CASH) / 5 / 252 * 365
print("年化收益率:", round(Annual_rate_of_return * 100, 2), '%') # 保留两位小数
#####################################
########## 绘图 ################
data[['close']].plot(grid=True, figsize=(18, 15))
plt.show()
x = data["trade_date"]
y = data["honding_income"] / CASH
plt.plot(x, y, ls='-', lw=0.5, label='cum_strategy_returns', color='r')
x = data["trade_date"]
y = hs300['cum_daily_return']
plt.plot(x, y, ls='-', lw=0.5, label='cum_market_returns', color='g')
plt.grid() # 显示网格
plt.legend()
plt.xlabel('Date')
plt.ylabel('Return')
plt.show()
|
|