def trendBreak(pdDataFrame): """ trendBreak based on provdied market data """ from abupy import pd_rolling_max from abupy import pd_expanding_max # 当天收盘价格超过N1天内最高价格作为买入信号 N1 = 20 # 当天收盘价格超过N2天内最低价格作为卖出信号 N2 = 15 kl_pd = pdDataFrame # 通过rolling_max方法计算最近N1个交易日的最高价 # kl_pd['n1_high'] = pd.rolling_max(kl_pd['high'], window=N1) kl_pd['n1_high'] = pd_rolling_max(kl_pd['high'], window=N1) # 表7-4所示 # expanding_max # expan_max = pd.expanding_max(kl_pd['close']) expan_max = pd_expanding_max(kl_pd['close']) # fillna使用序列对应的expan_max kl_pd['n1_high'].fillna(value=expan_max, inplace=True) # 表7-5所示 #print('kl_pd[0:5]:\n', kl_pd[0:5]) from abupy import pd_rolling_min, pd_expanding_min # 通过rolling_min方法计算最近N2个交易日的最低价格 # rolling_min与rolling_max类似 # kl_pd['n2_low'] = pd.rolling_min(kl_pd['low'], window=N2) kl_pd['n2_low'] = pd_rolling_min(kl_pd['low'], window=N2) # expanding_min与expanding_max类似 # expan_min = pd.expanding_min(kl_pd['close']) expan_min = pd_expanding_min(kl_pd['close']) # fillna使用序列对应的eexpan_min kl_pd['n2_low'].fillna(value=expan_min, inplace=True) # 当天收盘价格超过N天内的最高价或最低价, 超过最高价格作为买入信号买入股票持有 buy_index = kl_pd[kl_pd['close'] > kl_pd['n1_high'].shift(1)].index kl_pd.loc[buy_index, 'signal'] = 1 # 当天收盘价格超过N天内的最高价或最低价, 超过最低价格作为卖出信号 sell_index = kl_pd[kl_pd['close'] < kl_pd['n2_low'].shift(1)].index kl_pd.loc[sell_index, 'signal'] = 0 #kl_pd.signal.value_counts().plot(kind='pie', figsize=(5, 5)) #plt.show() """ 将信号操作序列移动一个单位,代表第二天再将操作信号执行,转换得到持股状态 这里不shift(1)也可以,代表信号产生当天执行,但是由于收盘价格是在收盘后 才确定的,计算突破使用了收盘价格,所以使用shift(1)更接近真实情况 """ kl_pd['keep'] = kl_pd['signal'].shift(1) kl_pd['keep'].fillna(method='ffill', inplace=True) return kl_pd
def MINMACACalculate(sample): rate = 0.015 sample['EMA12'] = QA.EMA(sample.close, 12) sample['EMA5'] = QA.EMA(sample.close, 5) sample['MA64'] = QA.MA(sample.close, 64) sample['MA256'] = QA.MA(sample.close, 256) sample['EMA20'] = QA.EMA(sample.close, 20) sample['k1'] = 0.618 * QA.HHV(sample.high, 256) + 0.382 * QA.LLV( sample.low, 256) sample['k2'] = 0.5 * QA.HHV(sample.high, 256) + 0.5 * QA.LLV( sample.low, 256) sample['k3'] = 0.382 * QA.HHV(sample.high, 256) + 0.618 * QA.LLV( sample.low, 256) sample['EMA30'] = QA.EMA(sample.close, 30) sample['EMA13'] = QA.EMA(sample.close, 13) sample['optimism'] = sample.high - sample.EMA13 sample['pessmist'] = sample.low - sample.EMA13 sample['up'] = sample.EMA13 * (1 + rate) sample['down'] = sample.EMA13 * (1 - rate) sample['EMA26'] = QA.EMA(sample.close, 26) sample['MACDQ'] = sample['EMA12'] - sample['EMA26'] sample['MACDSIG'] = QA.EMA(sample['MACDQ'], 9) sample['MACDBlock'] = sample['MACDQ'] - sample['MACDSIG'] sample['VolumeEMA'] = QA.EMA(sample.volume, 5) #sample['VolumeEMA'] = QA.EMA(sample.vol, 5) #trend block from abupy import pd_rolling_max from abupy import pd_expanding_max N = 15 sample['nhigh'] = pd_rolling_max(sample.high, window=N) expanmax = pd_expanding_max(sample.close) sample['nhigh'].fillna(value=expanmax, inplace=True) from abupy import pd_rolling_min, pd_expanding_min sample['nlow'] = pd_rolling_min(sample.low, window=N) expanmin = pd_expanding_min(sample.close) sample['nlow'].fillna(value=expanmin, inplace=True) sroc = [] for i in range(sample.shape[0]): if (i - 21 > 0 and sample.iloc[i].EMA13 != None and sample.iloc[i - 21].EMA13 != None): # print(sample.iloc[i].EMA13/sample.iloc[i-21].EMA13) sroc.append( (sample.iloc[i].EMA13 / sample.iloc[i - 21].EMA13) * 100) else: sroc.append(100) sample['SROC'] = sroc return sample
def TrendFinder(day, short=20, mid=60, long=120): #20, 30 , 60 5.3/10 # 20, 60, 120 5.0/10 #10, 20, 60 6.7/10 #10, 30, 60 5.7/10 day['long'] = QA.EMA(day.close, long) day['mid'] = QA.EMA(day.close, mid) day['short'] = QA.EMA(day.close, short) day['BIAS'] = (day.close - day.long) * 100 / day.long day['BMA'] = QA.EMA(day.BIAS, short) day['CS'] = (day.close - day.short) * 100 / day.short day['SM'] = (day.short - day.mid) * 100 / day.mid day['ML'] = (day.mid - day.long) * 100 / day.long day['threshold'] = pd_rolling_max(day.BIAS, window=2 * long) day['nthreshold'] = pd_rolling_min(day.BIAS, window=2 * long) sig = [] buy = 0 sell = 0 for i in range(day.shape[0]): if (day.BIAS[i] >= 0): flag = day.BIAS[i] / day.threshold[i] else: flag = day.BIAS[i] / day.nthreshold[i] if (day.CS[i] > 0 and day.SM[i] > 0 and buy == 0): sig.append(1) buy = 1 sell = 0 elif (day.CS[i] < 0 and day.SM[i] < 0 and sell == 1): sig.append(3) sell = 1 buy = 0 elif (day.CS[i] < 0 and day.BIAS[i] < day.BMA[i] and sell == 0): sig.append(5) buy = 0 sell = 1 else: sig.append(0) day['single'] = sig # day['single'] = [0]+sig[:-1] return day
def trendBreak(pdDataFrame): from abupy import pd_rolling_max from abupy import pd_expanding_max # 当天收盘价格超过N1天内最高价格作为买入信号 N1 = 40 # 当天收盘价格超过N2天内最低价格作为卖出信号 N2 = 20 kl_pd = pdDataFrame # 通过rolling_max方法计算最近N1个交易日的最高价 # kl_pd['n1_high'] = pd.rolling_max(kl_pd['high'], window=N1) kl_pd['n1_high'] = pd_rolling_max(kl_pd['high'], window=N1) # 表7-4所示 # expanding_max # expan_max = pd.expanding_max(kl_pd['close']) expan_max = pd_expanding_max(kl_pd['close']) # fillna使用序列对应的expan_max kl_pd['n1_high'].fillna(value=expan_max, inplace=True) # 表7-5所示 # print('kl_pd[0:5]:\n', kl_pd[0:5]) from abupy import pd_rolling_min, pd_expanding_min # 通过rolling_min方法计算最近N2个交易日的最低价格 # rolling_min与rolling_max类似 # kl_pd['n2_low'] = pd.rolling_min(kl_pd['low'], window=N2) kl_pd['n2_low'] = pd_rolling_min(kl_pd['low'], window=N2) # expanding_min与expanding_max类似 # expan_min = pd.expanding_min(kl_pd['close']) expan_min = pd_expanding_min(kl_pd['close']) # fillna使用序列对应的eexpan_min kl_pd['n2_low'].fillna(value=expan_min, inplace=True) cb = QA.CROSS(kl_pd.close,kl_pd.n1_high) cs = QA.CROSS(kl_pd.n2_low,kl_pd.close) ss = np.where(cs==1,3,0) bs = np.where(cb==1,1,ss) sig = [0]+bs[:-1].tolist() kl_pd['single'] = sig return kl_pd
# plt.axhline(close_mean,color='black',lw=1) # plt.axhline(sell_signal,color='g',lw=3) # plt.legend(['train close','buy_signal','close_mean','sell_signal'], loc='best') # # buy_index = train_kl[train_kl['close']< buy_signal].index # train_kl.loc[buy_index,'signal'] =1 #趋势跟踪策略 #当天收盘价超过N1天内最高价格作为买入信号 N1 = 42 #当天收盘价超过N2天内最低价格作为卖出信号 N2 = 21 kl_pd['n1_high'] = pd_rolling_max(kl_pd['high'], window=N1) kl_pd['n2_low'] = pd_rolling_min(kl_pd['low'], window=N2) expan_min = pd_expanding_min(kl_pd['close']) kl_pd['n2_low'].fillna(value=expan_min, inplace=True) buy_index = kl_pd[kl_pd['close'] > kl_pd['n1_high'].shift(1)].index kl_pd.loc[buy_index, 'signal'] = 1 sell_index = kl_pd[kl_pd['close'] < kl_pd['n2_low'].shift(1)].index kl_pd.loc[sell_index, 'signal'] = 0 kl_pd['keep'] = kl_pd['signal'].shift(1) kl_pd['keep'].fillna(method='ffill', inplace=True) #计算基准收益 kl_pd['benchmark_profit'] = np.log(kl_pd['close'] / kl_pd['close'].shift(1)) #计算使用趋势突破策略的收益
def sample_713(): """ 7.1.3 趋势跟踪策略 :return: """ # rolling_max示例序列 demo_list = np.array([1, 2, 1, 1, 100, 1000]) # 对示例序列以3个为一组,寻找每一组中的最大值 from abupy import pd_rolling_max # print('pd.rolling_max(demo_list, window=3):', pd.rolling_max(demo_list, window=3)) print('pd.rolling_max(demo_list, window=3):', pd_rolling_max(demo_list, window=3)) from abupy import pd_expanding_max # expanding_max示例序列 demo_list = np.array([1, 2, 1, 1, 100, 1000]) # print('pd.expanding_max(demo_list):', pd.expanding_max(demo_list)) print('pd.expanding_max(demo_list):', pd_expanding_max(demo_list)) # 当天收盘价格超过N1天内最高价格作为买入信号 N1 = 42 # 当天收盘价格超过N2天内最低价格作为卖出信号 N2 = 21 # 通过rolling_max方法计算最近N1个交易日的最高价 # kl_pd['n1_high'] = pd.rolling_max(kl_pd['high'], window=N1) kl_pd['n1_high'] = pd_rolling_max(kl_pd['high'], window=N1) # 表7-4所示 print('kl_pd[0:5]:\n', kl_pd[0:5]) # expanding_max # expan_max = pd.expanding_max(kl_pd['close']) expan_max = pd_expanding_max(kl_pd['close']) # fillna使用序列对应的expan_max kl_pd['n1_high'].fillna(value=expan_max, inplace=True) # 表7-5所示 print('kl_pd[0:5]:\n', kl_pd[0:5]) from abupy import pd_rolling_min, pd_expanding_min # 通过rolling_min方法计算最近N2个交易日的最低价格 # rolling_min与rolling_max类似 # kl_pd['n2_low'] = pd.rolling_min(kl_pd['low'], window=N2) kl_pd['n2_low'] = pd_rolling_min(kl_pd['low'], window=N2) # expanding_min与expanding_max类似 # expan_min = pd.expanding_min(kl_pd['close']) expan_min = pd_expanding_min(kl_pd['close']) # fillna使用序列对应的eexpan_min kl_pd['n2_low'].fillna(value=expan_min, inplace=True) # 当天收盘价格超过N天内的最高价或最低价, 超过最高价格作为买入信号买入股票持有 buy_index = kl_pd[kl_pd['close'] > kl_pd['n1_high'].shift(1)].index kl_pd.loc[buy_index, 'signal'] = 1 # 当天收盘价格超过N天内的最高价或最低价, 超过最低价格作为卖出信号 sell_index = kl_pd[kl_pd['close'] < kl_pd['n2_low'].shift(1)].index kl_pd.loc[sell_index, 'signal'] = 0 kl_pd.signal.value_counts().plot(kind='pie', figsize=(5, 5)) plt.show() """ 将信号操作序列移动一个单位,代表第二天再将操作信号执行,转换得到持股状态 这里不shift(1)也可以,代表信号产生当天执行,但是由于收盘价格是在收盘后 才确定的,计算突破使用了收盘价格,所以使用shift(1)更接近真实情况 """ kl_pd['keep'] = kl_pd['signal'].shift(1) kl_pd['keep'].fillna(method='ffill', inplace=True) # 计算基准收益 kl_pd['benchmark_profit'] = np.log( kl_pd['close'] / kl_pd['close'].shift(1)) # 计算使用趋势突破策略的收益 kl_pd['trend_profit'] = kl_pd['keep'] * kl_pd['benchmark_profit'] # 可视化收益的情况对比 kl_pd[['benchmark_profit', 'trend_profit']].cumsum().plot(grid=True, figsize=( 14, 7)) plt.show()