0
点赞
收藏
分享

微信扫一扫

股债轮动Python实现

梦想家们 2022-08-01 阅读 16


​​https://xueqiu.com/1884493065/126934263​​

1.策略介绍

股债轮动Python实现_mysql

2.数据库表设计

股债轮动Python实现_ico_02

3.数据导入

​​http://quotes.money.163.com/trade/lsjysj_zhishu_399300.html​​

去网易财经下载指数历史数据,导入到mysql中

股债轮动Python实现_sql_03

4. 策略回测代码

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# import talib
import pymysql
import datetime
import matplotlib.dates as dates
import logging



from matplotlib import dates as mdates

# 通过下面的方式进行简单配置输出方式与日志级别
logging.basicConfig(filename='logger1.log', level=logging.INFO)

start_date = '2005-01-04'

connect = pymysql.connect(
host = '127.0.0.1',
db = 'blog',
user = 'root',
passwd = '123456',
charset = 'utf8',
use_unicode = True
)
cursor = connect.cursor()

select_sql = "select date,open,high,low,adj_close from tmp_stock where code ='399300' and date > '%s' order by date asc" % start_date
data_300 = pd.read_sql(select_sql, con=connect)
data_300 = data_300.set_index('date')
data_300

select_sql = "select date,open,high,low,adj_close from tmp_stock where code ='399905' and date > '%s' order by date asc" % start_date
data_500 = pd.read_sql(select_sql, con=connect)
data_500 = data_500.set_index('date')
data_500

select_sql = "select date,open,high,low,adj_close from tmp_stock where code ='000852' and date > '%s' order by date asc" % start_date
data_1000 = pd.read_sql(select_sql, con=connect)
data_1000 = data_1000.set_index('date')
data_1000

select_sql = "select date,open,high,low,adj_close from tmp_stock where code ='399330' and date > '%s' order by date asc" % start_date
data_100 = pd.read_sql(select_sql, con=connect)
data_100 = data_100.set_index('date')
data_100

select_sql = "select date,open,high,low,adj_close from tmp_stock where code ='399006' and date > '%s' order by date asc" % start_date
data_cyb = pd.read_sql(select_sql, con=connect)
data_cyb = data_cyb.set_index('date')
data_cyb

def MaxDrawdown(return_list):
'''最大回撤率'''
i = np.argmax((np.maximum.accumulate(return_list) - return_list) / np.maximum.accumulate(return_list)) # 结束位置
if i == 0:
return 0
j = np.argmax(return_list[:i]) # 开始位置
return (return_list[j] - return_list[i]) / (return_list[j])
all_date = list(data_300.index.values)
import datetime

def is_high_average(input_dataframe, date, day_count):
all_date_array = list(input_dataframe.index.values)
try:
date_index = all_date_array.index(date) + 1
except ValueError:
date_index = -1
# print(date_index)
if date_index-day_count >= 0:
close = input_dataframe['adj_close'][date_index-day_count:date_index]
# print(close)
# print(close.sum())
return (close[-1] > (close.sum() / day_count) )
else:
return False

def get_rise_percent(input_dataframe, date, day_count):
all_date_array = list(input_dataframe.index.values)
try:
date_index = all_date_array.index(date) + 1
except ValueError:
date_index = -1

if date_index-day_count >= 0:
close = input_dataframe['adj_close'][date_index-day_count:date_index]
return close[-1] / close[0] - 1
else:
return -10
all_stock = {'hs300':data_300, 'zz500':data_500, 'zz1000':data_1000, 'sz100':data_100, 'cyb':data_cyb}
#货币基金年化
hb_percent = 0.04
def get_profit(percent_day_count=12, is_high_average_day_count=15, log=False):


