def Chaikin_vol(High, Low, timeperiod=10): Range = High - Low return ((pd.DataFrame(talib.EMA(Range, timeperiod)).pct_change() - 1) * 100.0).values
import pandas as pd import pandas.io.data as web import datetime as dt import matplotlib.pyplot as plt import talib as ta # Data Download start = dt.datetime(2014, 10, 1) end = dt.datetime(2015, 9, 30) aapl = web.DataReader('AAPL', 'yahoo', start, end) ########## # 2. Exponential Moving Averages EMA(5 & 21) Calculation and Chart # Technical Indicator Calculation aapl['ema5'] = ta.EMA(np.asarray(aapl['Close']), 5) aapl['ema21'] = ta.EMA(np.asarray(aapl['Close']), 21) # Technical Indicator Chart aapl.plot(y=['Close', 'ema5', 'ema21']) plt.title('Apple Close Prices & Exponential Moving Averages EMA(5 & 21)') plt.legend(loc='upper left') plt.show() ########## # 3. Double Crossover Trading Signals # Previous Periods Data (avoid back-testing bias) aapl['ema5(-1)'] = aapl['ema5'].shift(1) aapl['ema21(-1)'] = aapl['ema21'].shift(1) aapl['ema5(-2)'] = aapl['ema5'].shift(2) aapl['ema21(-2)'] = aapl['ema21'].shift(2)
def __uptrend(price_action, window_size): ema = ta.EMA(price_action, window_size) for i in range(1, window_size + 1): if price_action[-i] < ema[-i]: return False return True
# AVGPRICE ti_AVGPRICE = talib.AVGPRICE(bars['open'].values, bars['high'].values, bars['low'].values, bars['close'].values) # CMO ti_CMO = talib.CMO(bars['price'].values, time_period) # DEMA ti_DEMA = talib.DEMA(bars['price'].values, time_period) # DX ti_DX = talib.DX(bars['high'].values, bars['low'].values, bars['close'].values, time_period) # EMA ti_EMA = talib.EMA(bars['price'].values, time_period) # MACDEXT ti_MACD, ti_MACDSIGNAL, ti_MACDHIST = talib.MACDFIX(bars['price'].values) # MEDPRICE ti_MEDPRICE = talib.MEDPRICE(bars['high'].values, bars['low'].values) # MFI ti_MFI = talib.MFI(bars['high'].values, bars['low'].values,\ bars['close'].values, vol['volume'].values, time_period) # MINUS_DI ti_MINUS_DI = talib.MINUS_DI(bars['high'].values, bars['low'].values,\ bars['close'].values, time_period)
i = 0 list_indicators = [] list_missing = [] for index, row in final_pairs_to_csv.iterrows(): try: i += 1 df_daily = cryptocompare_wrapper.hourly_price_historical(row['Coin'], row['Pair_tuple'], limit=250, aggregate=4, exchange=row['Exchange']) closes = df_daily.close.values lows = df_daily.low.values highs = df_daily.high.values opens = df_daily.open.values volumetos = df_daily.volumeto.values rsi = talib.RSI(closes, timeperiod=14) ema12 = talib.EMA(closes, timeperiod=12) ema26 = talib.EMA(closes, timeperiod=26) ema50 = talib.EMA(closes, timeperiod=50) ema200 = talib.EMA(closes, timeperiod=200) atr = talib.ATR(highs, lows, closes, timeperiod=14) obv = talib.OBV(closes, volumetos) list_indicators.append([row.Coin + '/' + row.Pair_tuple, closes[-2], rsi[-2], ema50[-2], ema200[-2]]) print(i) #if i == 5: break except: list_missing.append([row.Coin + '/' + row.Pair_tuple, row.Exchange]) pass df_indicators = pd.DataFrame(list_indicators, columns=['Pair', '4H Close', '4H RSI', '4H EMA50', '4H EMA200']) df_indicators.set_index('Pair', inplace=True)
def EMA(matrix, timeperiod): matrix['EMA' + str(timeperiod)] = talib.EMA(real=matrix['1-Close'].values, timeperiod=timeperiod) return matrix
def main(): LogProfitReset() LogReset() Log("init OK", time.strftime('%Y-%m-%d %X', time.localtime(time.time()))) Log(a, b, c, d) _G("ok", 123) Log(GetPid(), _G(), _G("ok"), _G("dummy")) Sleep(1000) _G(None) Log(_G("ok")) LogStatus("Time", time.time()) EnableLog(True) SetErrorFilter("net") Log(GetLastError()) Log(GetCommand()) ticker = exchange.GetTicker() Log('ticker buy', ticker.Buy, ticker['Buy']) r = _C(exchange.GetRecords) Log(TA.ATR(r)) Log(TA.EMA(r, 10)) # test talib Log(str(talib.EMA(r.Close, 10))) for e in exchanges: Log(e.GetName(), e.GetRate(), e.GetCurrency(), e.GetFee()) Log(e.GetAccount()) Log(_C(e.GetOrders)) Log(e.GetOrder(10)) Log(e.CancelOrder(10000)) Log(e.IO("api", "userinfo")) Log(e.IO("api", "order_info", "symbol=btc_usd&order_id=3")) Log(e.GetUSDCNY()) #Log(e.GetPosition()) #Log(e.SetContractType("next_week")) Log(e.GetTicker()) Log('Asks:', len(e.GetDepth().Asks)) #Log(e.SetMarginLevel(10)) #Log(e.SetDirection("buy")) #Log(e.SetContractType("quarter")) #Log(e.GetRecords(PERIOD_M30)[0]) Log(e.GetRecords()[0]) x = Chart({ 'title': { 'text': 'test chart' }, 'xAxis': { 'type': 'datetime' }, 'series': [{ 'name': 'Buy', 'data': [] }, { 'name': 'Sell', 'data': [] }] }) x.reset() Log("策略将每10秒更新一次ticker") for i in range(100): ts = int(time.time() * 1000) ticker = _C(exchange.GetTicker) x.add(0, [ts, ticker.Buy]) x.add(1, [ts, ticker.Sell]) LogStatus(ticker) Sleep(10000)
def vfi(dataframe, length=130, coef=0.2, vcoef=2.5, signalLength=5, smoothVFI=False): """ Volume Flow Indicator conversion Author: creslinux, June 2018 - Python Original Author: Chris Moody, TradingView - Pinescript To return vfi, vfima and histogram A simplified interpretation of the VFI is: * Values above zero indicate a bullish state and the crossing of the zero line is the trigger or buy signal. * The strongest signal with all money flow indicators is of course divergence. * A crossover of vfi > vfima is uptrend * A crossunder of vfima > vfi is downtrend * smoothVFI can be set to smooth for a cleaner plot to ease false signals * histogram can be used against self -1 to check if upward or downward momentum Call from strategy to populate vfi, vfima, vfi_hist into dataframe Example how to call: # Volume Flow Index: Add VFI, VFIMA, Histogram to DF dataframe['vfi'], dataframe['vfima'], dataframe['vfi_hist'] = \ vfi(dataframe, length=130, coef=0.2, vcoef=2.5, signalLength=5, smoothVFI=False) :param dataframe: :param length: - VFI Length - 130 default :param coef: - price coef - 0.2 default :param vcoef: - volume coef - 2.5 default :param signalLength: - 5 default :param smoothVFI: bool - False detault :return: vfi, vfima, vfi_hist """ """" Original Pinescript From: https://www.tradingview.com/script/MhlDpfdS-Volume-Flow-Indicator-LazyBear/ length = input(130, title="VFI length") coef = input(0.2) vcoef = input(2.5, title="Max. vol. cutoff") signalLength=input(5) smoothVFI=input(false, type=bool) #### Conversion summary to python - ma(x,y) => smoothVFI ? sma(x,y) : x // Added as smoothVFI test on vfi - typical = hlc3 // Added to DF as HLC - inter = log(typical) - log(typical[1]) // Added to DF as inter - vinter = stdev(inter, 30) // Added to DF as vinter - cutoff = coef * vinter * close // Added to DF as cutoff - vave = sma(volume, length)[1] // Added to DF as vave - vmax = vave * vcoef // Added to Df as vmax - vc = iff(volume < vmax, volume, vmax) // Added np.where test, result in DF as vc - mf = typical - typical[1] // Added into DF as mf - typical is hlc3 - vcp = iff(mf > cutoff, vc, iff(mf < -cutoff, -vc, 0)) // added in def vcp, in DF as vcp - vfi = ma(sum(vcp, length) / vave, 3) // Added as DF vfi. Will sma vfi 3 if smoothVFI flag set - vfima = ema(vfi, signalLength) // added to DF as vfima - d = vfi-vfima // Added to df as histogram ### Pinscript plotout - nothing to do here for freqtrade. plot(0, color=gray, style=3) showHisto=input(false, type=bool) plot(showHisto ? d : na, style=histogram, color=gray, linewidth=3, transp=50) plot( vfima , title="EMA of vfi", color=orange) plot( vfi, title="vfi", color=green,linewidth=2) """ import talib as ta from math import log from pyti.simple_moving_average import simple_moving_average as sma from numpy import where length = length coef = coef vcoef = vcoef signalLength = signalLength smoothVFI = smoothVFI df = dataframe # Add hlc3 and populate inter to the dataframe df['hlc'] = ((df['high'] + df['low'] + df['close']) / 3).astype(float) df['inter'] = df['hlc'].map(log) - df['hlc'].shift(+1).map(log) df['vinter'] = df['inter'].rolling(30).std(ddof=0) df['cutoff'] = (coef * df['vinter'] * df['close']) # Vave is to be calculated on volume of the past bar df['vave'] = sma(df['volume'].shift(+1), length) df['vmax'] = df['vave'] * vcoef df['vc'] = where((df['volume'] < df['vmax']), df['volume'], df['vmax']) df['mf'] = df['hlc'] - df['hlc'].shift(+1) # more logic for vcp, so create a def and df.apply it def vcp(x): if x['mf'] > x['cutoff']: return x['vc'] elif x['mf'] < -(x['cutoff']): return -(x['vc']) else: return 0 df['vcp'] = df.apply(vcp, axis=1) # vfi has a smooth option passed over def call, sma if set df['vfi'] = (df['vcp'].rolling(length).sum()) / df['vave'] if smoothVFI == True: df['vfi'] = sma(df['vfi'], 3) df['vfima'] = ta.EMA(df['vfi'], signalLength) df['vfi_hist'] = df['vfi'] - df['vfima'] # clean up columns used vfi calculation but not needed for strat df.drop('hlc', axis=1, inplace=True) df.drop('inter', axis=1, inplace=True) df.drop('vinter', axis=1, inplace=True) df.drop('cutoff', axis=1, inplace=True) df.drop('vave', axis=1, inplace=True) df.drop('vmax', axis=1, inplace=True) df.drop('vc', axis=1, inplace=True) df.drop('mf', axis=1, inplace=True) df.drop('vcp', axis=1, inplace=True) return df['vfi'], df['vfima'], df['vfi_hist']
def on_tick(self, tick: TickData): """ Callback of new tick data update. """ # 时间过滤 if (tick.datetime.time() > self.day_open_time and tick.datetime.time() < self.day_close_time) or ( tick.datetime.time() > self.night_open_time) or ( tick.datetime.time() < self.night_close_time): self.flag = 1 self.put_counter += 1 if self.put_counter > 120: self.put_counter = 0 self.put_event() else: if self.flag == 0: return tick_time = tick.datetime self.write_log("{0} in on_tick:不在交易时间".format(tick_time)) print("{0} in on_tick:不在交易时间".format(tick_time)) # 活跃单全撤 self.cancel_all() # 市价平仓 if self.get_pos(self.leg1_symbol) > 0: # leg1平多 vt_orderids = self.sell( self.leg1_symbol, self.leg1_last_bid - 10 * self.pricetick, abs(self.get_pos(self.leg1_symbol))) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) if self.get_pos(self.leg1_symbol) < 0: # leg1平空 vt_orderids = self.cover( self.leg1_symbol, self.leg1_last_ask + 10 * self.pricetick, abs(self.get_pos(self.leg1_symbol))) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) if self.get_pos(self.leg2_symbol) > 0: # leg2平多 vt_orderids = self.sell( self.leg2_symbol, self.leg2_last_bid - 10 * self.pricetick, abs(self.get_pos(self.leg2_symbol))) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) if self.get_pos(self.leg2_symbol) < 0: # leg2平空 vt_orderids = self.cover( self.leg2_symbol, self.leg2_last_ask + 10 * self.pricetick, abs(self.get_pos(self.leg2_symbol))) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) self.flag = 0 # 回到初始状态 self.write_log("该交易时段交易次数{0},单腿风险次数{1},单腿风险比{2}".format( self.trade_counter, self.risk_counter, 2 * self.risk_counter / self.trade_counter + 1)) print("该交易时段交易次数{0},单腿风险次数{1},单腿风险比{2}".format( self.trade_counter, self.risk_counter, 2 * self.risk_counter / self.trade_counter + 1)) self.spread_count = 0 self.spread_mid_array.clear() self.counter = 0 self.try_open = 0 self.risk_counter = 0 self.trade_counter = 0 self.put_counter = 0 return # 行情 if tick.vt_symbol == self.leg1_symbol: self.leg1_last_ask = tick.ask_price_1 self.leg1_last_bid = tick.bid_price_1 if self.dom_symbol == 1: spread_mid = (self.leg1_last_ask - self.leg2_last_bid + self.leg1_last_bid - self.leg2_last_ask) / 2 self.spread_mid_array.append(spread_mid) self.spread_count += 1 else: return elif tick.vt_symbol == self.leg2_symbol: self.leg2_last_ask = tick.ask_price_1 self.leg2_last_bid = tick.bid_price_1 if self.dom_symbol == 2: spread_mid = (self.leg1_last_ask - self.leg2_last_bid + self.leg1_last_bid - self.leg2_last_ask) / 2 self.spread_mid_array.append(spread_mid) self.spread_count += 1 else: return else: return # 确保行情足够 if self.spread_count < self.ema_window + 5: return # 检查委托 if self.active_orderids: if self.try_open: # 试图开仓中,判断是否存在一边全成 if (abs(self.get_pos(self.leg1_symbol)) == self.arb_size) or (abs( self.get_pos(self.leg2_symbol)) == self.arb_size): if abs(self.get_pos(self.leg1_symbol)) != self.arb_size: tick_time = tick.datetime code_time = datetime.now() self.write_log( "code{0} tick{1} in on_tick:{2}尝试追单".format( code_time, tick_time, self.leg1_symbol)) #print("code{0} tick{1} in on_tick:{2}尝试追单".format(code_time, tick_time, self.leg1_symbol)) # leg1没到位 for vt_orderid in list(self.active_orderids): order = self.get_order(vt_orderid) if not order: self.write_log("未找到该订单{}".format(vt_orderid)) if order and order.vt_symbol == self.leg1_symbol: tar_direction = order.direction tar_offset = order.offset tar_price = order.price tar_vol = self.arb_size - abs( self.get_pos(self.leg1_symbol)) if tar_direction == Direction.LONG: tar_price += self.price_add * self.pricetick else: tar_price -= self.price_add * self.pricetick self.cancel_order(order.vt_orderid) # 挂新单 vt_orderids = self.send_order( order.vt_symbol, tar_direction, tar_offset, tar_price, tar_vol) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) tick_time = tick.datetime code_time = datetime.now() self.write_log( "code{} tick{} in on_tick:追单完成".format( code_time, tick_time)) #print("code{} tick{} in on_tick:追单完成".format(code_time,tick_time)) self.try_open = 0 break if abs(self.get_pos(self.leg2_symbol)) != self.arb_size: tick_time = tick.datetime code_time = datetime.now() self.write_log( "code{} tick{} in on_tick:{}尝试追单".format( code_time, tick_time, self.leg2_symbol)) #print("code{} tick{} in on_tick:{}尝试追单".format(code_time,tick_time,self.leg2_symbol)) # leg2没到位 for vt_orderid in list(self.active_orderids): order = self.get_order(vt_orderid) if not order: self.write_log("未找到该订单{}".format(vt_orderid)) if order and order.vt_symbol == self.leg2_symbol: tar_direction = order.direction tar_offset = order.offset tar_price = order.price tar_vol = self.arb_size - abs( self.get_pos(self.leg2_symbol)) if tar_direction == Direction.LONG: tar_price += self.price_add * self.pricetick else: tar_price -= self.price_add * self.pricetick self.cancel_order(order.vt_orderid) # 挂新单 vt_orderids = self.send_order( order.vt_symbol, tar_direction, tar_offset, tar_price, tar_vol) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) tick_time = tick.datetime code_time = datetime.now() self.write_log( "code{} tick{} in on_tick:追单完成".format( code_time, tick_time)) #print("code{} tick{} in on_tick:追单完成".format(code_time,tick_time)) self.try_open = 0 break if self.counter < self.time_out: self.counter += 1 return tick_time = tick.datetime code_time = datetime.now() self.write_log( "code{} tick{} in on_tick:等待时间到,当前仓位:近月{}远月{},本地委托{}".format( code_time, tick_time, self.get_pos(self.leg1_symbol), self.get_pos(self.leg2_symbol), self.active_orderids)) #print("code{} tick{} in on_tick:等待时间到,当前仓位:近月{}远月{},本地委托{}".format(code_time, tick_time,self.get_pos(self.leg1_symbol),self.get_pos(self.leg2_symbol),self.active_orderids)) self.try_open = 0 # 委托全撤 self.cancel_all() return else: self.try_open = 0 self.counter = 0 # 检查单腿风险 if (self.get_pos(self.leg1_symbol) + self.get_pos(self.leg2_symbol)) != 0: tick_time = tick.datetime code_time = datetime.now() self.write_log( "code{} tick{} in on_tick:出现单腿风险,当前仓位:近月{}远月{},本地委托{}".format( code_time, tick_time, self.get_pos(self.leg1_symbol), self.get_pos(self.leg2_symbol), self.active_orderids)) # 记录启动以来总单腿风险次数 self.risk_counter += 1 # 处理单腿 # 市价平仓 if self.get_pos(self.leg1_symbol) > 0: # leg1平多 vt_orderids = self.sell( self.leg1_symbol, self.leg1_last_bid - 10 * self.pricetick, abs(self.get_pos(self.leg1_symbol))) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) if self.get_pos(self.leg1_symbol) < 0: # leg1平空 vt_orderids = self.cover( self.leg1_symbol, self.leg1_last_ask + 10 * self.pricetick, abs(self.get_pos(self.leg1_symbol))) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) if self.get_pos(self.leg2_symbol) > 0: # leg2平多 vt_orderids = self.sell( self.leg2_symbol, self.leg2_last_bid - 10 * self.pricetick, abs(self.get_pos(self.leg2_symbol))) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) if self.get_pos(self.leg2_symbol) < 0: # leg2平空 vt_orderids = self.cover( self.leg2_symbol, self.leg2_last_ask + 10 * self.pricetick, abs(self.get_pos(self.leg2_symbol))) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) return # 区间更新 ema = talib.EMA(np.array(self.spread_mid_array), timeperiod=self.ema_window) self.ema_mid = ema[-2] self.ema_up = ema[-2] + self.ema_th * self.pricetick self.ema_down = ema[-2] - self.ema_th * self.pricetick self.spread_last_mid = self.spread_mid_array[-1] # 计算信号并发单 if self.get_pos(self.leg1_symbol) == 0 and self.get_pos( self.leg2_symbol) == 0: if self.spread_last_mid >= self.ema_up: # 做空价差 tick_time = tick.datetime code_time = datetime.now() self.write_log( f"code{code_time} tick{tick_time} in on_tick:{self.spread_last_mid}>={self.ema_up},价差开空头" ) #print(f"code{code_time} tick{tick_time} in on_tick:{self.spread_last_mid}>={self.ema_up},价差开空头") vt_orderids = self.short(self.leg1_symbol, self.leg1_last_ask, self.arb_size) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) vt_orderids = self.buy(self.leg2_symbol, self.leg2_last_bid, self.arb_size) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) self.try_open = 1 if self.spread_last_mid <= self.ema_down: # 做多价差 tick_time = tick.datetime code_time = datetime.now() self.write_log( f"code{code_time} tick{tick_time} in on_tick:{self.spread_last_mid}<={self.ema_down},价差开多头" ) #print(f"code{code_time} tick{tick_time} in on_tick:{self.spread_last_mid}<={self.ema_down},价差开多头") vt_orderids = self.buy(self.leg1_symbol, self.leg1_last_bid, self.arb_size) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) vt_orderids = self.short(self.leg2_symbol, self.leg2_last_ask, self.arb_size) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) self.try_open = 1 if self.get_pos(self.leg1_symbol) > 0 and self.get_pos( self.leg2_symbol) < 0: if self.spread_last_mid >= self.ema_mid: # 反手做空价差 tick_time = tick.datetime code_time = datetime.now() self.write_log( f"code{code_time} tick{tick_time} in on_tick:{self.spread_last_mid}>={self.ema_mid},价差多头退出" ) #print(f"code{code_time} tick{tick_time} in on_tick:{self.spread_last_mid}>={self.ema_mid},价差多头退出") vt_orderids = self.sell(self.leg1_symbol, self.leg1_last_ask, self.arb_size) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) vt_orderids = self.cover(self.leg2_symbol, self.leg2_last_bid, self.arb_size) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) if self.get_pos(self.leg1_symbol) < 0 and self.get_pos( self.leg2_symbol) > 0: if self.spread_last_mid <= self.ema_mid: # 反手做多价差 tick_time = tick.datetime code_time = datetime.now() self.write_log( f"code{code_time} tick{tick_time} in on_tick:{self.spread_last_mid}<={self.ema_mid},价差空头退出" ) #print(f"code{code_time} tick{tick_time} in on_tick:{self.spread_last_mid}<={self.ema_mid},价差空头退出") vt_orderids = self.cover(self.leg1_symbol, self.leg1_last_bid, self.arb_size) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid) vt_orderids = self.sell(self.leg2_symbol, self.leg2_last_ask, self.arb_size) if vt_orderids: for vt_orderid in vt_orderids: self.active_orderids.add(vt_orderid)
def calc(marketItem): # 生配列をnp DataFrameに変換 df_ohclv = pd.DataFrame( marketItem, columns=['Timestamp', 'Open', 'High', 'Low', 'Close', 'Volume']) # 欠損値の削除 df_ohclv = df_ohclv.dropna() # PlotlyとTA-libでテクニカル分析チャートを描く # https://akatak.hatenadiary.jp/entry/2019/11/23/220836 h = np.array(df_ohclv['High'].fillna(method='ffill')) l = np.array(df_ohclv['Low'].fillna(method='ffill')) c = np.array(df_ohclv['Close'].fillna(method='ffill')) # Simple Moving Average 5 df_ohclv['Sma5'] = ta.SMA(c, timeperiod=5) # Simple Moving Average 10 df_ohclv['Sma10'] = ta.SMA(c, timeperiod=10) # Simple Moving Average 20 df_ohclv['Sma20'] = ta.SMA(c, timeperiod=20) # Simple Moving Average 60 df_ohclv['Sma60'] = ta.SMA(c, timeperiod=60) # Exponential Moving Average 5 df_ohclv['Ema5'] = ta.EMA(c, timeperiod=5) # Exponential Moving Average 20 df_ohclv['Ema20'] = ta.EMA(c, timeperiod=20) # Exponential Moving Average 40 df_ohclv['Ema40'] = ta.EMA(c, timeperiod=40) # 標準偏差 df_ohclv['StdDev'] = ta.STDDEV(c, timeperiod=26) # ADX(Average Directional Movement Index 平均方向性指数) df_ohclv['Adx'] = ta.ADX(h, l, c, timeperiod=14) # Bollinger Bands ary_uband, ary_mband, ary_lband = ta.BBANDS(c, timeperiod=21, nbdevup=0.75, nbdevdn=0.75, matype=0) df_ohclv['BbH'] = ary_uband df_ohclv['BbM'] = ary_mband df_ohclv['BbL'] = ary_lband # ATR(Average True Range) df_ohclv['ATR'] = ta.ATR(h, l, c, timeperiod=14) # SIC (期間中の最大と最小) df_ohclv["SicH"] = pd.Series(c).rolling(window=20).max() df_ohclv["SicL"] = pd.Series(c).rolling(window=20).min() # SAR (Stop and Reverse) df_ohclv["SarH"] = df_ohclv["SicH"] - df_ohclv['ATR'] * 3.3 df_ohclv["SarL"] = df_ohclv["SicL"] + df_ohclv['ATR'] * 3.3 # SAR Trend ary_SarH = np.array(df_ohclv["SarH"]) ary_SarL = np.array(df_ohclv["SarL"]) ary_SarT = [] ary_SarTp = [] ary_SarTm = [] ary_Sar = [] # 標準偏差ボラティリティトレード ary_StdDev = np.array(df_ohclv["StdDev"]) ary_Adx = np.array(df_ohclv['Adx']) ary_SdBlaT = [] ary_SdBlaTp = [] ary_SdBlaTm = [] # 移動平均大循環分析 & 乖離率 ary_SMA5 = np.array(df_ohclv["Sma5"]) ary_SMA20 = np.array(df_ohclv["Sma20"]) ary_SMA60 = np.array(df_ohclv["Sma60"]) ary_MACycle = [] ary_MACycleT = [] ary_MACycleT1 = [] ary_MACycleT2 = [] ary_MACycleT3 = [] ary_MACycleT4 = [] ary_MACycleT5 = [] ary_MACycleT6 = [] ary_MADiff_5_60 = [] # Trend Balance Point # モメンタムファクター 当日終値とTBP_K日前の終値の差分 ary_mf = pd.Series(df_ohclv.Close) - pd.Series(df_ohclv.Close).shift(2) # TBP 上昇トレンド転換値(上昇トレンド、TBP(当日) = 前々日終値 + (前日MF、前々日MFの小さい方)) ary_Tbpp = pd.Series(df_ohclv.Close).shift(2) + np.min( [ary_mf.shift(1), ary_mf.shift(2)], axis=0) # TBP 下降トレンド転換値(下落トレンド、TBP(当日) = 前々日終値 + (前日MF、前々日MFの大きい方)) ary_Tbpm = pd.Series(df_ohclv.Close).shift(2) + np.max( [ary_mf.shift(1), ary_mf.shift(2)], axis=0) # np.max([df_ohclv.High - df_ohclv.Low, # # (pd.Series(df_ohclv.Close).shift(1) - df_ohclv.High).abs(), # # (pd.Series(df_ohclv.Close).shift(1) - df_ohclv.Low).abs()], # # axis=0) # 自分でループしないと計算できないヤツラ for idx in range(df_ohclv.shape[0]): if idx == 0: ary_SarT.append(0) ary_SarTp.append(0) ary_SarTm.append(0) ary_Sar.append(0) ary_SdBlaT.append(0) ary_SdBlaTp.append(0) ary_SdBlaTm.append(0) ary_MACycle.append(0) ary_MACycleT.append(0) ary_MACycleT1.append(0) ary_MACycleT2.append(0) ary_MACycleT3.append(0) ary_MACycleT4.append(0) ary_MACycleT5.append(0) ary_MACycleT6.append(0) ary_MADiff_5_60.append(0) continue # SAR (Stop and Reverse) # SarLをCloseが上抜け(Golden Cross) if ary_SarL[idx - 1] > c[idx - 1] and \ ary_SarL[idx] <= c[idx]: ary_SarT.append(1) ary_SarTp.append(1) ary_SarTm.append(0) ary_Sar.append(ary_SarH[idx]) # SarHをCloseが下抜け(Golden Cross) elif ary_SarH[idx - 1] < c[idx - 1] and \ ary_SarH[idx] >= c[idx]: ary_SarT.append(-1) ary_SarTp.append(0) ary_SarTm.append(1) ary_Sar.append(ary_SarL[idx]) else: # 前日のトレンドを保持 ary_SarT.append(ary_SarT[idx - 1]) ary_SarTp.append(ary_SarTp[idx - 1]) ary_SarTm.append(ary_SarTm[idx - 1]) if ary_SarT[idx] == 1: ary_Sar.append(ary_SarH[idx]) elif ary_SarT[idx] == -1: ary_Sar.append(ary_SarL[idx]) else: ary_Sar.append(0) # 標準偏差ボラティリティトレードモデル if ary_StdDev[idx] > ary_StdDev[idx - 1] and \ ary_Adx[idx] > ary_Adx[idx - 1] and \ c[idx] >= ary_uband[idx]: ary_SdBlaT.append(1) ary_SdBlaTp.append(1) ary_SdBlaTm.append(0) elif ary_StdDev[idx] > ary_StdDev[idx - 1] and \ ary_Adx[idx] > ary_Adx[idx - 1] and \ c[idx] <= ary_lband[idx]: ary_SdBlaT.append(-1) ary_SdBlaTp.append(0) ary_SdBlaTm.append(1) elif ary_SdBlaT[idx - 1] == 1 and \ c[idx] >= ary_uband[idx]: ary_SdBlaT.append(1) ary_SdBlaTp.append(1) ary_SdBlaTm.append(0) elif ary_SdBlaT[idx - 1] == -1 and \ c[idx] <= ary_lband[idx]: ary_SdBlaT.append(-1) ary_SdBlaTp.append(0) ary_SdBlaTm.append(1) else: ary_SdBlaT.append(0) ary_SdBlaTp.append(0) ary_SdBlaTm.append(0) # 移動平均大循環分析 & 乖離率 if ary_SMA5[idx] >= ary_SMA20[idx] >= ary_SMA60[idx]: ary_MACycle.append("ST1") ary_MACycleT.append(1) ary_MACycleT1.append(1) ary_MACycleT2.append(0) ary_MACycleT3.append(0) ary_MACycleT4.append(0) ary_MACycleT5.append(0) ary_MACycleT6.append(0) ary_MADiff_5_60.append(ary_SMA5[idx] / ary_SMA60[idx] * 100) elif ary_SMA20[idx] >= ary_SMA5[idx] >= ary_SMA60[idx]: ary_MACycle.append("ST2") ary_MACycleT.append(0) ary_MACycleT1.append(0) ary_MACycleT2.append(1) ary_MACycleT3.append(0) ary_MACycleT4.append(0) ary_MACycleT5.append(0) ary_MACycleT6.append(0) ary_MADiff_5_60.append(ary_SMA5[idx] / ary_SMA60[idx] * 100) elif ary_SMA20[idx] >= ary_SMA60[idx] >= ary_SMA5[idx]: ary_MACycle.append("ST3") ary_MACycleT.append(0) ary_MACycleT1.append(0) ary_MACycleT2.append(0) ary_MACycleT3.append(1) ary_MACycleT4.append(0) ary_MACycleT5.append(0) ary_MACycleT6.append(0) ary_MADiff_5_60.append(ary_SMA5[idx] / ary_SMA60[idx] * 100) elif ary_SMA60[idx] >= ary_SMA20[idx] >= ary_SMA5[idx]: ary_MACycle.append("ST4") ary_MACycleT.append(-1) ary_MACycleT1.append(0) ary_MACycleT2.append(0) ary_MACycleT3.append(0) ary_MACycleT4.append(1) ary_MACycleT5.append(0) ary_MACycleT6.append(0) ary_MADiff_5_60.append(ary_SMA5[idx] / ary_SMA60[idx] * 100) elif ary_SMA60[idx] >= ary_SMA5[idx] >= ary_SMA20[idx]: ary_MACycle.append("ST5") ary_MACycleT.append(0) ary_MACycleT1.append(0) ary_MACycleT2.append(0) ary_MACycleT3.append(0) ary_MACycleT4.append(0) ary_MACycleT5.append(1) ary_MACycleT6.append(0) ary_MADiff_5_60.append(ary_SMA5[idx] / ary_SMA60[idx] * 100) elif ary_SMA5[idx] >= ary_SMA60[idx] >= ary_SMA20[idx]: ary_MACycle.append("ST6") ary_MACycleT.append(0) ary_MACycleT1.append(0) ary_MACycleT2.append(0) ary_MACycleT3.append(0) ary_MACycleT4.append(0) ary_MACycleT5.append(0) ary_MACycleT6.append(1) ary_MADiff_5_60.append(ary_SMA5[idx] / ary_SMA60[idx] * 100) else: ary_MACycle.append("None") ary_MACycleT.append(0) ary_MACycleT1.append(0) ary_MACycleT2.append(0) ary_MACycleT3.append(0) ary_MACycleT4.append(0) ary_MACycleT5.append(0) ary_MACycleT6.append(0) ary_MADiff_5_60.append(0) df_ohclv["SarT"] = ary_SarT df_ohclv["SarTp"] = ary_SarTp df_ohclv["SarTm"] = ary_SarTm df_ohclv["Sar"] = ary_Sar df_ohclv["SdBlaT"] = ary_SdBlaT df_ohclv["SdBlaTp"] = ary_SdBlaTp df_ohclv["SdBlaTm"] = ary_SdBlaTm df_ohclv["MACycle"] = ary_MACycle df_ohclv["MACycleT"] = ary_MACycleT df_ohclv["MACycleT1"] = ary_MACycleT1 df_ohclv["MACycleT2"] = ary_MACycleT2 df_ohclv["MACycleT3"] = ary_MACycleT3 df_ohclv["MACycleT4"] = ary_MACycleT4 df_ohclv["MACycleT5"] = ary_MACycleT5 df_ohclv["MACycleT6"] = ary_MACycleT6 df_ohclv["MADiff_5_60"] = ary_MADiff_5_60 df_ohclv["TbpMf"] = ary_mf df_ohclv["TbpP"] = ary_Tbpp df_ohclv["TbpM"] = ary_Tbpm # # Simple Moving Average 5 # df_ohclv['Sma5'] = pd.Series(df_ohclv.Close).rolling(window=5).mean() # # Simple Moving Average 20 # df_ohclv['Sma20'] = pd.Series(df_ohclv.Close).rolling(window=20).mean() # # Simple Moving Average 60 # df_ohclv['Sma60'] = pd.Series(df_ohclv.Close).rolling(window=60).mean() # # # Exponential Moving Average 5 # df_ohclv['Ema5'] = pd.Series(df_ohclv.Close).ewm(span=5).mean() # # Exponential Moving Average 20 # df_ohclv['Ema20'] = pd.Series(df_ohclv.Close).ewm(span=20).mean() # # Exponential Moving Average 40 # df_ohclv['Ema40'] = pd.Series(df_ohclv.Close).ewm(span=40).mean() # # # True Range # df_ohclv['Tr'] = np.max([df_ohclv.High - df_ohclv.Low, # (pd.Series(df_ohclv.Close).shift(1) - df_ohclv.High).abs(), # (pd.Series(df_ohclv.Close).shift(1) - df_ohclv.Low).abs()], # axis=0) # # Average True Range # df_ohclv["Atr"] = pd.Series(df_ohclv.Tr).rolling(window=7).mean() # # # SIC (期間中の最大と最小) # df_ohclv["SicH"] = pd.Series(df_ohclv.Close).rolling(window=20).max() # df_ohclv["SicL"] = pd.Series(df_ohclv.Close).rolling(window=20).min() # # # Wilder Volatility System Trend # df_ohclv["WVST"] = "None" # # # # # Stop And Reverse (SAR) return df_ohclv
def ema(dataframe, period, field='close'): import talib.abstract as ta return ta.EMA(dataframe, timeperiod=period, price=field)
def data_construct(DataFrame, lookUp, predictionWindow, pairName): '''function to construct the features from the inspection window and to create the supervised x,y pairs for training. Parameters ---------- DataFrame : dataFrame LookUp : int predictionWindow : int pairName : str Returns ------- output : dict a dict containing inputs matrix, targets matrix, raw inputs and mapping dict for features ''' # fetch data for indicators calculations openPrice = DataFrame.o.values.astype("double") closePrice = DataFrame.c.values.astype("double") highPrice = DataFrame.h.values.astype("double") lowPrice = DataFrame.l.values.astype("double") volume = DataFrame.volume.values.astype("double") # calculate technical indicators values simple_ma_slow = ta.SMA(closePrice, 30) # slow moving average simple_ma_fast = ta.SMA(closePrice, 15) # fast moving average exp_ma_slow = ta.EMA(closePrice, 20) # slow exp moving average exp_ma_fast = ta.EMA(closePrice, 10) # fast exp moving average bbands = ta.BBANDS(closePrice, timeperiod=15) # calculate bollinger bands deltaBands = (bbands[0] - bbands[2] ) / bbands[2] # deltas between bands vector (bollinger) macd_s1, macd_s2, macd_hist = ta.MACD( closePrice) # MACD values calculation sar = ta.SAR(highPrice, lowPrice) # prabolic SAR stochK, stochD = ta.STOCH(highPrice, lowPrice, closePrice) # stochastic calculations rsi = ta.RSI(closePrice, timeperiod=15) # RSI indicator adx = ta.ADX(highPrice, lowPrice, closePrice, timeperiod=15) # ADX indicator mfi = ta.MFI(highPrice, lowPrice, closePrice, volume, timeperiod=15) # money flow index # calculate statistical indicators values beta = ta.BETA(highPrice, lowPrice, timeperiod=5) # beta from CAPM model slope = ta.LINEARREG_ANGLE( closePrice, timeperiod=5) # slope for fitting linera reg. to the last x points # calculate candle indicators values spinTop = ta.CDLSPINNINGTOP(openPrice, highPrice, lowPrice, closePrice) doji = ta.CDLDOJI(openPrice, highPrice, lowPrice, closePrice) dojiStar = ta.CDLDOJISTAR(openPrice, highPrice, lowPrice, closePrice) marubozu = ta.CDLMARUBOZU(openPrice, highPrice, lowPrice, closePrice) hammer = ta.CDLHAMMER(openPrice, highPrice, lowPrice, closePrice) invHammer = ta.CDLINVERTEDHAMMER(openPrice, highPrice, lowPrice, closePrice) hangingMan = ta.CDLHANGINGMAN(openPrice, highPrice, lowPrice, closePrice) shootingStar = ta.CDLSHOOTINGSTAR(openPrice, highPrice, lowPrice, closePrice) engulfing = ta.CDLENGULFING(openPrice, highPrice, lowPrice, closePrice) morningStar = ta.CDLMORNINGSTAR(openPrice, highPrice, lowPrice, closePrice) eveningStar = ta.CDLEVENINGSTAR(openPrice, highPrice, lowPrice, closePrice) whiteSoldier = ta.CDL3WHITESOLDIERS(openPrice, highPrice, lowPrice, closePrice) blackCrow = ta.CDL3BLACKCROWS(openPrice, highPrice, lowPrice, closePrice) insideThree = ta.CDL3INSIDE(openPrice, highPrice, lowPrice, closePrice) # prepare the final matrix ''' matrix configurations ::> [o,c,h,l,ma_slow,ma_fast,exp_slow,exp_fast, deltaBands,macd_s1,macd_s2,sar,stochK, stochD,rsi,adx,mfi,beta,slope,spinTop,doji,dojiStar, marubozu,hammer,invHammer,hangingMan,shootingStar,engulfing, morningStar,eveningStar,whiteSoldier,blackCrow,insideThree] a 33 features matrix in total ''' DataMatrix = np.column_stack( (openPrice, closePrice, highPrice, lowPrice, simple_ma_slow, simple_ma_fast, exp_ma_slow, exp_ma_fast, deltaBands, macd_s1, macd_s2, sar, stochK, stochD, rsi, adx, mfi, beta, slope, spinTop, doji, dojiStar, marubozu, hammer, invHammer, hangingMan, shootingStar, engulfing, morningStar, eveningStar, whiteSoldier, blackCrow, insideThree)) # remove undifined values DataMatrix = DataMatrix[~np.isnan(DataMatrix).any( axis=1)] # remove all raws containing nan values # define number of windows to analyze framesCount = DataMatrix.shape[0] - ( lookUp + predictionWindow) + 1 # 1D convolution outputsize = ceil[((n-f)/s)+1] # define input/output arrays container rawInputs = {} inputsOpen = np.zeros((framesCount, lookUp)) inputsClose = np.zeros((framesCount, lookUp)) inputsHigh = np.zeros((framesCount, lookUp)) inputsLow = np.zeros((framesCount, lookUp)) inputs = np.zeros((framesCount, 62)) outputs = np.zeros((framesCount, 1)) # main loop and data for i in range(framesCount): mainFrame = DataMatrix[i:i + lookUp + predictionWindow, :] window = np.array_split(mainFrame, [lookUp])[0] windowForecast = np.array_split(mainFrame, [lookUp])[1] ''' window configurations ::> [0:o,1:c,2:h,3:l,4:ma_slow,5:ma_fast,6:exp_slow,7:exp_fast, 8:deltaBands,9:macd_slow,10:macd_fast,11:sar,12:stochK, 13:stochD,14:rsi,15:adx,16:mfi,17:beta,18:slope,19:spinTop,20:doji,21:dojiStar, 22:marubozu,23:hammer,24:invHammer,25:hangingMan,26:shootingStar,27:engulfing, 28:morningStar,29:eveningStar,30:whiteSoldier,31:blackCrow,32:insideThree] ''' #sma features detection ma_slow = window[:, 4] ma_fast = window[:, 5] uptrend_cross = ma_fast > ma_slow uptrend_cross = np.concatenate( (np.array([False]), (uptrend_cross[:-1] < uptrend_cross[1:]))) # check the false->true transition try: uptrend_cross_location = np.where(uptrend_cross == True)[0][ -1] # latest uptrend cross_over location except: uptrend_cross_location = -1 downtrend_cross = ma_slow > ma_fast downtrend_cross = np.concatenate( (np.array([False]), (downtrend_cross[:-1] < downtrend_cross[1:]))) # check the false->true transition try: downtrend_cross_location = np.where(downtrend_cross == True)[0][ -1] # latest downtrend cross_over location except: downtrend_cross_location = -1 if (uptrend_cross_location > downtrend_cross_location): # latest cross is an uptrend sma_latest_crossover = 1 # uptrend sign sma_location_of_latest_crossover = uptrend_cross_location alpha_1 = (math.atan(ma_slow[uptrend_cross_location] - ma_slow[uptrend_cross_location - 1])) * ( 180 / math.pi) alpha_2 = (math.atan(ma_fast[uptrend_cross_location] - ma_fast[uptrend_cross_location - 1])) * ( 180 / math.pi) sma_latest_crossover_angle = alpha_1 + alpha_2 elif (downtrend_cross_location > uptrend_cross_location): # latest cross is a downtrend sma_latest_crossover = -1 # downtrend sign sma_location_of_latest_crossover = downtrend_cross_location alpha_1 = (math.atan(ma_slow[downtrend_cross_location] - ma_slow[downtrend_cross_location - 1])) * ( 180 / math.pi) alpha_2 = (math.atan(ma_fast[downtrend_cross_location] - ma_fast[downtrend_cross_location - 1])) * ( 180 / math.pi) sma_latest_crossover_angle = alpha_1 + alpha_2 else: # no cross in the given window sma_latest_crossover = 0 # no sign sma_location_of_latest_crossover = -1 sma_latest_crossover_angle = 0 up_count = np.sum(ma_fast > ma_slow) down_count = np.sum(ma_slow > ma_fast) if (up_count > down_count): sma_dominant_type_fast_slow = 1 elif (down_count > up_count): sma_dominant_type_fast_slow = -1 else: sma_dominant_type_fast_slow = 0 #ema features detection exp_slow = window[:, 6] exp_fast = window[:, 7] uptrend_cross = exp_fast > exp_slow uptrend_cross = np.concatenate( (np.array([False]), (uptrend_cross[:-1] < uptrend_cross[1:]))) # check the false->true transition try: uptrend_cross_location = np.where(uptrend_cross == True)[0][ -1] # latest uptrend cross_over location except: uptrend_cross_location = -1 downtrend_cross = exp_slow > exp_fast downtrend_cross = np.concatenate( (np.array([False]), (downtrend_cross[:-1] < downtrend_cross[1:]))) # check the false->true transition try: downtrend_cross_location = np.where(downtrend_cross == True)[0][ -1] # latest downtrend cross_over location except: downtrend_cross_location = -1 if (uptrend_cross_location > downtrend_cross_location): # latest cross is an uptrend ema_latest_crossover = 1 # uptrend sign ema_location_of_latest_crossover = uptrend_cross_location alpha_1 = (math.atan(exp_slow[uptrend_cross_location] - exp_slow[uptrend_cross_location - 1])) * ( 180 / math.pi) alpha_2 = (math.atan(exp_fast[uptrend_cross_location] - exp_fast[uptrend_cross_location - 1])) * ( 180 / math.pi) ema_latest_crossover_angle = alpha_1 + alpha_2 elif (downtrend_cross_location > uptrend_cross_location): # latest cross is a downtrend ema_latest_crossover = -1 # downtrend sign ema_location_of_latest_crossover = downtrend_cross_location alpha_1 = (math.atan(exp_slow[downtrend_cross_location] - exp_slow[downtrend_cross_location - 1])) * ( 180 / math.pi) alpha_2 = (math.atan(exp_fast[downtrend_cross_location] - exp_fast[downtrend_cross_location - 1])) * ( 180 / math.pi) ema_latest_crossover_angle = alpha_1 + alpha_2 else: # no cross in the given window ema_latest_crossover = 0 # no sign ema_location_of_latest_crossover = -1 ema_latest_crossover_angle = 0 up_count = np.sum(exp_fast > exp_slow) down_count = np.sum(exp_slow > exp_fast) if (up_count > down_count): ema_dominant_type_fast_slow = 1 elif (down_count > up_count): ema_dominant_type_fast_slow = -1 else: ema_dominant_type_fast_slow = 0 # B.Bands features detection deltaBands = window[:, 8] deltaBands_mean = np.mean(deltaBands) deltaBands_std = np.std(deltaBands) deltaBands_maximum_mean = np.amax(deltaBands) / deltaBands_mean deltaBands_maximum_location = np.where( deltaBands == np.amax(deltaBands))[0][-1] # location of maximum deltaBands_minimum_mean = np.amin(deltaBands) / deltaBands_mean deltaBands_minimum_location = np.where( deltaBands == np.amin(deltaBands))[0][-1] # location of maximum # macd features detection macd_slow = window[:, 9] macd_fast = window[:, 10] uptrend_cross = macd_fast > macd_slow uptrend_cross = np.concatenate( (np.array([False]), (uptrend_cross[:-1] < uptrend_cross[1:]))) # check the false->true transition try: uptrend_cross_location = np.where(uptrend_cross == True)[0][ -1] # latest uptrend cross_over location except: uptrend_cross_location = -1 downtrend_cross = macd_slow > macd_fast downtrend_cross = np.concatenate( (np.array([False]), (downtrend_cross[:-1] < downtrend_cross[1:]))) # check the false->true transition try: downtrend_cross_location = np.where(downtrend_cross == True)[0][ -1] # latest downtrend cross_over location except: downtrend_cross_location = -1 if (uptrend_cross_location > downtrend_cross_location): # latest cross is an uptrend macd_latest_crossover = 1 # uptrend sign macd_location_of_latest_crossover = uptrend_cross_location alpha_1 = (math.atan(macd_slow[uptrend_cross_location] - macd_slow[uptrend_cross_location - 1])) * ( 180 / math.pi) alpha_2 = (math.atan(macd_fast[uptrend_cross_location] - macd_fast[uptrend_cross_location - 1])) * ( 180 / math.pi) macd_latest_crossover_angle = alpha_1 + alpha_2 elif (downtrend_cross_location > uptrend_cross_location): # latest cross is a downtrend macd_latest_crossover = -1 # downtrend sign macd_location_of_latest_crossover = downtrend_cross_location alpha_1 = (math.atan(macd_slow[downtrend_cross_location] - macd_slow[downtrend_cross_location - 1])) * ( 180 / math.pi) alpha_2 = (math.atan(macd_fast[downtrend_cross_location] - macd_fast[downtrend_cross_location - 1])) * ( 180 / math.pi) macd_latest_crossover_angle = alpha_1 + alpha_2 else: # no cross in the given window macd_latest_crossover = 0 # no sign macd_location_of_latest_crossover = -1 macd_latest_crossover_angle = 0 up_count = np.sum(macd_fast > macd_slow) down_count = np.sum(macd_slow > macd_fast) if (up_count > down_count): macd_dominant_type_fast_slow = 1 elif (down_count > up_count): macd_dominant_type_fast_slow = -1 else: macd_dominant_type_fast_slow = 0 # sar features detection average_price = (window[:, 0] + window[:, 1] + window[:, 2] + window[:, 3]) / 4 sar = window[:, 11] uptrend = sar < average_price uptrend = np.concatenate( (np.array([False]), (uptrend[:-1] < uptrend[1:]))) # check the false->true transition try: uptrend_location = np.where( uptrend == True)[0][-1] # latest uptrend location except: uptrend_location = -1 downtrend = sar > average_price downtrend = np.concatenate( (np.array([False]), (downtrend[:-1] < downtrend[1:]))) # check the false->true transition try: downtrend_location = np.where( downtrend == True)[0][-1] # latest downtrend location except: downtrend_location = -1 if (uptrend_location > downtrend_location): # latest signal is an uptrend sar_latest_shiftPoint = 1 sar_latest_shiftPoint_location = uptrend_location elif (downtrend_location > uptrend_location): # latest signal is a downtrend sar_latest_shiftPoint = -1 sar_latest_shiftPoint_location = downtrend_location else: # same direction along the frame under question sar_latest_shiftPoint = 0 # no sign sar_latest_shiftPoint_location = -1 sar_total_number_shifts = np.where( downtrend == True)[0].shape[0] + np.where( uptrend == True)[0].shape[0] # stochastic(K) features detection stochK = window[:, 12] stochK_mean = np.mean(stochK) stochK_std = np.std(stochK) uptrend = stochK <= 20 uptrend = np.concatenate( (np.array([False]), (uptrend[:-1] < uptrend[1:]))) # check the false->true transition try: uptrend_location = np.where( uptrend == True)[0][-1] # latest uptrend location except: uptrend_location = -1 downtrend = stochK >= 80 downtrend = np.concatenate( (np.array([False]), (downtrend[:-1] < downtrend[1:]))) # check the false->true transition try: downtrend_location = np.where( downtrend == True)[0][-1] # latest downtrend location except: downtrend_location = -1 if (uptrend_location > downtrend_location): # latest signal is an uptrend stochK_latest_event = 1 stochK_event_location = uptrend_location elif (downtrend_location > uptrend_location): # latest signal is a downtrend stochK_latest_event = -1 stochK_event_location = downtrend_location else: # same direction along the frame under question stochK_latest_event = 0 # no sign stochK_event_location = -1 # stochastic(D) features detection stochD = window[:, 13] stochD_mean = np.mean(stochD) stochD_std = np.std(stochD) uptrend = stochD <= 20 uptrend = np.concatenate( (np.array([False]), (uptrend[:-1] < uptrend[1:]))) # check the false->true transition try: uptrend_location = np.where( uptrend == True)[0][-1] # latest uptrend location except: uptrend_location = -1 downtrend = stochD >= 80 downtrend = np.concatenate( (np.array([False]), (downtrend[:-1] < downtrend[1:]))) # check the false->true transition try: downtrend_location = np.where( downtrend == True)[0][-1] # latest downtrend location except: downtrend_location = -1 if (uptrend_location > downtrend_location): # latest signal is an uptrend stochD_latest_event = 1 stochD_event_location = uptrend_location elif (downtrend_location > uptrend_location): # latest signal is a downtrend stochD_latest_event = -1 stochD_event_location = downtrend_location else: # same direction along the frame under question stochD_latest_event = 0 # no sign stochD_event_location = -1 # rsi features detection rsi = window[:, 14] rsi_mean = np.mean(rsi) rsi_std = np.std(rsi) uptrend = rsi <= 30 uptrend = np.concatenate( (np.array([False]), (uptrend[:-1] < uptrend[1:]))) # check the false->true transition try: uptrend_location = np.where( uptrend == True)[0][-1] # latest uptrend location except: uptrend_location = -1 downtrend = rsi >= 70 downtrend = np.concatenate( (np.array([False]), (downtrend[:-1] < downtrend[1:]))) # check the false->true transition try: downtrend_location = np.where( downtrend == True)[0][-1] # latest downtrend location except: downtrend_location = -1 if (uptrend_location > downtrend_location): # latest signal is an uptrend rsi_latest_event = 1 rsi_event_location = uptrend_location elif (downtrend_location > uptrend_location): # latest signal is a downtrend rsi_latest_event = -1 rsi_event_location = downtrend_location else: # same direction along the frame under question rsi_latest_event = 0 # no sign rsi_event_location = -1 # adx features detection adx = window[:, 15] adx_mean = np.mean(adx) adx_std = np.std(adx) splitted_array = np.array_split(adx, 2) m0 = np.mean(splitted_array[0]) m1 = np.mean(splitted_array[1]) adx_mean_delta_bet_first_second_half = (m1 - m0) / m0 # mfi features detection mfi = window[:, 16] mfi_mean = np.mean(mfi) mfi_std = np.std(mfi) splitted_array = np.array_split(mfi, 2) m0 = np.mean(splitted_array[0]) m1 = np.mean(splitted_array[1]) mfi_mean_delta_bet_first_second_half = (m1 - m0) / m0 # resistance levels features detection closePrice = window[:, 1] resLevels = argrelextrema(closePrice, np.greater, order=4)[0] if (resLevels.shape[0] == 0): relation_r1_close = 0 relation_r2_close = 0 relation_r3_close = 0 elif (resLevels.shape[0] == 1): relation_r1_close = (closePrice[-1] - closePrice[resLevels[-1]]) / closePrice[-1] relation_r2_close = 0 relation_r3_close = 0 elif (resLevels.shape[0] == 2): relation_r1_close = (closePrice[-1] - closePrice[resLevels[-1]]) / closePrice[-1] relation_r2_close = (closePrice[-1] - closePrice[resLevels[-2]]) / closePrice[-1] relation_r3_close = 0 else: relation_r1_close = (closePrice[-1] - closePrice[resLevels[-1]]) / closePrice[-1] relation_r2_close = (closePrice[-1] - closePrice[resLevels[-2]]) / closePrice[-1] relation_r3_close = (closePrice[-1] - closePrice[resLevels[-3]]) / closePrice[-1] # support levels features detection closePrice = window[:, 1] supLevels = argrelextrema(closePrice, np.less, order=4)[0] if (supLevels.shape[0] == 0): relation_s1_close = 0 relation_s2_close = 0 relation_s3_close = 0 elif (supLevels.shape[0] == 1): relation_s1_close = (closePrice[-1] - closePrice[supLevels[-1]]) / closePrice[-1] relation_s2_close = 0 relation_s3_close = 0 elif (supLevels.shape[0] == 2): relation_s1_close = (closePrice[-1] - closePrice[supLevels[-1]]) / closePrice[-1] relation_s2_close = (closePrice[-1] - closePrice[supLevels[-2]]) / closePrice[-1] relation_s3_close = 0 else: relation_s1_close = (closePrice[-1] - closePrice[supLevels[-1]]) / closePrice[-1] relation_s2_close = (closePrice[-1] - closePrice[supLevels[-2]]) / closePrice[-1] relation_s3_close = (closePrice[-1] - closePrice[supLevels[-3]]) / closePrice[-1] # slope features detection slope = window[:, 18] slope_mean = np.mean(slope) # beta features detection beta = window[:, 17] beta_mean = np.mean(beta) beta_std = np.std(beta) # spinTop features detection np.sum(np.where(a==1)[0]) count100plus = np.sum(np.where(window[:, 19] == 100)[0]) count100minus = (np.sum(np.where(window[:, 19] == -100)[0])) * -1 spinTop_number_occurrence = count100plus + count100minus # doji features detection count100plus = np.sum(np.where(window[:, 20] == 100)[0]) count100minus = (np.sum(np.where(window[:, 20] == -100)[0])) * -1 doji_number_occurrence = count100plus + count100minus # dojiStar features detection count100plus = np.sum(np.where(window[:, 21] == 100)[0]) count100minus = (np.sum(np.where(window[:, 21] == -100)[0])) * -1 dojiStar_number_occurrence = count100plus + count100minus # marubozu features detection count100plus = np.sum(np.where(window[:, 22] == 100)[0]) count100minus = (np.sum(np.where(window[:, 22] == -100)[0])) * -1 marubozu_number_occurrence = count100plus + count100minus # hammer features detection count100plus = np.sum(np.where(window[:, 23] == 100)[0]) count100minus = (np.sum(np.where(window[:, 23] == -100)[0])) * -1 hammer_number_occurrence = count100plus + count100minus # invHammer features detection count100plus = np.sum(np.where(window[:, 24] == 100)[0]) count100minus = (np.sum(np.where(window[:, 24] == -100)[0])) * -1 invHammer_number_occurrence = count100plus + count100minus # hangingMan features detection count100plus = np.sum(np.where(window[:, 25] == 100)[0]) count100minus = (np.sum(np.where(window[:, 25] == -100)[0])) * -1 hangingMan_number_occurrence = count100plus + count100minus # shootingStar features detection count100plus = np.sum(np.where(window[:, 26] == 100)[0]) count100minus = (np.sum(np.where(window[:, 26] == -100)[0])) * -1 shootingStar_number_occurrence = count100plus + count100minus # engulfing features detection count100plus = np.sum(np.where(window[:, 27] == 100)[0]) count100minus = (np.sum(np.where(window[:, 27] == -100)[0])) * -1 engulfing_number_occurrence = count100plus + count100minus # morningStar features detection count100plus = np.sum(np.where(window[:, 28] == 100)[0]) count100minus = (np.sum(np.where(window[:, 28] == -100)[0])) * -1 morningStar_number_occurrence = count100plus + count100minus # eveningStar features detection count100plus = np.sum(np.where(window[:, 29] == 100)[0]) count100minus = (np.sum(np.where(window[:, 29] == -100)[0])) * -1 eveningStar_number_occurrence = count100plus + count100minus # whiteSoldier features detection count100plus = np.sum(np.where(window[:, 30] == 100)[0]) count100minus = (np.sum(np.where(window[:, 30] == -100)[0])) * -1 whiteSoldier_number_occurrence = count100plus + count100minus # blackCrow features detection count100plus = np.sum(np.where(window[:, 31] == 100)[0]) count100minus = (np.sum(np.where(window[:, 31] == -100)[0])) * -1 blackCrow_number_occurrence = count100plus + count100minus # insideThree features detection count100plus = np.sum(np.where(window[:, 32] == 100)[0]) count100minus = (np.sum(np.where(window[:, 32] == -100)[0])) * -1 insideThree_number_occurrence = count100plus + count100minus # fill the inputs matrix inputs[i, 0] = sma_latest_crossover inputs[i, 1] = sma_location_of_latest_crossover inputs[i, 2] = sma_latest_crossover_angle inputs[i, 3] = sma_dominant_type_fast_slow inputs[i, 4] = ema_latest_crossover inputs[i, 5] = ema_location_of_latest_crossover inputs[i, 6] = ema_latest_crossover_angle inputs[i, 7] = ema_dominant_type_fast_slow inputs[i, 8] = deltaBands_mean inputs[i, 9] = deltaBands_std inputs[i, 10] = deltaBands_maximum_mean inputs[i, 11] = deltaBands_maximum_location inputs[i, 12] = deltaBands_minimum_mean inputs[i, 13] = deltaBands_minimum_location inputs[i, 14] = macd_latest_crossover inputs[i, 15] = macd_location_of_latest_crossover inputs[i, 16] = macd_latest_crossover_angle inputs[i, 17] = macd_dominant_type_fast_slow inputs[i, 18] = sar_latest_shiftPoint inputs[i, 19] = sar_latest_shiftPoint_location inputs[i, 20] = sar_total_number_shifts inputs[i, 21] = stochK_mean inputs[i, 22] = stochK_std inputs[i, 23] = stochK_latest_event inputs[i, 24] = stochK_event_location inputs[i, 25] = stochD_mean inputs[i, 26] = stochD_std inputs[i, 27] = stochD_latest_event inputs[i, 28] = stochD_event_location inputs[i, 29] = rsi_mean inputs[i, 30] = rsi_std inputs[i, 31] = rsi_latest_event inputs[i, 32] = rsi_event_location inputs[i, 33] = adx_mean inputs[i, 34] = adx_std inputs[i, 35] = adx_mean_delta_bet_first_second_half inputs[i, 36] = mfi_mean inputs[i, 37] = mfi_std inputs[i, 38] = mfi_mean_delta_bet_first_second_half inputs[i, 39] = relation_r1_close inputs[i, 40] = relation_r2_close inputs[i, 41] = relation_r3_close inputs[i, 42] = relation_s1_close inputs[i, 43] = relation_s2_close inputs[i, 44] = relation_s3_close inputs[i, 45] = slope_mean inputs[i, 46] = beta_mean inputs[i, 47] = beta_std inputs[i, 48] = spinTop_number_occurrence inputs[i, 49] = doji_number_occurrence inputs[i, 50] = dojiStar_number_occurrence inputs[i, 51] = marubozu_number_occurrence inputs[i, 52] = hammer_number_occurrence inputs[i, 53] = invHammer_number_occurrence inputs[i, 54] = hangingMan_number_occurrence inputs[i, 55] = shootingStar_number_occurrence inputs[i, 56] = engulfing_number_occurrence inputs[i, 57] = morningStar_number_occurrence inputs[i, 58] = eveningStar_number_occurrence inputs[i, 59] = whiteSoldier_number_occurrence inputs[i, 60] = blackCrow_number_occurrence inputs[i, 61] = insideThree_number_occurrence # fill raw inputs matrices inputsOpen[i, :] = window[:, 0].reshape(1, lookUp) inputsClose[i, :] = window[:, 1].reshape(1, lookUp) inputsHigh[i, :] = window[:, 2].reshape(1, lookUp) inputsLow[i, :] = window[:, 3].reshape(1, lookUp) # fill the output matrix futureClose = windowForecast[:, 1] if (pairName == "USD_JPY"): outputs[ i, 0] = (futureClose[-1] - futureClose[0] ) / 0.01 # one pip = 0.01 for any pair containing JPY else: outputs[i, 0] = (futureClose[-1] - futureClose[0] ) / 0.0001 # one pip = 0.0001 for this pairs # create mapping dict. mappingDict = { "sma_latest_crossover": 0, "sma_location_of_latest_crossover": 1, "sma_latest_crossover_angle": 2, "sma_dominant_type_fast_slow": 3, "ema_latest_crossover": 4, "ema_location_of_latest_crossover": 5, "ema_latest_crossover_angle": 6, "ema_dominant_type_fast_slow": 7, "deltaBands_mean": 8, "deltaBands_std": 9, "deltaBands_maximum_mean": 10, "deltaBands_maximum_location": 11, "deltaBands_minimum_mean": 12, "deltaBands_minimum_location": 13, "macd_latest_crossover": 14, "macd_location_of_latest_crossover": 15, "macd_latest_crossover_angle": 16, "macd_dominant_type_fast_slow": 17, "sar_latest_shiftPoint": 18, "sar_latest_shiftPoint_location": 19, "sar_total_number_shifts": 20, "stochK_mean": 21, "stochK_std": 22, "stochK_latest_event": 23, "stochK_event_location": 24, "stochD_mean": 25, "stochD_std": 26, "stochD_latest_event": 27, "stochD_event_location": 28, "rsi_mean": 29, "rsi_std": 30, "rsi_latest_event": 31, "rsi_event_location": 32, "adx_mean": 33, "adx_std": 34, "adx_mean_delta_bet_first_second_half": 35, "mfi_mean": 36, "mfi_std": 37, "mfi_mean_delta_bet_first_second_half": 38, "relation_r1_close": 39, "relation_r2_close": 40, "relation_r3_close": 41, "relation_s1_close": 42, "relation_s2_close": 43, "relation_s3_close": 44, "slope_mean": 45, "beta_mean": 46, "beta_std": 47, "spinTop_number_occurrence": 48, "doji_number_occurrence": 49, "dojiStar_number_occurrence": 50, "marubozu_number_occurrence": 51, "hammer_number_occurrence": 52, "invHammer_number_occurrence": 53, "hangingMan_number_occurrence": 54, "shootingStar_number_occurrence": 55, "engulfing_number_occurrence": 56, "morningStar_number_occurrence": 57, "eveningStar_number_occurrence": 58, "whiteSoldier_number_occurrence": 59, "blackCrow_number_occurrence": 60, "insideThree_number_occurrence": 61 } # remove undifined values from the output refMatrix = inputs inputs = inputs[~np.isnan(refMatrix).any( axis=1)] # remove all raws containing nan values outputs = outputs[~np.isnan(refMatrix).any( axis=1)] # remove all raws containing nan values inputsOpen = inputsOpen[~np.isnan(refMatrix).any( axis=1)] # remove all raws containing nan values inputsClose = inputsClose[~np.isnan(refMatrix).any( axis=1)] # remove all raws containing nan values inputsHigh = inputsHigh[~np.isnan(refMatrix).any( axis=1)] # remove all raws containing nan values inputsLow = inputsLow[~np.isnan(refMatrix).any( axis=1)] # remove all raws containing nan values # create raw inputs dict. rawInputs["open"] = inputsOpen rawInputs["close"] = inputsClose rawInputs["high"] = inputsHigh rawInputs["low"] = inputsLow # return the function output output = { "mappingDict": mappingDict, "rawInputs": rawInputs, "inputFeatures": inputs, "targets": outputs } return (output)
def start(): get_k_data = ts.get_k_data("sh000001", start='1990-12-19') data = pd.DataFrame(get_k_data) data_size = data.iloc[:, 0].size up_list = [] down_list = [] up_down_list = [] v_list = [] per_volume_list = [] rvi_list = [] up_date_list = [] down_date_list = [] date_list = [] close_list = [] volume_list = [] qhlsr_list = [] obv_list = [] obv_rate_list = [] zzz_v_list = [] obv = 0 #昨收 y_close = 0 pre_down = 0 pre_up = 0 times = 100000000 up_volume = 1 down_volume = 1 up_times = 0 y_open = 0 y_close = 0 y_high = 0 y_low = 0 y_volume = 0 for index, row in data.iterrows(): open = row.open close = row.close high = row.high low = row.low volume = row.volume date = row.date date_list.append(date) close_list.append(close) volume_list.append(volume) if close > y_close: up_times = up_times + 1 up_volume = up_volume + volume else: down_volume = down_volume + volume obv_rate_list.append(up_volume / down_volume) ###阻力指标 if y_volume == 0: qhlsr = 0 else: qhlsr = (close - y_close ) - (volume - y_volume) * (y_high - y_low) / y_volume qhlsr_list.append(qhlsr) zzz_v_list.append((close - y_close)) v_list.append(close - y_close) up_list.append(times * (close - y_close) / volume) print(times * (close - y_close) / volume) down_list.append(times * (high - close) / volume) up_down_list.append(up_list[index] - down_list[index]) # rvi_list.append((close-open)/(high-low)); if (high - low) == 0: # per_volume_list.append(0); rvi_list.append(0) else: # per_volume_list.append((volume/(close - y_close))); rvi_list.append((close - open) / (high - low)) y_open = open y_close = close y_high = high y_low = low y_volume = volume fig, axes = plt.subplots(3, 1, sharex=True, sharey=False) # axes.plot(up_list[0:2300], 'r-') # plt.subplots_adjust(wspace = 0, hspace = 0) # plt.figure(figsize=(8,4)) lll = 1000 timeperiod = 20 obv_list = get_obv(data, data_size - lll, data_size) close_ma = ta.MA( np.array(close_list[len(close_list) - lll:len(close_list)]), 1) # rvi_ma = ta.EMA(np.array(rvi_list[len(rvi_list) - lll:len(rvi_list)]), timeperiod) # up_down_ma = ta.EMA(np.array(up_down_list[len(up_down_list) - lll:len(up_down_list)]), timeperiod) rvi_ma = ta.CMO( np.array(close_list[len(close_list) - lll:len(close_list)]), timeperiod) # up_down_ma = ta.ROC(np.array(close_list[len(close_list) - lll:len(close_list)]), timeperiod) s = 50 f = 9 up_down_ema_s = ta.EMA(np.array(up_list[len(up_list) - lll:len(up_list)]), s) up_down_ema_f = ta.EMA(np.array(up_list[len(up_list) - lll:len(up_list)]), f) real = ta.LINEARREG_SLOPE(np.array(close_list[len(close_list) - lll:len(close_list)]), timeperiod=10) real = ta.EMA(np.array(real), s) up_down_ma_s = ta.MA(np.array(up_list[len(up_list) - lll:len(up_list)]), s) up_down_ma_f = ta.MA(np.array(up_list[len(up_list) - lll:len(up_list)]), f) v_ema_s = ta.EMA(np.array(v_list[len(v_list) - lll:len(v_list)]), s) v_ema_f = ta.EMA(np.array(v_list[len(v_list) - lll:len(v_list)]), f) axes[0].plot(date_list[len(date_list) - lll:len(date_list)], close_ma, "y--", linewidth=1) # axes[0].plot(date_list[len(date_list) - lll:len(date_list)],v_ema_s,"r--",linewidth=1); # axes[1].plot(date_list[len(date_list) - lll:len(date_list)],rvi_ma,"b--",linewidth=1); axes[1].plot(date_list[len(date_list) - lll:len(date_list)], real, "b--", linewidth=1) # axes[1].plot(date_list[len(date_list) - lll:len(date_list)],v_ema_f,"r--",linewidth=1); axes[2].plot(date_list[len(date_list) - lll:len(date_list)], up_down_ema_s, "b--", linewidth=1) axes[2].plot(date_list[len(date_list) - lll:len(date_list)], up_down_ema_f, "r--", linewidth=1) # axes[2].plot(date_list[len(date_list) - lll:len(date_list)],,"b--",linewidth=1); where_are_nan = np.isnan(up_down_ema_s) where_are_inf = np.isinf(up_down_ema_s) up_down_ema_s[where_are_nan] = 0 up_down_ema_s[where_are_inf] = 0 # print("up_list", np.mean(up_down_ema_s)); # print("v_list", np.mean(v_list)); plt.show()
def calculate_features(data: pd.DataFrame, normalization=False, train_data: list = None, start=None, end=None): Open = data['Open'].values High = data['High'].values Low = data['Low'].values Close = data['Close'].values Volume = data['Volume'].values data['ret'] = data['Close'].pct_change() * 100.0 data['ret_2'] = data['Close'].pct_change().shift() * 100.0 data['ret_3'] = data['Close'].pct_change().shift(2) * 100.0 data['ret_4'] = data['Close'].pct_change().shift(3) * 100.0 data['ret_5'] = data['Close'].pct_change().shift(4) * 100.0 data['ret_ratio'] = (data['ret'] / data['ret_5'] - 1) * 100.0 data['log_ret'] = (np.log(data['Close'])).diff() * 100.0 data['gap'] = ((data['Open'] - data['Close'].shift()) / data['Open'] * 100.0) data['gap2'] = ((data['Open'] - data['Close'].shift()) / data['Open'] * 100.0).shift() data['gap3'] = ((data['Open'] - data['Close'].shift()) / data['Open'] * 100.0).shift(2) data['gap4'] = ((data['Open'] - data['Close'].shift()) / data['Open'] * 100.0).shift(3) data['gap5'] = ((data['Open'] - data['Close'].shift()) / data['Open'] * 100.0).shift(4) data['hl'] = ((data['High'] - data['Low']) / data['Open'] * 100.0) data['hl2'] = ((data['High'] - data['Low']) / data['Open'] * 100.0).shift() data['hl3'] = ((data['High'] - data['Low']) / data['Open'] * 100.0).shift(2) data['hl4'] = ((data['High'] - data['Low']) / data['Open'] * 100.0).shift(3) data['hl5'] = ((data['High'] - data['Low']) / data['Open'] * 100.0).shift(4) data['oc'] = ((data['Close'] - data['Open']) / data['Open'] * 100.0) data['oc2'] = ((data['Close'] - data['Open']) / data['Open'] * 100.0).shift() data['oc3'] = ((data['Close'] - data['Open']) / data['Open'] * 100.0).shift(2) data['oc4'] = ((data['Close'] - data['Open']) / data['Open'] * 100.0).shift(3) data['oc5'] = ((data['Close'] - data['Open']) / data['Open'] * 100.0).shift(4) data['MA_short'] = talib.EMA(data['Close'].values, 10) data['MA_long'] = talib.EMA(data['Close'].values, 120) data['MA_ratio'] = (data['MA_short'] / data['MA_long'] - 1) * 100.0 data['MA2_short'] = talib.EMA(data['Close'].values, 10) data['MA2_long'] = talib.EMA(data['Close'].values, 60) data['MA2_ratio'] = (data['MA2_short'] / data['MA2_long'] - 1) * 100.0 data['vol_long'] = pd.rolling_std(data['Close'], 30) data['vol_short'] = pd.rolling_std(data['Close'], 15) data['vol_ratio'] = (data['vol_short'] / data['vol_long'] - 1) * 100.0 data['EMA'] = (Close / talib.EMA(Close, 5) - 1) * 100.0 data['EMA_long'] = (Close / talib.EMA(Close, 60) - 1) * 100.0 data['RSI'] = talib.RSI(data['Close'].values) / 100.0 data['MOM'] = talib.MOM(data['Close'].values, timeperiod=14) / 100.0 data['MACD_vfast'], data['MACD_signal_vfast'], data['MACD_hist'] = \ talib.MACD(data['Close'].values, fastperiod=4, slowperiod=9, signalperiod=3) data['MACD_fast'], data['MACD_signal_fast'], _ = \ talib.MACD(data['Close'].values, fastperiod=12, slowperiod=26, signalperiod=9) data['MACD_slow'], _, _ = talib.MACD(data['Close'].values, fastperiod=25, slowperiod=50) data['MACD'], data['MACD_signal'], data['MACD_hist'] = talib.MACD( data['Close'].values, fastperiod=30, slowperiod=65, signalperiod=22) data['ATR'] = talib.ATR(High, Low, Close, timeperiod=28) data['ADX_vlong'] = talib.ADX(High, Low, Close, timeperiod=120) data['ADX_long'] = talib.ADX(High, Low, Close, timeperiod=28) data['ADX_short'] = talib.ADX(High, Low, Close, timeperiod=14) data['TSF_short'] = talib.TSF(data['Close'].values, timeperiod=14) data['TSF_long'] = talib.TSF(data['Close'].values, timeperiod=28) data['TSF_ratio'] = (data['TSF_short'] / data['TSF_long'] - 1) * 100.0 data['BBand_up'], data['BBand_mid'], data['BBand_low'] = talib.BBANDS( data['Close'].values, timeperiod=20) data['BBand_width'] = (data['BBand_up'] / data['BBand_low'] - 1) * 100.0 data['HMA_short'] = HMA(data['Close'].values, timeperiod=9) data['HMA_long'] = HMA(data['Close'].values, timeperiod=60) data['HMA_ratio'] = (data['HMA_short'] / data['HMA_long'] - 1) * 100.0 data['HMA_ret'] = HMA(data['Close'].values, 100) # data['HMA_ret'] = data['HMA_ret'].pct_change() data['OBV'] = talib.OBV(Close, Volume) data['mean'] = pd.rolling_mean(data['ret'], 10) data['std'] = pd.rolling_std(data['ret'], 10) data['skewness'] = pd.rolling_skew(data['ret'], 10) data['kurtosis'] = (pd.rolling_kurt(data['ret'], 10) - 3) data['STOCHk'], data['STOCHd'] = talib.STOCH(High, Low, Close, fastk_period=28, slowk_period=3, slowd_period=3) data['STOCHRSId'], data['STOCHRSIk'] = talib.STOCHRSI(Close) data['Chaikin_vol'] = Chaikin_vol(High, Low) data['Chaikin_oscillator'] = Chaikin_oscillator(High, Low, Close, Volume) data['PDI'] = talib.PLUS_DI(High, Low, Close, timeperiod=14) data['MDI'] = talib.MINUS_DI(High, Low, Close, timeperiod=14) data['DI'] = data['ADX_short'] - data['PDI'] + data['MDI'] # train_data = ['ret', 'ret_2', 'ret_3', 'ret_4', 'ret_5', 'vol_ratio', 'hl', 'oc', 'gap'] # 'ret_2', 'ret_3', 'ret_4', 'ret_5'] # data = include_VIX(data) data.replace(np.nan, 0, inplace=True) if normalization is True: for feature in data.columns: if feature not in [ 'Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume', 'Product', 'log_ret', 'ret', 'ret_2', 'ret_3', 'ret_4', 'ret_5', 'Date' ]: data[feature] = (normalize(data[feature], start=start, end=end)) if train_data is None: # train_data = ['MACD_vfast', 'vol_ratio', 'oc', 'hl', 'ret', 'ADX_short', 'MA_ratio', 'MA2_ratio', # 'RSI', 'skewness', 'kurtosis', 'mean', 'std'] train_data = ['oc', 'vol_ratio', 'hl', 'ret'] # train_data = ['MACD_vfast', 'vol_ratio', 'oc', 'hl', 'gap', 'ret', 'ADX_short', 'BBand_width', 'MA_ratio', # 'RSI', 'skewness', 'kurtosis', 'mean', 'std'] # most original # train_data = ['MACD_vfast', 'vol_ratio', 'oc', 'hl', 'gap', 'ret', # 'ADX_short', 'BBand_width', 'MA_ratio', 'RSI', 'skewness', 'kurtosis', 'mean', 'std'] data = feature_analysis(data, feature=train_data, pca_components=len(train_data), start=start, end=end) return data
def handle_data(context, data): valid_contracts = [contract for contract in context.contracts if contract.start_date <= get_datetime() - pd.Timedelta(days=SLOW_MA+2) and contract.end_date >= get_datetime()] hist = data.history(valid_contracts, fields=['price', 'high', 'low'], bar_count=SLOW_MA + 1, frequency='1d') slow_ma = hist['price'].apply(lambda x: talib.EMA(x.as_matrix(), timeperiod=SLOW_MA)[-1]) fast_ma = hist['price'].apply(lambda x: talib.EMA(x.as_matrix(), timeperiod=FAST_MA)[-1]) atr = hist.apply(lambda x: talib.ATR(x['high'].fillna(x['price']).as_matrix(), x['low'].fillna( x['price']).as_matrix(), x['price'].as_matrix(), timeperiod=SLOW_MA)[-1], axis=(1, 0)) # breakout above is a buy signal upper = hist['price'][-BREAKOUT-1:-2].max(axis=0) # breakout below is a sell signal lower = hist['price'][-BREAKOUT-1:-2].min(axis=0) # last price price = hist['price'].fillna(method='ffill').iloc[-1] # position sizes as % of portfolio value weights = RISK/100 * price/atr longs = ((price > upper) & (fast_ma > slow_ma)) * weights shorts = ((price < lower) & (fast_ma < slow_ma)) * -weights signals = longs + shorts # convert Continuous_future objects in indexes to current Future objects signals.index = data.current(signals.index, 'contract') atr.index = data.current(atr.index, 'contract') price.index = data.current(price.index, 'contract') signals = signals[signals != 0].dropna() # rollover expiring contracts for cont, pos in context.portfolio.positions.items(): if cont not in price.index: weight = context.portfolio.current_portfolio_weights[cont] root = cont.root_symbol # close existing contract signals[cont] = 0 current = data.current(continuous_future(root), 'contract') position = context.portfolio.positions[cont] # open current contract only if unrealised PnL positive if (position.last_sale_price - position.cost_basis) * position.amount > 0: if current: # contract could've been delisted signals[current] = weight # still need the old contract for stop-loss calculation atr[cont] = atr[current] price[cont] = price[current] # implement stop-loss for contract, position in context.portfolio.positions.items(): if contract in context.min_max: context.min_max[contract] = (min(context.min_max[contract][0], position.cost_basis, position.last_sale_price), max(context.min_max[contract][1], position.cost_basis, position.last_sale_price)) else: context.min_max[contract] = (min(position.cost_basis, position.last_sale_price), max(position.cost_basis, position.last_sale_price)) # calculate stop loss level if position.amount > 0: stop_price = context.min_max[contract][1] - \ atr[contract].item() * STOP if price[contract] <= stop_price: signals[contract] = 0 del context.min_max[contract] if position.amount < 0: stop_price = context.min_max[contract][0] + \ atr[contract].item() * STOP if price[contract] >= stop_price: signals[contract] = 0 del context.min_max[contract] # execute trades existing_positions = list(context.portfolio.positions.keys()) for asset, target in signals.items(): # pdb.set_trace() log.info('transactions on {}:'.format(get_datetime())) if asset in existing_positions: # don't trade in existing positions unless it's stop loss if target != 0: continue log.info('{}: {}'.format(asset, target)) order_target_percent(asset, target)
def on_message(client, userdata, msg): logger.debug(msg.topic + " " + str(msg.payload)) global reading_watt_frigo, reading_watt_piastra, reading_watt_microwav, reading_watt_boiler global time_watt_frigo, time_watt_piastra, time_watt_microwav, time_watt_boiler global total_watt, total_watt_last, total_watt_var, power_watt_series, total_watt_last_ema now = datetime.now() value = json.loads(msg.payload) watt = value["ENERGY"]["Power"] t = datetime.strptime(value["Time"], TIME_FORMAT) + timedelta( hours=TIMEZONE_IOT_OFFSET_HOURS) if msg.topic == TOPIC_GR_FRIGO: reading_watt_frigo = watt time_watt_frigo = t logger.debug("frigo W {:d} {}".format(reading_watt_frigo, time_watt_frigo)) elif msg.topic == TOPIC_GR_PIASTRA: reading_watt_piastra = watt time_watt_piastra = t logger.debug("piastr W {:d} {}".format(reading_watt_piastra, time_watt_piastra)) elif msg.topic == TOPIC_GR_MICROWAV: reading_watt_microwav = watt time_watt_microwav = t logger.debug("microw W {:d} {}".format(reading_watt_microwav, time_watt_microwav)) elif msg.topic == TOPIC_GR_BOILER: reading_watt_boiler = watt time_watt_boiler = t logger.debug("boiler W {:d} {}".format(reading_watt_boiler, time_watt_boiler)) # scadenza valori if (datetime.now() - time_watt_frigo).total_seconds() > EXPIRE_SEC: time_watt_frigo = datetime.now() reading_watt_frigo = 0 if (datetime.now() - time_watt_piastra).total_seconds() > EXPIRE_SEC: time_watt_piastra = datetime.now() reading_watt_piastra = 0 if (datetime.now() - time_watt_microwav).total_seconds() > EXPIRE_SEC: time_watt_microwav = datetime.now() reading_watt_microwav = 0 if (datetime.now() - time_watt_boiler).total_seconds() > EXPIRE_SEC: time_watt_boiler = datetime.now() reading_watt_boiler = 0 # calcolo total_watt = reading_watt_frigo + reading_watt_piastra + reading_watt_microwav + reading_watt_boiler total_watt_var = round( -(total_watt_last - total_watt) / TOTAL_WATT_MAX * 100.0, 1) total_watt_perc = round(total_watt / TOTAL_WATT_MAX * 100.0, 1) power_watt_series = np.delete(power_watt_series, 0) power_watt_series = np.append(power_watt_series, total_watt) # EMA = exponential moving average # FIR filter total_watt_ema = round(talib.EMA(power_watt_series, timeperiod=4)[10 - 1]) total_watt_var_ema = round( -(total_watt_last_ema - total_watt_ema) / TOTAL_WATT_MAX * 100.0, 1) # if total_watt_var > 200: logger.info( "total W {:d} var % {} load % {} EMA4 W {} var EMA4 % {}".format( total_watt, total_watt_var, total_watt_perc, total_watt_ema, total_watt_var_ema)) # update total_watt_last = total_watt total_watt_last_ema = total_watt_ema msg = None if total_watt_var_ema > MESSAGE_EMA_LEVEL: msg = "la potenza sta salendo al {} percento".format( round(total_watt_perc)) if total_watt_var_ema < -MESSAGE_EMA_LEVEL: msg = "la potenza sta scendendo al {} percento".format( round(total_watt_perc)) if msg is not None: # tts @ home assistant payload = { "time": now.strftime(TIME_FORMAT), "speech": { "entity_id": HA_CHROMECAST_ID, "language": 'it', "message": msg } } client.publish(HA_SERVICE, json.dumps(payload))
timeperiod = 120 # 하이퍼파라미터 몇가지를 잘 모르겠다. # Turnover # Stock Turnover = Cost of Goods Sold / Average Inventory, # 거래량 / 총 발행 주식수 # Bias ??? # Bollingerbands df_amd_bb_upper, df_amd_bb_middle, df_amd_bb_lower = ta.BBANDS(df_amd['Close'], timeperiod=timeperiod) # Directionalmovementindex df_amd_dx = ta.DX(df_amd['Close'],df_amd['Open'],df_amd['High'], timeperiod=timeperiod) # Exponentialmovingaverages df_amd_ema = ta.EMA(df_amd['Close'], timeperiod=timeperiod) # Stochasticindex df_amd_slowk, df_amd_slowd = ta.STOCH(df_amd['High'], df_amd['Low'], df_amd['Close'], fastk_period=5, slowk_period=3, slowk_matype=0, slowd_period=3, slowd_matype=0) # Movingaverages df_amd_ma5 = ta.MA(df_amd['Close'], timeperiod=timeperiod) # MACD df_amd_macd, df_amd_macdsignal, df_amd_macdhist = ta.MACD(df_amd['Close'], fastperiod=12, slowperiod=26, signalperiod=9) # Relativestrengthindex df_amd_rsi = ta.RSI(df_amd['Close'], timeperiod=timeperiod) df_amd_total = df_amd.copy()
def get_dataframe(index_component, input_window_length, forecast_horizon, start_date, end_date, frequency, classnum, method): #get dataframe from sigle company #input shortcuts iwl = input_window_length fh = forecast_horizon method_list = ['ANN', 'SVM'] if not (method in method_list): raise Exception(method + ' is not in' + str(method_list)) ic = index_component this_ti = get_price(ic, start_date, end_date, frequency=frequency) dates = this_ti.index[:-fh] close = np.array(this_ti['close']) next_close = get_next_close(close, fh) high = np.array(this_ti['high']) low = np.array(this_ti['low']) Y = labeling(fh, close[:-fh], next_close, classes=classnum) sma = talib.SMA(close, iwl)[:-fh] ema = talib.EMA(close, iwl)[:-fh] atr = talib.ATR(high, low, close, iwl)[:-fh] admi = talib.ADX(high, low, close, iwl)[:-fh] cci = talib.CCI(high, low, close, iwl)[:-fh] roc = talib.ROC(close, timeperiod=iwl)[:-fh] rsi = talib.RSI(close, timeperiod=iwl)[:-fh] williams = talib.WILLR(high, low, close, timeperiod=iwl)[:-fh] slowk = stochasticK(high, low, close, iwl)[:-fh] slowd = talib.EMA(slowk, 3) #form a initial data frame df = pd.DataFrame( { 'close price t': close[:-fh], 'close price t+s': next_close, # 'Y':Y, 'SMA': sma, 'EMA': ema, 'ATR': atr, 'ADMI': admi, 'CCI': cci, 'ROC': roc, 'RSI': rsi, 'Williams %R': williams, 'Stochastic %K': slowk, 'Stochastic %D': slowd, }, index=dates) # append label according to the method if method == 'SVM': df['Y'] = Y df = df.dropna(axis=0, how='any') y = df['Y'].values if method == 'ANN': one_hot_code = get_onehotcode(Y) ys = [] for i in range(len(one_hot_code[0])): string = 'Y' + str(i + 1) ys.append(string) df[string] = one_hot_code[:, i] df = df.dropna(axis=0, how='any') y = df[ys].values x = df[[ 'ADMI', 'ATR', 'CCI', 'EMA', 'ROC', 'RSI', 'SMA', 'Stochastic %D', 'Stochastic %K', 'Williams %R' ]].values return x, y
def test_ema(): c = numpy.random.randn(100) # this is the library function d = talib.EMA(c, timeperiod=30) assert d is not None
def EMA(df): df['EMA7'] = talib.EMA(df.close, timeperiod=5) df['EMA14'] = talib.EMA(df.close, timeperiod=10) return df
def EMA(self, window=30): real = talib.EMA(self.close, timeperiod=window) return real
def all_technical_indicator_inputs( ohlc_data: pd.DataFrame) -> pd.DataFrame: inputs = { 'open': ohlc_data['Open'], 'high': ohlc_data['High'], 'low': ohlc_data['Low'], 'close': ohlc_data['Close'], 'volume': ohlc_data['Volume'] } # Price Data def day_diff(diff_days: int): n_day_diff = ohlc_data["Close"][diff_days:].to_numpy( ) - ohlc_data["Close"][:-diff_days].to_numpy() n_day_diff = np.insert(n_day_diff, 0, [np.nan] * diff_days, axis=0) return n_day_diff for i in range(5): k = i + 1 ohlc_data["diff-day-" + str(k)] = day_diff(k) # Simple Indicators ohlc_data["EMA-2"] = ohlc_data["Close"] - talib.EMA( ohlc_data["Close"], 2) ohlc_data["EMA-3"] = ohlc_data["Close"] - talib.EMA( ohlc_data["Close"], 3) ohlc_data["EMA-5"] = ohlc_data["Close"] - talib.EMA( ohlc_data["Close"], 5) ohlc_data["EMA-7"] = ohlc_data["Close"] - talib.EMA( ohlc_data["Close"], 7) ohlc_data["EMA-21"] = ohlc_data["Close"] - talib.EMA( ohlc_data["Close"], 21) ohlc_data["EMA-50"] = ohlc_data["Close"] - talib.EMA( ohlc_data["Close"], 50) ohlc_data["RSI"] = talib.RSI(ohlc_data["Close"], 14) / 100 ohlc_data["MACD"] = talib.MACD(ohlc_data["Close"], 12, 26, 9)[2] ohlc_data["ADX"] = talib.ADX(ohlc_data["High"], ohlc_data["Low"], ohlc_data["Close"]) / 100 ohlc_data["STD"] = talib.STDDEV(ohlc_data["Close"]) # Raw Indicators ohlc_data["RAW-EMA-2"] = talib.EMA(ohlc_data["Close"], 2) ohlc_data["RAW-EMA-3"] = talib.EMA(ohlc_data["Close"], 3) ohlc_data["RAW-EMA-5"] = talib.EMA(ohlc_data["Close"], 5) ohlc_data["RAW-EMA-7"] = talib.EMA(ohlc_data["Close"], 7) ohlc_data["RAW-EMA-21"] = talib.EMA(ohlc_data["Close"], 21) ohlc_data["RAW-EMA-50"] = talib.EMA(ohlc_data["Close"], 50) # Complex Indicators def get_useful_bbands(): bb = talib.BBANDS(ohlc_data["Close"]) bb_width = bb[0] - bb[2] bb_buy = ohlc_data["Close"] - bb[0] bb_sell = bb[2] - ohlc_data["Close"] return bb_width, bb_buy, bb_sell ohlc_data["bb_width"], ohlc_data["bb_buy"], ohlc_data[ "bb_sell"] = get_useful_bbands() ohlc_data['Volume'] = ohlc_data['Volume'].diff() return ohlc_data
def cal_ema(close, peroid): return talib.EMA(np.array(close), timeperiod=peroid)
def handle_data(context, data): short_window = 5 #value obtained from Belinda script long_window = 24 #value obtained from Belinda script context.i += 1 if context.i < long_window: return #calculate EMA with Talib my_short_stock_series = data.history(context.asset, 'price', bar_count = short_window, frequency = "1T",) ema_short_result = talib.EMA(my_short_stock_series, timeperiod=short_window) short_ema = ema_short_result[-1] my_long_stock_series = data.history(context.asset, 'price', bar_count = long_window, frequency = "1T",) ema_long_result = talib.EMA(my_long_stock_series, timeperiod=long_window) long_ema = ema_long_result[-1] price = data.current(context.asset, 'price') if context.base_price is None: context.base_price = price price_change = (price - context.base_price)/context.base_price record(price = price, cash = context.portfolio.cash, price_change = price_change, short_ema = short_ema, long_ema = long_ema) pos_amount = context.portfolio.positions[context.asset].amount orders = context.blotter.open_orders if len(orders) > 0: return if not data.can_trade(context.asset): return #sizing calculations #getting high, low, close value from history to talib.ATR function highs = data.history(context.asset, 'high', bar_count = 300, frequency = "1T",).dropna() lows = data.history(context.asset, 'low', bar_count = 300, frequency = "1T",).dropna() closes = data.history(context.asset, 'close', bar_count = 300, frequency = "1T",).dropna() atr = talib.ATR(highs, lows, closes) #talib.ATR output is an array stop_loss_atr = atr[-1] #talib.ATR output is an array stop = stop_loss_atr #print("stop_loss_atr=", stop_loss_atr) #position size calculation based on current equity, risk and trailing stop size = context.portfolio.portfolio_value*context.risk/stop trading_avaliable = context.portfolio.portfolio_value/0.3/price size_aval = size if size<trading_avaliable else trading_avaliable #equal to PineScript statement, size_aval = size<trading_avaliable?size:trading_avaliable #print("size_aval=", size_aval) #trailing stop call. obtaining context.stop_price set_trailing_stop(context, data, stop) #maybe trailing stop should be calculated when order start set_trailing_stop_short(context, data, stop) #print("price=", price, "context.stop_price=", context.stop_price,"context.stop_price_short=", context.stop_price_short) #check for the long stop price and long orders are open if (pos_amount > 0): if price < context.stop_price: order_target_percent(context.asset, 0) context.stop_price = 0 #print("trailing stop") if (pos_amount < 0): if price > context.stop_price_short: order_target_percent(context.asset, 0) context.stop_price_short = 0 #print("trailing stop short") if short_ema > long_ema and pos_amount <=0: order_target_percent(context.asset, 0) #close short asset order(context.asset, size_aval) #open long asset #print("long") elif short_ema < long_ema and pos_amount > 0: order_target_percent(context.asset, 0) #close long asset order(context.asset, -size_aval) #open short asset
def ema(self, n, array=False): """简单均线""" result = talib.EMA(self.close, n) if array: return result return result[-1]
output = pd.concat([leo_candles, leodf_resampled], axis=1) output['burn_amount_usd'] = output['leo_burn_amount'] * output['leo_open'] btc_candles = pd.read_csv('data/BTCUSD_3H_2018-01-01-present.csv', parse_dates=[0], infer_datetime_format=True) btc_candles.set_index(btc_candles['timestamp'], inplace=True) btc_candles.sort_index(inplace=True) btc_candles.rename(columns={'open': 'btc_open', 'volume': 'btc_volume'}, inplace=True) btc_candles.drop(['timestamp','high','low','close'], axis=1, inplace=True) btc_candles['btc_usd_volume'] = btc_candles['btc_volume'] * btc_candles['btc_open'] output = pd.concat([output, btc_candles], axis=1) output['burn_amount_usd_EMA'] = ta.EMA(output['burn_amount_usd'].ffill(), ema_period) output['btc_usd_volume_EMA'] = ta.EMA(output['btc_usd_volume'], ema_period) import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.dates as mdates from matplotlib.lines import Line2D from matplotlib.patches import Rectangle, Patch import matplotlib.patches as mpatches # from matplotlib.finance import candlestick_ohlc from matplotlib.ticker import ScalarFormatter, NullFormatter
'/Users/shashank/Documents/Code/Python/Finance/spxTickers.pickle') tickers = [item.replace(".", "-") for item in tickers] frames = [] for symbol in tickers: ticker = ['{}'.format(symbol)] # Read data data = yf.download(symbol, start, end) # ## SMA and EMA #Simple Moving Average data['SMA'] = talib.SMA(data['Adj Close'], timeperiod=20) # Exponential Moving Average data['EMA'] = talib.EMA(data['Adj Close'], timeperiod=20) # Bollinger Bands data['upper_band'], data['middle_band'], data['lower_band'] = talib.BBANDS( data['Adj Close'], timeperiod=20) # ## MACD (Moving Average Convergence Divergence) # MACD data['macd'], data['macdsignal'], data['macdhist'] = talib.MACD( data['Adj Close'], fastperiod=12, slowperiod=26, signalperiod=9) # ## RSI (Relative Strength Index) # RSI data['RSI'] = talib.RSI(data['Adj Close'], timeperiod=14) # ## OBV (On Balance Volume)
def run(): """ * 如果趋势发生变化,撤销所有的限价挂单以及委托挂单 * 如果有逆势持仓,则平掉所有逆势持仓 * 如果有逆势限价挂单,则撤销所有逆势限价挂单 * 如果没有顺势持仓,则(如果没有限价挂单,则按最优价格挂单;如果有限价挂单,检查价位是否合理,如果不合理则撤销重新挂单) * 如果有顺势持仓,则只挂止盈委托挂单,在慢速ema价格上设置止盈点 """ global g_ret g_ret = qds_test_registration() if not g_ret: logging.debug("Error, software is not correctly registered. Please contact [email protected] to register") return False global period global ma_fast global ma_slow global open_offset global open_interval global stop_offset global level_rate global max_open_number global trend_history global_data = Organized() logging.debug("qds params: period={0}, ma_fast={1}, ma_slow={2}, open_offset={3}, open_interval={4}, " "stop_offset={5}, level_rate={6}, max_open_number={7}".format( period, ma_fast, ma_slow, open_offset, open_interval, stop_offset, level_rate, max_open_number)) if not get_system_running(): return False g_ret = dm.get_contract_kline(symbol=symbol_period, period=period, size=300) if not ru.is_ok(g_ret): logging.debug("get_contract_kline failed, ret={0}".format(pformat(g_ret))) return False global_data = KLineAdapterHuobi.ParseData(g_ret['data']) close_list = global_data._close_list ma_fast_list = talib.EMA(np.array(close_list), timeperiod=ma_fast) ma_slow_list = talib.EMA(np.array(close_list), timeperiod=ma_slow) global_data._ema_list[ma_fast] = ma_fast_list global_data._ema_list[ma_slow] = ma_slow_list # debug_ema(global_data) last_index = global_data.GetLen() - 2 last_ema_fast = global_data.ema_list[ma_fast][last_index] last_ema_slow = global_data.ema_list[ma_slow][last_index] ts = global_data._timestamp[last_index] # 多空决策 trend = None if last_ema_fast > last_ema_slow: trend = 'long' elif last_ema_fast < last_ema_slow: trend = 'short' else: # 趋势不变 if trend_history: trend = trend_history else: trend = 'long' # 趋势发生变化,撤销所有的限价挂单以及委托挂单 logging.debug("ts:{0} ma{1}:{2}, ma{3}:{4}".format(ts, ma_fast, last_ema_fast, ma_slow, last_ema_slow)) if trend_history != trend: logging.debug( "trend={5} last: {4} ma{0}:{1}, ma{2}:{3}".format(ma_fast, last_ema_fast, ma_slow, last_ema_slow, ts, trend)) if not get_system_running(): return False g_ret = dm.cancel_all_contract_order(symbol_type) if ru.is_ok(g_ret): logging.debug("cancel_all_contract_order successfully at trend changed") else: if ru.is_no_order(g_ret): logging.debug("cancel_all_contract_order no orders") else: logging.debug("cancel_all_contract_order failed at trend changed, ret={0}".format(pformat(g_ret))) return False if not get_system_running(): return False g_ret = dm.cancel_all_contract_trigger(symbol_type) if ru.is_ok(g_ret): logging.debug("cancel_all_contract_trigger successfully at trend changed") else: if ru.is_no_order(g_ret): logging.debug("cancel_all_contract_trigger no orders") else: logging.debug("cancel_all_contract_trigger failed at trend changed, ret={0}".format(pformat(g_ret))) return False # 确保撤单成功再修改趋势,否则下次会再次执行撤单操作 trend_history = trend if not get_system_running(): return False g_ret = dm.get_contract_account_position_info(symbol_type) if ru.is_ok(g_ret): available = g_ret['data'][0]['margin_available'] balance = g_ret['data'][0]['margin_balance'] logging.debug("margin_available={0}, margin_balance={1}".format(available, balance)) set_margin(available, balance) if available == 0.0 and balance == 0.0: logging.debug("no available margin {0}, {1}".format(available, balance)) return False # 获取当前持仓多单数量,空单数量,价格 if not get_system_running(): return False g_ret = dm.get_contract_position_info(symbol_type) if not ru.is_ok(g_ret): logging.debug("get_contract_position_info failed, ret={0}".format(pformat(g_ret))) return False cpi_helper.log_all_orders("buy", g_ret) cpi_helper.log_all_orders('sell', g_ret) limit_holding_buy_count = cpi_helper.get_orders_count('buy', g_ret) limit_holding_buy_price = cpi_helper.get_price('buy', g_ret) limit_holding_sell_count = cpi_helper.get_orders_count('sell', g_ret) limit_holding_sell_price = cpi_helper.get_price('sell', g_ret) # 获取当前限价挂单的方向以及价格 if not get_system_running(): return False g_ret = dm.get_contract_open_orders(symbol_type) if not ru.is_ok(g_ret): logging.debug("get_contract_open_orders failed, ret={0}".format(pformat(g_ret))) return False coo_helper.log_all_orders('buy', g_ret) coo_helper.log_all_orders('sell', g_ret) limit_pending_buy_count = coo_helper.get_orders_count('buy', 'open', g_ret) # 开仓 limit_pending_close_sell_count = coo_helper.get_orders_count('sell', 'close', g_ret) # 平仓 limit_pending_sell_count = coo_helper.get_orders_count('sell', 'open', g_ret) limit_pending_close_buy_count = coo_helper.get_orders_count('buy', 'close', g_ret) limit_pending_buy_price_list = coo_helper.get_price('buy', 'open', g_ret) limit_pending_sell_price_list = coo_helper.get_price('sell', 'open', g_ret) # 获取当前委托挂单多单数量,空单数量 if not get_system_running(): return False g_ret = dm.get_contract_trigger_openorders(symbol_type) if not ru.is_ok(g_ret): logging.debug("get_contract_trigger_openorders failed, ret={0}".format(pformat(g_ret))) return False ctoo_helper.log_all_orders('buy', g_ret) ctoo_helper.log_all_orders('sell', g_ret) trigger_holding_buy_count = ctoo_helper.get_orders_count('buy', 'close', g_ret) trigger_holding_sell_count = ctoo_helper.get_orders_count('sell', 'close', g_ret) # 获取当前委托挂单方向以及价格 trigger_holding_buy_order_price = round(ctoo_helper.get_order_price('buy', g_ret)) trigger_holding_sell_order_price = round(ctoo_helper.get_order_price('sell', g_ret)) # 设置最大允许操作数量(挂单数量+持仓数量) max_on_trend_count = max_open_number # 计算当前是否有逆势持仓 limit_holding_against_trend_count = 0 limit_holding_against_trend_close_direction = '' limit_holding_price = 0 trigger_holding_against_trend_count = 0 # 止盈止损 stop_earning_trigger_type = '' stop_earning_trigger_price = 0 stop_earning_order_price = 0 stop_earning_direction = '' limit_pending_on_trend_count = 0 limit_pending_close_on_trend_count = 0 limit_pending_against_trend_count = 0 limit_pending_on_trend_price_list = [] trigger_holding_on_trend_order_price = 0 base_open_point = 0 if trend == 'long': base_open_point = last_ema_slow - open_offset limit_holding_against_trend_count = limit_holding_sell_count limit_holding_against_trend_close_direction = 'buy' trigger_holding_against_trend_count = trigger_holding_sell_count trigger_holding_on_trend_count = trigger_holding_sell_count trigger_holding_on_trend_order_price = trigger_holding_sell_order_price limit_pending_on_trend_open_direction = 'buy' limit_pending_on_trend_count = limit_pending_buy_count limit_pending_close_on_trend_count = limit_pending_close_sell_count limit_pending_against_trend_count = limit_pending_sell_count limit_pending_on_trend_price_list = limit_pending_buy_price_list limit_holding_on_trend_count = limit_holding_buy_count limit_holding_price = limit_holding_buy_price stop_earning_trigger_type = 'ge' stop_earning_order_price = round(last_ema_slow + stop_offset) stop_earning_trigger_price = round(stop_earning_order_price - 10) stop_earning_direction = 'sell' else: base_open_point = last_ema_slow + open_offset limit_holding_against_trend_count = limit_holding_buy_count limit_holding_against_trend_close_direction = 'sell' trigger_holding_against_trend_count = trigger_holding_buy_count trigger_holding_on_trend_count = trigger_holding_buy_count trigger_holding_on_trend_order_price = trigger_holding_buy_order_price limit_pending_on_trend_open_direction = 'sell' limit_pending_on_trend_count = limit_pending_sell_count limit_pending_close_on_trend_count = limit_pending_close_buy_count limit_pending_against_trend_count = limit_pending_buy_count limit_pending_on_trend_price_list = limit_pending_sell_price_list limit_holding_on_trend_count = limit_holding_sell_count limit_holding_price = limit_holding_sell_price stop_earning_trigger_type = 'le' stop_earning_order_price = round(last_ema_slow - stop_offset) stop_earning_trigger_price = round(stop_earning_order_price + 10) stop_earning_direction = 'buy' # 最优限价挂单价格 limit_best_price = [ round(base_open_point - open_interval), round(base_open_point), round(base_open_point + open_interval) ] logging.debug("limit_best_price={0}, {1}, {2}".format(limit_best_price[0], limit_best_price[1], limit_best_price[2])) # 执行交易 # 平掉所有逆势持仓 if limit_holding_against_trend_count > 0: logging.debug("limit_holding_against_trend_count={0}".format(limit_holding_against_trend_count)) if not get_system_running(): return False g_ret = dm.send_lightning_close_position(symbol_type, contract_type_period, '', int(limit_holding_against_trend_count), limit_holding_against_trend_close_direction, '', None) if ru.is_ok(g_ret): limit_holding_against_trend_count = 0 logging.debug("send_lightning_close_position successfully, direction={0}, volume={1}".format( limit_holding_against_trend_close_direction, limit_holding_against_trend_count)) else: logging.debug("send_lightning_close_position failed, ret={0}".format(pformat(g_ret))) return False # 撤销所有逆势限价挂单,简化操作,只要逆势挂单就撤销所有限价挂单 if limit_pending_against_trend_count > 0: logging.debug("limit_pending_against_trend_count={0}".format(limit_pending_against_trend_count)) if not get_system_running(): return False g_ret = dm.cancel_all_contract_order(symbol_type) if ru.is_ok(g_ret): limit_pending_on_trend_count = 0 limit_pending_against_trend_count = 0 logging.debug("cancel_all_contract_order successfully") else: logging.debug("cancel_all_contract_order failed, ret={0}".format(pformat(g_ret))) return False # 如果没有顺势持仓,则(如果没有限价挂单,则按最优价格挂单;如果有限价挂单,检查价位是否合理,如果不合理则撤销重新挂单) if limit_holding_on_trend_count == 0: if limit_pending_on_trend_count == 0: available_limit_pending_on_trend_count = max_on_trend_count logging.debug("available_limit_pending_on_trend_count={0}".format(available_limit_pending_on_trend_count)) if available_limit_pending_on_trend_count > 0: available_limit_pending_on_trend_count_each = [ round(available_limit_pending_on_trend_count / 3), round(available_limit_pending_on_trend_count / 3), max_on_trend_count - round(available_limit_pending_on_trend_count / 3) * 2 ] for i in range(0, len(available_limit_pending_on_trend_count_each)): if limit_holding_on_trend_count < max_on_trend_count: price = round(limit_best_price[i]) volume = available_limit_pending_on_trend_count_each[i] if volume > available_limit_pending_on_trend_count: volume = available_limit_pending_on_trend_count direction = limit_pending_on_trend_open_direction if price > 0 and volume > 0: if not get_system_running(): return False g_ret = dm.send_contract_order(symbol=symbol_type, contract_type=contract_type_period, contract_code='', client_order_id='', price=price, volume=int(volume), direction=direction, offset='open', lever_rate=level_rate, order_price_type='limit') if ru.is_ok(g_ret): available_limit_pending_on_trend_count -= volume logging.debug( "send_contract_order successfully, price={0} volume={1} direction={2}".format( price, int(volume), direction)) else: logging.debug("send_contract_order failed, ret={0}".format(pformat(g_ret))) return False elif limit_pending_on_trend_count != max_on_trend_count: global g_fix_race_check_one_more_time if limit_pending_on_trend_count < max_on_trend_count and not g_fix_race_check_one_more_time: logging.debug( "Fix race issue: limit_pending_on_trend_count {0} is smaller than max_on_trend_count {1}, " "need to check one more time".format(limit_pending_on_trend_count, max_on_trend_count)) g_fix_race_check_one_more_time = True else: g_fix_race_check_one_more_time = False if not get_system_running(): return False g_ret = dm.cancel_all_contract_order(symbol_type) if ru.is_ok(g_ret): logging.debug( "cancel_all_contract_order successfully, limit_pending_on_trend_count {0} not match with " "max_on_trend_count {1}".format(limit_pending_on_trend_count, max_on_trend_count)) else: logging.debug("cancel_all_contract_order failed, ret={0}".format(pformat(g_ret))) return False else: logging.debug("limit_pending_on_trend_count={0}".format(limit_pending_on_trend_count)) for i in range(0, len(limit_pending_on_trend_price_list)): price = limit_pending_on_trend_price_list[i] # 如果限价挂单价格不是最优价格,则撤销重新挂单 is_best_limit_price = False for j in range(0, len(limit_best_price)): if price == limit_best_price[j]: is_best_limit_price = True if not is_best_limit_price: if not get_system_running(): return False g_ret = dm.cancel_all_contract_order(symbol_type) if ru.is_ok(g_ret): logging.debug( "cancel_all_contract_order successfully, price={0} is not one of limit_best_price".format( price)) else: logging.debug("cancel_all_contract_order failed, ret={0}".format(pformat(g_ret))) return False break # 如果有顺势持仓,则只挂止盈委托挂单,在持仓的价格上设置止盈点 # 在只有限价单持仓的情况下,才能设置止盈委托挂单,否则会容易交易失败,而且不合逻辑 available_trigger_pending_on_trend_count = limit_holding_on_trend_count - \ limit_pending_close_on_trend_count - trigger_holding_on_trend_count if available_trigger_pending_on_trend_count > 0: logging.debug("available_trigger_pending_on_trend_count={0}".format(available_trigger_pending_on_trend_count)) if not get_system_running(): return False g_ret = dm.send_contract_trigger_order(symbol=symbol_type, contract_type=contract_type_period, contract_code=None, trigger_type=stop_earning_trigger_type, trigger_price=round(stop_earning_trigger_price), order_price=round(stop_earning_order_price), order_price_type='limit', volume=int(available_trigger_pending_on_trend_count), direction=stop_earning_direction, offset='close', lever_rate=level_rate) if ru.is_ok(g_ret): logging.debug("send_contract_trigger_order successfully, {0} {1} {2} {3} {4}".format( stop_earning_trigger_type, round(stop_earning_trigger_price), round(stop_earning_order_price), int(available_trigger_pending_on_trend_count), stop_earning_direction)) else: logging.debug("send_contract_trigger_order failed, ret={0}".format(pformat(g_ret))) return False
def handle_data(context): # 买入信号 long_signal_triggered = False # 卖出信号 short_signal_triggered = False # 止损信号 stop_loss_signal_triggered = False # 更新净值最大值 if context.user_data.max_net is None: context.user_data.max_net = context.account.huobi_cny_net else: if context.user_data.max_net < context.account.huobi_cny_net: context.user_data.max_net = context.account.huobi_cny_net # 计算当前回撤 current_draw_down = ( 1 - context.account.huobi_cny_net / context.user_data.max_net) * 100 context.log.info("当前回撤为 %.2f%%, 止损线为 %.2f%%" % (current_draw_down, context.user_data.stop_loss_line)) # 当前回撤大于止损线,则产生卖出止损信号 if current_draw_down > context.user_data.stop_loss_line: context.log.info("已经触发止损线,全仓卖出止损,等待下一次买入信号") stop_loss_signal_triggered = True # 获取历史数据 hist = context.data.get_price(context.security, count=context.user_data.ema_slow_window + 1, frequency=context.frequency) if len(hist.index) < context.user_data.ema_slow_window: context.log.warn("bar的数量不足, 等待下一根bar...") return # 收盘价 close_prices = hist["close"].values # 计算EMA值 ema_fast = talib.EMA(close_prices, context.user_data.ema_fast_window) ema_slow = talib.EMA(close_prices, context.user_data.ema_slow_window) # 当前快线EMA current_ema_fast = ema_fast[-1] # 当前慢线EMA current_ema_slow = ema_slow[-1] # 前一个bar的快线EMA pre_ema_fast = ema_fast[-2] # 前一个bar的慢线EMA pre_ema_slow = ema_slow[-2] context.log.info( "当前EMA 快线 = %.2f, 慢线 = %.2f; 前一个bar EMA 快线 = %.2f, 慢线 = %.2f" % (current_ema_fast, current_ema_slow, pre_ema_fast, pre_ema_slow)) # EMA快线从下向上穿过EMA慢线时,产生买入信号 if pre_ema_fast <= pre_ema_slow and current_ema_fast > current_ema_slow: context.log.info("EMA快线从下向上穿过EMA慢线时,产生买入信号") long_signal_triggered = True # EMA快线从上向下穿过EMA慢线时,产生卖出信号 elif pre_ema_fast >= pre_ema_slow and current_ema_fast < current_ema_slow: context.log.info("EMA快线从上向下穿过EMA慢线时,产生卖出信号") short_signal_triggered = True # 有卖出信号,且持有仓位,则市价单全仓卖出 if short_signal_triggered or stop_loss_signal_triggered: if context.account.huobi_cny_btc >= HUOBI_CNY_BTC_MIN_ORDER_QUANTITY: context.user_data.max_net = None # 卖出信号,且不是空仓,则市价单全仓清空 context.log.info("正在卖出 %s" % context.security) context.log.info("卖出数量为 %s" % context.account.huobi_cny_btc) context.order.sell(context.security, quantity=str(context.account.huobi_cny_btc)) else: context.log.info("仓位不足,无法卖出") # 有买入信号,且持有现金,则市价单全仓买入 elif long_signal_triggered: if context.account.huobi_cny_cash >= HUOBI_CNY_BTC_MIN_ORDER_CASH_AMOUNT: # 买入信号,且持有现金,则市价单全仓买入 context.log.info("正在买入 %s" % context.security) context.log.info("下单金额为 %s 元" % context.account.huobi_cny_cash) context.order.buy(context.security, cash_amount=str(context.account.huobi_cny_cash)) else: context.log.info("现金不足,无法下单") else: context.log.info("无交易信号,进入下一根bar")
def Chaikin_oscillator(High, Low, Close, Volume, n=3, m=9): ADL = ((Close - Low) - (High - Close)) / (High - Low) * Volume + 1 return talib.EMA(ADL, n) - talib.EMA(ADL, m)