失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 基于市场情绪平稳度的股指期货日内交易策略

基于市场情绪平稳度的股指期货日内交易策略

时间:2022-05-11 09:55:16

相关推荐

基于市场情绪平稳度的股指期货日内交易策略

基于市场情绪平稳度的股指期货日内交易策略

策略说明请下载下面这个pdf文件:

基于市场情绪平稳度的股指期货日内交易策略.pdf

测试数据请下载下面这个csv文件:

data.csv

实现内容

策略题为一个PDF文档(基于市场情绪平稳度的股指期货日内交易策略)和写策略需要的聚宽数据包(data.csv),

根据文档和数据包写出程序和年化收益图

实现截图

编程难点

平均最大回撤和平均最大反向回撤的计算累计收益的计算

代码实现(使用python实现,其他编程语言大概一致)

配置类Configuration.py

class Configuration:# 文件地址file_path = "/Users/zhangqinxiong/Downloads/基于市场情绪平稳度的股指期货日内交易策略/data.csv"# 情绪平稳度阈值emotional_stability_threshold = 9 / 10000.0# 止损阈值stop_loss_threshold = 0.5 / 100.0# 初始金额# 设置为100是因为算到最后的结果刚好可以以百分比表示init_money = 100# 多次开仓交易的数据# money保存的是交易当前的金额# details保存的是所有的交易数据multi_transaction_data = dict(money=init_money, details=[])# 一次开仓交易的数据# money保存的是交易当前的金额# details保存的是所有的交易数据uni_transaction_data = dict(money=init_money, details=[])# 交易成本(双边)# 在计算收益的时候需要去掉service_charge = 2 / 10000.0# 以日期分组的数据data_group_by_date = {}# 沪深300期货每天的收盘价列表hu_shen_300_date_close_price_list = []# 沪深300期货每天的日期列表hu_shen_300_date_list = []

处理csv文件的工具类csv_file_utils.py

import csvfrom domain.configuration import Configuration# 以日期分组数据def group_data_by_date(file_path):# 从csv文件读取内容file = open(file_path, "r")line_list = csv.reader(file)# 保存以日期分组之后的内容data_group_by_date = Configuration.data_group_by_date# 不处理第一行字段index = 0# 遍历每一行内容for line in line_list:# 第一行数据是字段名称,不用处理index = index + 1if index == 1:continue# 把每一行数据转换成对象csv_data = dict(date=line[0], open=float(line[1]), close=float(line[2]), high=float(line[3]),low=float(line[4]),volume=int(line[5]), money=int(line[6]))# 截取日期,格式为年/月/日csv_date = line[0]csv_date = csv_date.split(" ")[0]# list保存一个日期的所有数据# 第一步先判断有没有保存这个日期的数据# 如果没有则初始化为空的数组# 如果有则拿出来if csv_date in data_group_by_date.keys():csv_data_list = data_group_by_date[csv_date]else:csv_data_list = []# 保存数据csv_data_list.append(csv_data)data_group_by_date[csv_date] = csv_data_list# 释放文件资源file.close()# 计算保存沪深300期货所有的日期和收盘价数据hu_shen_300_date_close_price_list = Configuration.hu_shen_300_date_close_price_listhu_shen_300_date_list = Configuration.hu_shen_300_date_listfor date in data_group_by_date:data_of_date = data_group_by_date[date] # 每天的数据len_of_data_of_date = len(data_of_date)close = data_of_date[len_of_data_of_date - 1]["close"] # 沪深300期货每天的收盘价hu_shen_300_date_list.append(date)hu_shen_300_date_close_price_list.append(close)print("沪深300期货所有的日期列表:")print(hu_shen_300_date_list)print("沪深300期货每天所有的收盘价数据:")print(hu_shen_300_date_close_price_list)

计算市场情绪平稳度的工具类emotional_stability_utils.py

