# =====产生交易信号:布林线策略
# ===布林线策略
# 布林线中轨:n天收盘价的移动平均线
# 布林线上轨:n天收盘价的移动平均线 + m * n天收盘价的标准差
# 布林线上轨:n天收盘价的移动平均线 - m * n天收盘价的标准差
# 当收盘价由下向上穿过上轨的时候,做多;然后由上向下穿过下轨的时候,平仓。
# 当收盘价由上向下穿过下轨的时候,做空;然后由下向上穿过上轨的时候,平仓。
import pandas as pd
import warnings #警告忽略
pd.set_option('display.max_rows', 500)
pd.set_option('expand_frame_repr', False) # 当列太多时不换行
pd.set_option('mode.chained_assignment', None) #关闭警告
df = pd.read_hdf('D:\work\lianghua\py\data\class8\eth_1min_data.h5', key='all_data') #5分钟数据导入
# warnings.filterwarnings("ignore")
#转换周期
df.set_index('candle_begin_time', inplace=True) #设置为index
df2 = df[['close']].resample('15T').last()
df2['low'] = df['low'].resample('15T').min()
df2['high'] = df['high'].resample('15T').max()
df2['open'] = df['open'].resample('15T').first()
df2['volume'] = df['volume'].resample('15T').sum()
df2.dropna(subset=['open'], inplace=True) #去除没有开盘价的数据 dropna 缺失值删除
df2 = df2[df2['volume'] > 0] #过滤成交量为0的交易
df2.reset_index(inplace=True)
df2 = df2[['candle_begin_time','open', 'high', 'low', 'close', 'volume']] #排序
df = df2[df2['candle_begin_time'] >= pd.to_datetime('2017-01-01')]
# =====产生交易信号:布林线策略
# ===布林线策略
# 布林线中轨:n天收盘价的移动平均线
# 布林线上轨:n天收盘价的移动平均线 + m * n天收盘价的标准差
# 布林线上轨:n天收盘价的移动平均线 - m * n天收盘价的标准差
# 当收盘价由下向上穿过上轨的时候,做多;然后由上向下穿过下轨的时候,平仓。
# 当收盘价由上向下穿过下轨的时候,做空;然后由下向上穿过上轨的时候,平仓。
n = 100
m = 2
#计算均线
df['median'] = df['close'].rolling(n, min_periods=1).mean()
#计算上轨、下轨道
df['std'] = df['close'].rolling(n, min_periods=1).std(ddof=0) # ddof代表标准差自由度 标准差计算
df['okup'] = df['median'] + m * df['std']
df['oklow'] = df['median'] - m * df['std']
# 找出做多信号 收盘价大于上轨 之前K线的收盘价小于上轨
condition1 = df['close'] > df['okup']
condition2 = df['close'].shift(1) <= df['okup'].shift(1)
df.loc[condition1 & condition2,'signal_long'] = 1
# 做多平仓信号 当前K线收盘价<中轨 之前K线的收盘价 >= 中轨
condition1 = df['close'] < df['median']
condition2 = df['close'].shift(1) >= df['median'].shift(1)
df.loc[condition1 & condition2,'signal_long'] = 0
# 找出做空
condition1 = df['close'] < df['oklow']
condition2 = df['close'].shift(1) >= df['oklow'].shift(1)
df.loc[condition1 & condition2,'signal_short'] = -1
# 做空平仓
condition1 = df['close'] > df['median']
condition2 = df['close'].shift(1) <= df['median'].shift(1)
df.loc[condition1 & condition2,'signal_short'] = 0
# ===合并做多做空信号,去除重复信号 (横向相加)
# df['signal'] = df[['signal_long', 'signal_short']].sum() #axis=0指的是逐行,axis=1指的是逐列。
# print(df[['signal_long','signal_short','signal']].head(500))
# df['signal'] = df[['signal_long', 'signal_short']].sum(axis=1, skipna=True)
df.loc[:,'signal'] = df.loc[:,['signal_long','signal_short']].sum(axis=1, min_count=1)
#对合并信号进行调整
#先将不为空的信号存储
# temp = df[df['signal'].notnull()][['signal']] #非空的signal给temp signal 列
# # #找到和上一行不一样的信号
# temp = temp[temp['signal'] != temp['signal'].shift(1)]
# #将不一样信号重新附加给signal
# df['signal'] = temp['signal']
df.drop(['median', 'std', 'okup', 'oklow', 'signal_long', 'signal_short'], axis=1, inplace=True) #删除之前参数
df.reset_index(inplace=True)
# ============ 开始计算资金曲线
df['pos'] = df['signal'].shift() #实际的操作要在第二根K新开仓
df['pos'].fillna(method='ffill',inplace = True)#向上补全
df['pos'].fillna(0,inplace = True)#补全初始Nan为0
print(df.head(500))
df.to_hdf('bolling_signal.h5', key='all_data')
#fillna test