# percent_day_count = 12
# is_high_average_day_count = 15
is_buy = False
buy_stock = 'hs300'
start_hb_date = datetime.datetime.strptime(start_date, "%Y-%m-%d")
profit = 1
log_profit = 1
win_profit = []
loss_profit = []
profit_list = []
profit_date = []
for date in all_date:
stock_rise_percent = {}
max_stock = None
for stock in all_stock.keys():
stock_rise_percent[stock] = get_rise_percent(all_stock[stock], date, percent_day_count)

max_stock_rise_percent = -10
for stock in stock_rise_percent.keys():
if stock_rise_percent[stock] >= max_stock_rise_percent:
max_stock_rise_percent = stock_rise_percent[stock]
max_stock = stock

is_high = is_high_average(all_stock[max_stock], date, is_high_average_day_count)
if is_high and is_buy is False:
current_date_time = datetime.datetime.strptime(str(date)[0:10], "%Y-%m-%d")
day_count = (current_date_time - start_hb_date).days
#算上空仓的货币基金收益
profit *= 1 + ((day_count / 365) * hb_percent)

is_buy = True
buy_stock = max_stock
buy_price = all_stock[max_stock]['adj_close'][date]
if log:
print("buy:" + max_stock + " date:" + str(date) + " price:" + str(buy_price))

if is_buy and log:
date_index = list(all_stock[buy_stock].index.values).index(date)
log_profit = log_profit * (all_stock[buy_stock]['adj_close'][date_index] / all_stock[buy_stock]['adj_close'][date_index - 1])

if is_buy is True and (max_stock != buy_stock or is_high is False):
is_buy = False
start_hb_date = datetime.datetime.strptime(str(date)[0:10], "%Y-%m-%d")
sell_price = all_stock[buy_stock]['adj_close'][date]
current_profit = (sell_price / buy_price)
profit *= current_profit
#算上买卖成本
profit *= 0.9985
log_profit = profit
if current_profit >=1:
win_profit.append(current_profit - 1)
else:
loss_profit.append(current_profit - 1)
if log:
print("sell:" + buy_stock + " date:" + str(date) + " price:" + str(sell_price) + " profit:" + str(profit))
if is_high:
is_buy = True
buy_stock = max_stock
buy_price = all_stock[max_stock]['adj_close'][date]
if log:
print("change buy:" + max_stock + " date:" + str(date) + " price:" + str(buy_price))
profit_list.append(log_profit)
profit_date.append(date)


if log:
print('净值:' + str(profit))
print('盈利次数:' + str(len(win_profit)))
print('亏损次数:' + str(len(loss_profit)))
winPercent = len(win_profit) / float(len(win_profit) + len(loss_profit))
print('胜率:' + str( winPercent) )
averangeWinPercent = np.sum(win_profit) / float(len(win_profit))
print('平均每次盈利:' + str(averangeWinPercent ) )
averageLossPerent = np.sum(loss_profit) / float(len(loss_profit))
print('平均每次亏损:' + str(averageLossPerent ) )
kali = winPercent - (1 - winPercent) / (averangeWinPercent / abs(averageLossPerent));
print('盈亏比:' + str(abs(averangeWinPercent / averageLossPerent)))
print('凯利最佳仓位:' + str(kali))
max_down = MaxDrawdown(profit_list)
print('最大回撤:' + str(max_down))
return profit, profit_list, profit_date

profit, profit_list, profit_date = get_profit(10, 16, True)
x = profit_date
y = profit_list
plt.figure(figsize=(15,8)) #创建绘图对象
plt.plot(x,y,"b",linewidth=1) #在当前绘图对象绘图(X轴,Y轴,蓝色,线宽度)
# plt.plot(x,hs_profit_list,"r",linewidth=1)
plt.xlabel("Date") #X轴标签
plt.ylabel("Profit") #Y轴标签
plt.title("Lundong") #图标题
plt.show() #显示图

5. 策略输出

股债轮动Python实现_mysql_04

6.策略净值走势

股债轮动Python实现_sql_05

感觉跟原文的回测结果不一样,我再花点时间检查下看,哪里出了问题。


举报

相关推荐

0 条评论