# 计算情绪平稳度# 计算每分钟的最大回撤和反向最大回撤# 最大回撤计算公式max(1 - close_j / close_i)# 反向最大回撤计算公式-min(1 - close_j / close_i)# 然后计算平均最大回撤和平均反向最大回撤# 文档中指出使用收盘价格进行计算# 平均最大回撤和平均反向最大回撤,哪个小就是用哪个def calculate_emotional_stability(data):length_of_data = len(data)max_sum = 0.0 # 最大回撤求和min_sum = 0.0 # 反向最大回撤求和for i_value in range(0, length_of_data):close_i = data[i_value]["close"]max_value = 0.0 # 计算一分钟的最大回撤min_value = 0.0 # 计算一分钟的反向最大回撤for j_value in range(i_value + 1, length_of_data):close_j = data[j_value]["close"]calculate_result = 1 - close_j / close_iif calculate_result > max_value:max_value = calculate_resultif calculate_result < min_value:min_value = calculate_resultmax_sum += max_value # 把每一分钟的最大回撤相加min_sum += -min_value # 把每一分钟的反向最大回撤相加(注意取负值)max_ave = max_sum / length_of_data # 平均最大回撤min_ave = min_sum / length_of_data # 平均最大反向回撤print("平均最大回撤:" + str(max_ave))print("平均最大反向回撤:" + str(min_ave))# 比较平均最大回撤和平均最大反向回撤,哪个小就返回哪个if max_ave <= min_ave:print("采用平均最大回撤作为平稳度")return max_aveelse:print("采用平均最大反向回撤作为平稳度")return min_ave

绘制折线图的工具类line_chart_utils.py

# 绘制折线图import matplotlib.pyplot as plt# 绘制折线图from matplotlib.ticker import MultipleLocatorfrom domain.configuration import Configuration# 绘制折线图def draw_line_chart():# 从单次开仓交易数据中获取折线图的数据uni_line_chart_data = get_line_chart_data(Configuration.uni_transaction_data)uni_date_list = uni_line_chart_data["date_list"]uni_money_list = uni_line_chart_data["money_list"]# 从多次开仓交易数据中获取折线图的数据multi_line_chart_data = get_line_chart_data(Configuration.multi_transaction_data)multi_date_list = multi_line_chart_data["date_list"]multi_money_list = multi_line_chart_data["money_list"]plt.subplots_adjust(bottom=0.4) # 调节下方位置,不然日期太长会被挡住'''plt.subplots_adjust(bottom=0.9) # 调节下方位置,不然日期太长会被挡住plt.title("model cumulative income") # 标题,模型累计收益plt.xlabel("date") # x轴表示日期plt.ylabel("cumulative income") # y轴表示累计收益# 把x轴的刻度间隔设置为40,并存在变量里x_major_locator = MultipleLocator(40)# ax为两条坐标轴的实例ax = plt.gca()# 把x轴的主刻度设置为40的倍数ax.xaxis.set_major_locator(x_major_locator)# x轴倾斜90度for tick in ax.get_xticklabels():tick.set_rotation(90)'''# 开始绘制折线图fig = plt.figure(figsize=(20, 10))ax1 = fig.add_subplot(111)ax1.xaxis.set_major_locator(MultipleLocator(30))for tick in ax1.get_xticklabels():tick.set_rotation(90)ax1.plot(multi_date_list, multi_money_list, color="blue")ax1.plot(uni_date_list, uni_money_list, color="gray")ax2 = ax1.twinx() # this is the important functionax2.xaxis.set_major_locator(MultipleLocator(30))ax2.plot(Configuration.hu_shen_300_date_list, Configuration.hu_shen_300_date_close_price_list, color="orange")# 同时展示多条图表plt.legend()plt.show()# 从交易数据中获取绘制折线图所需要的数据def get_line_chart_data(transaction_data):# 保存x轴的数据 日期date_list = []# 保存y轴的数据 累计收益money_list = []for details in transaction_data["details"]:date_value = details["date"]money_value = details["money"]date_list.append(date_value)# 注意这里减去init_money非常必要,因为算的是累计收益,必须减去本金,不然会多100%money_list.append(money_value - Configuration.init_money)return dict(date_list=date_list, money_list=money_list)

计算累计收益的交易工具类transaction_utils.py

