# SMI指标事件策略复现 **Published by:** [不确定性守恒](https://paragraph.com/@uniswapv6/) **Published on:** 2022-06-09 **URL:** https://paragraph.com/@uniswapv6/smi ## Content https://bbs.quantclass.cn/thread/12407一、指标说明二、策略代码2.1、指标计算# batch_parameters() def calculate(df, parameters, **kwargs): """ 计算单个币种的因子 这边坚决不能进行去重或者删除空值等删除某行的操作 :param df: 需要计算的币种数据 :param parameters: 参数 :param kwargs: 额外的参数 :return: """ N1, N2, N3 = parameters # print(N1) H = df['high'].rolling(N1).max() # print(H) L = df['low'].rolling(N1).min() # print(L) M = (H+L)/2 # print(M) D = df['close']-M # print(D) # print(type(D)) _DS = D.ewm(span=N2).mean() # print(_DS) DS = _DS.ewm(span=N2).mean() # print(DS) _DHL = (H-L).ewm(span=N2).mean() DHL = _DHL.ewm(span=N2).mean() SMI = 100*DS/DHL # print(SMI) SMIMA = SMI.rolling(window=N3).mean() # print(SMIMA) df['{}_{}'.format(factor_name,parameters)]=SMI df['{}MA_{}'.format(factor_name,parameters)] = SMIMA return df 2.2、遍历代码def batch_parameters(): """ 生成遍历的参数 :return: """ one_parameters_list = [2, 3, 5, 8, 13, 21, 34, 55, 89] _para = one_parameters_list[-1] while _para < 500: _para = int(_para/0.618) one_parameters_list.append(_para) n1n2_list = [] for i in one_parameters_list: for j in one_parameters_list: n1n2_list.append([i, j]) parameters_list=[] for i in n1n2_list: for j in one_parameters_list: parameters_list.append([i[0], i[1], j]) print() return parameters_list[:300] 2.3、事件定义SMI指标上穿其均线时,买入。 (均线为当日收盘价与最近N天的最高价与最低价均值之间的距离值)def event_strategy(df, params, **kwargs): """ 计算事件 :param df: 数据 :param params: :return: """ event_name = '{}_{}'.format(strategy_name, params) # 策略名称 #-----long------------- #条件1,SMI上穿其均线,做多 con1 = df['SMI_{}'.format(params)] > df['SMIMA_{}'.format(params)] #条件2,上一周期,SMI在均线下 #短线对应SMI df['SMI_shift_{}'.format(params)] = df.groupby('symbol')['SMI_{}'.format(params)].shift() #长线对应SMIMA df['SMIMA_shift_{}'.format(params)] = df.groupby('symbol')['SMIMA_{}'.format(params)].shift() con2=df['SMI_shift_{}'.format(params)] <df['SMIMA_shift_{}'.format(params)] df.loc[con1 & con2, event_name] = 1 return df 三、回测结果(收益回撤比Top3)3.1、TOP1资金曲线3.2、事件频率3.3、回测评价3.4、最优结果每年表现3.5、TOP1盈利最多三笔交易3.6、TOP1亏损最多三笔交易四、遍历结果(收益回撤比前十)五、附件内容1、指标计算代码import pandas as pd factor_name = 'SMI' def special_data(candle_df, symbol, agg_dict, **kwargs): """ 导入额外的数据 :param candle_df: 基础数据 :param symbol: 币种名 :param agg_dict: 转换周期的字典 :return: """ return candle_df, agg_dict def batch_parameters(): """ 生成遍历的参数 :return: """ one_parameters_list = [2, 3, 5, 8, 13, 21, 34, 55, 89] _para = one_parameters_list[-1] while _para < 500: _para = int(_para/0.618) one_parameters_list.append(_para) n1n2_list = [] for i in one_parameters_list: for j in one_parameters_list: n1n2_list.append([i, j]) parameters_list=[] for i in n1n2_list: for j in one_parameters_list: parameters_list.append([i[0], i[1], j]) print() return parameters_list[:300] # batch_parameters() def calculate(df, parameters, **kwargs): """ 计算单个币种的因子 这边坚决不能进行去重或者删除空值等删除某行的操作 :param df: 需要计算的币种数据 :param parameters: 参数 :param kwargs: 额外的参数 :return: """ N1, N2, N3 = parameters # print(N1) H = df['high'].rolling(N1).max() # print(H) L = df['low'].rolling(N1).min() # print(L) M = (H+L)/2 # print(M) D = df['close']-M # print(D) # print(type(D)) _DS = D.ewm(span=N2).mean() # print(_DS) DS = _DS.ewm(span=N2).mean() # print(DS) _DHL = (H-L).ewm(span=N2).mean() DHL = _DHL.ewm(span=N2).mean() SMI = 100*DS/DHL # print(SMI) SMIMA = SMI.rolling(window=N3).mean() # print(SMIMA) df['{}_{}'.format(factor_name,parameters)]=SMI df['{}MA_{}'.format(factor_name,parameters)] = SMIMA return df def cross_section_calculate(df, parameters, **kwargs): """ 计算截面因子的函数 :param df: 所有币种的数据 :param parameters: 参数 :param kwargs: 额外的参数 :return: """ df['{}_{}_排名' .format (factor_name,parameters)] = df.groupby('candle_begin_time')['{}_{}'.format(factor_name,parameters)].rank(ascending=False, method='first') return df 2、事件生成代码# 事件需要的因子 factors = ['SMI'] # 事件的名称名 strategy_name = 'SMI&event' # 名称和程序文件名相同,不能含有_ def batch_parameters(): """ 生成遍历的参数 :return: """ one_parameters_list = [2, 3, 5, 8, 13, 21, 34, 55, 89] _para = one_parameters_list[-1] while _para < 500: _para = int(_para/0.618) one_parameters_list.append(_para) n1n2_list = [] for i in one_parameters_list: for j in one_parameters_list: n1n2_list.append([i, j]) parameters_list=[] for i in n1n2_list: for j in one_parameters_list: parameters_list.append([i[0], i[1], j]) return parameters_list[:300] # print(batch_parameters()) def event_strategy(df, params, **kwargs): """ 计算事件 :param df: 数据 :param params: :return: """ event_name = '{}_{}'.format(strategy_name, params) # 策略名称 #-----long------------- #条件1,SMI上穿其均线,做多 con1 = df['SMI_{}'.format(params)] > df['SMIMA_{}'.format(params)] #条件2,上一周期,SMI在均线下 #短线对应SMI df['SMI_shift_{}'.format(params)] = df.groupby('symbol')['SMI_{}'.format(params)].shift() #长线对应SMIMA df['SMIMA_shift_{}'.format(params)] = df.groupby('symbol')['SMIMA_{}'.format(params)].shift() con2=df['SMI_shift_{}'.format(params)] <df['SMIMA_shift_{}'.format(params)] df.loc[con1 & con2, event_name] = 1 return df 3、遍历回测结果https://bbs.quantclass.cn/thread/12407 ## Publication Information - [不确定性守恒](https://paragraph.com/@uniswapv6/): Publication homepage - [All Posts](https://paragraph.com/@uniswapv6/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@uniswapv6): Subscribe to updates