from utils import emotional_stability_utilsfrom domain.configuration import Configuration# 计算一天的交易数据# transaction_data 保存所有的交易数据# date_value 日期# date_init_list 一天所有的原始csv数据# sample_observation_begin_index 样本观察开始索引# sample_observation_end_index 样本观察结束索引# finish_index 收盘平仓时的索引def calculate_transaction_data(transaction_data, date_value, date_init_list, sample_observation_begin_index,sample_observation_end_index, finish_index):# 根据样本观察索引区间获取样本数据sample_observation = date_init_list[sample_observation_begin_index:sample_observation_end_index]print("样本长度为:" + str(len(sample_observation)))# 根据样本数据计算情绪平稳度emotional_stability = emotional_stability_utils.calculate_emotional_stability(sample_observation)# 情绪平稳度小于阈值,决定开仓if emotional_stability < Configuration.emotional_stability_threshold:print("情绪平稳度小于阈值,决定开仓")# 样本观察收盘价sample_observation_end_close = date_init_list[sample_observation_end_index - 1]["close"]# 样本观察开盘价sample_observation_begin_open = date_init_list[sample_observation_begin_index]["open"]# 在样本观察之后的下一分钟开盘买入buy_price = date_init_list[sample_observation_end_index]["open"]# 如果样本观察的收盘价大于样本观察开盘价,则做多if sample_observation_end_close > sample_observation_begin_open:print("开始做多")long = 1else:print("开始做空")long = 0for i_value in range(sample_observation_end_index + 1, finish_index):# 在开盘之后判断是否需要止损sell_price = date_init_list[i_value]["open"]# 如果做多,则用卖出价格减去买入价格if long == 1:percent = (sell_price - buy_price) / buy_price# 如果做空,则用买入价格减去卖出价格else:percent = (buy_price - sell_price) / sell_price# 如果损失大于止损阈值,则平仓止损if percent < 0 and abs(percent) > Configuration.stop_loss_threshold:print("平仓止损")transaction_data["money"] = transaction_data["money"] * (1 + percent - Configuration.service_charge)transaction_data["details"].append(dict(date=date_value, money=transaction_data["money"]))returnprint("收盘平仓")sell_price = date_init_list[finish_index - 1]["close"]# 如果做多,则用卖出价格减去买入价格if long == 1:percent = (sell_price - buy_price) / buy_price# 如果做空,则用买入价格减去卖出价格else:percent = (buy_price - sell_price) / sell_pricetransaction_data["money"] = transaction_data["money"] * (1 + percent - Configuration.service_charge)transaction_data["details"].append(dict(date=date_value, money=transaction_data["money"]))returnelse:print("情绪平稳度大于阈值,决定不开仓")transaction_data["details"].append(dict(date=date_value, money=transaction_data["money"]))return

最后是程序入口main.py

# 程序入口from utils import csv_file_utils, line_chart_utils, transaction_utilsfrom domain.configuration import Configuration# 以日期分组数据csv_file_utils.group_data_by_date(Configuration.file_path)data_group_by_date = Configuration.data_group_by_datefor date in data_group_by_date.keys():print("开始处理日期" + date + "的数据")# 当前日期所有的初始数据date_csv_list = data_group_by_date[date]length = len(date_csv_list)print("当前日期有" + str(length) + "条数据")# 早晨样本观察开始索引morning_sample_start = 0# 早晨样本观察结束索引morning_sample_end = 0# 早晨平仓索引morning_position_close = 0# 下午样本观察开始索引afternoon_sample_start = 0# 下午样本观察结束索引afternoon_sample_end = 0# 下午平仓索引afternoon_position_close = length# 多次开仓的交易策略中,上午开仓同原始策略一致,观察开盘后50分钟的收盘价样本,随后决定是否开仓。但是在11:30上午收市时平仓。下午开盘则充分利用上午的数据,观察包括上午收盘数据在内11:12至13:32的数据样本,并在13:33决定下午是否开仓。# 遍历该日期对应的所有时间点,找出操作点对应的索引for i in range(0, length):i_date = date_csv_list[i]["date"]if i_date.endswith("9:16"):morning_sample_start = iif i_date.endswith("10:06"):morning_sample_end = iif i_date.endswith("11:30"):morning_position_close = iif i_date.endswith("11:12"):afternoon_sample_start = iif i_date.endswith("13:32"):afternoon_sample_end = i# 多次开仓 --> 早晨开仓print("----------------------------------------")print("多次开仓 --> 早晨开仓,开始处理......")transaction_utils.calculate_transaction_data(Configuration.multi_transaction_data, date, date_csv_list,morning_sample_start,morning_sample_end, morning_position_close + 1)# 多次开仓 --> 下午开仓print("----------------------------------------")print("多次开仓 --> 下午开仓,开始处理......")transaction_utils.calculate_transaction_data(Configuration.multi_transaction_data, date, date_csv_list,afternoon_sample_start,afternoon_sample_end, afternoon_position_close)# 一次开仓print("----------------------------------------")print("一次开仓,开始处理......")transaction_utils.calculate_transaction_data(Configuration.uni_transaction_data, date, date_csv_list,morning_sample_start, morning_sample_end, afternoon_position_close)print("\r\n")# 开始绘制折线图line_chart_utils.draw_line_chart()

福利环节,源码链接地址(我永远喜欢薇尔莉特,永远喜欢编程ヾ(≧▽≦*)o)

source_code.zip

如果觉得《基于市场情绪平稳度的股指期货日内交易策略》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。