def bollinger_bands(dataframe, period=21, stdv=2, field='close', colum_prefix="bb") -> DataFrame: from pyti.bollinger_bands import lower_bollinger_band, middle_bollinger_band, upper_bollinger_band dataframe["{}_lower".format(colum_prefix)] = lower_bollinger_band(dataframe[field], period, stdv) dataframe["{}_middle".format(colum_prefix)] = middle_bollinger_band(dataframe[field], period, stdv) dataframe["{}_upper".format(colum_prefix)] = upper_bollinger_band(dataframe[field], period, stdv) return dataframe
def get_analysis(self, data, bollinger_function): if bollinger_function == 'upper': return bollinger_bands.upper_bollinger_band( data, self.params['period']) if bollinger_function == 'middle': return bollinger_bands.middle_bollinger_band( data, self.params['period']) if bollinger_function == 'lower': return bollinger_bands.lower_bollinger_band( data, self.params['period']) if bollinger_function == 'bandwidth': return bollinger_bands.bandwidth(data, self.params['period']) if bollinger_function == 'range': return bollinger_bands.bb_range(data, self.params['period']) if bollinger_function == 'percent_bandwidth': return bollinger_bands.percent_bandwidth(data, self.params['period']) if bollinger_function == 'percent_b': return bollinger_bands.percent_b(data, self.params['period'])
def Update(): print(str(dt.datetime.now()) + " " + timeframe + " Bar Closed - Running Update Function...") # Calculate Indicators iBBUpper = bb.upper_bollinger_band(pricedata['bidclose'], bb_periods, bb_standard_deviations) iBBMiddle = bb.middle_bollinger_band(pricedata['bidclose'], bb_periods, bb_standard_deviations) iBBLower = bb.lower_bollinger_band(pricedata['bidclose'], bb_periods, bb_standard_deviations) iADX = adx(pricedata['bidclose'], pricedata['bidhigh'], pricedata['bidlow'], adx_periods) # Declare simplified variable names for most recent close candle close_price = pricedata['bidclose'][len(pricedata)-1] BBUpper = iBBUpper[len(iBBUpper)-1] BBMiddle = iBBMiddle[len(iBBMiddle)-1] BBLower = iBBLower[len(iBBLower)-1] ADX = iADX[len(iADX)-1] # Print Price/Indicators print("Close Price: " + str(close_price)) print("Upper BB: " + str(BBUpper)) print("Middle BB: " + str(BBMiddle)) print("Lower BB: " + str(BBLower)) print("ADX: " + str(ADX)) # TRADING LOGIC # Change Any Existing Trades' Limits to Middle Bollinger Band if countOpenTrades()>0: openpositions = con.get_open_positions(kind='list') for position in openpositions: if position['currency'] == symbol: print("Changing Limit for tradeID: " + position['tradeId']) try: editlimit = con.change_trade_stop_limit(trade_id=position['tradeId'], is_stop=False, rate=BBMiddle, is_in_pips=False) except: print(" Error Changing Limit.") else: print(" Limit Changed Successfully.") # Entry Logic if ADX < adx_trade_below: if countOpenTrades("B") == 0 and close_price < BBLower: print(" BUY SIGNAL!") print(" Opening Buy Trade...") stop = pricedata['askclose'][len(pricedata)-1] - (BBMiddle - pricedata['askclose'][len(pricedata)-1]) limit = BBMiddle enter("B", stop, limit) if countOpenTrades("S") == 0 and close_price > BBUpper: print(" SELL SIGNAL!") print(" Opening Sell Trade...") stop = pricedata['bidclose'][len(pricedata)-1] + (pricedata['bidclose'][len(pricedata)-1] - BBMiddle) limit = BBMiddle enter("S", stop, limit) # Exit Logic if countOpenTrades("B") > 0 and close_price > BBMiddle: print(" Closing Buy Trade(s)...") exit("B") if countOpenTrades("S") > 0 and close_price < BBMiddle: print(" Closing Sell Trade(s)...") exit("S") print(str(dt.datetime.now()) + " " + timeframe + " Update Function Completed.\n")
def test_middle_bollinger_bands_invalid_period(self): period = 128 with self.assertRaises(Exception) as cm: bollinger_bands.middle_bollinger_band(self.data, period) expected = "Error: data_len < period" self.assertEqual(str(cm.exception), expected)
def test_middle_bollinger_bands_period_6(self): period = 6 middle_bb = bollinger_bands.middle_bollinger_band(self.data, period) np.testing.assert_array_equal(middle_bb, self.middle_bb_period_6_expected)
def calc_feature(data, feature, args): #helper function for creating logs def replace_zero_with_min(series): return series.replace(0, series.loc[series > 0].min()) import numpy as np import pandas as pd from pyti import bollinger_bands as bbands if feature == "SMA": if len(args) != 2: raise ValueError("SMA requires 2 args; period and column name") return data[args[1]].rolling(int(args[0])).mean() elif feature == "BBANDS": if len(args) != 4: raise ValueError( "BBANDS requires 4 args; period, std dev, data_type (1=upper, 2=lower, 3=middle, 4=range) and column name" ) if (int(args[2]) == 1): return bbands.upper_bollinger_band(data[args[3]], int(args[0]), float(args[1])) elif (int(args[2]) == 2): return bbands.lower_bollinger_band(data[args[3]], int(args[0]), float(args[1])) elif (int(args[2]) == 3): return bbands.middle_bollinger_band(data[args[3]], int(args[0]), float(args[1])) elif (int(args[2]) == 4): return bbands.bb_range(data[args[3]], int(args[0]), float(args[1])) else: raise ValueError( "BBANDS data_type must be one of (1=upper, 2=lower, 3=middle, 4=range)" ) elif feature == "ATR": if len(args) != 4: raise ValueError( "ATR requires 4 args; period and close column, high column, low column" ) range_table = pd.DataFrame() range_table["A"] = data[args[2]] - data[args[3]] range_table["B"] = abs(data[args[2]] - data[args[1]].shift(1)) range_table["C"] = abs(data[args[3]] - data[args[1]].shift(1)) range_table["max"] = range_table[['A', 'B', 'C']].max(axis=1) return range_table["max"].rolling(int(args[0])).mean() elif feature == "VOLATILITY_LOG_MA": #calculates relative volatility of 12 periods compared to 200 the #smooths with a moving average if len(args) != 3: raise ValueError( "ATR requires 3 args; period, high column name, low column name" ) data["volatility_12"] = (data[args[1]] - data[args[2]]).rolling(12).std() data["volatility_200"] = (data[args[1]] - data[args[2]]).rolling(200).std() data["volatility"] = data["volatility_12"] / data["volatility_200"] data["volatility_log"] = np.log( replace_zero_with_min(data["volatility"])) return data["volatility_log"].rolling(int(args[0])).mean() elif feature == "VOLUME_LOG_MA": if len(args) != 2: raise ValueError( "VOLUME_LOG_MA requires 2 args; period, column name") data["volume_log"] = np.log(replace_zero_with_min( data[args[1]])) / np.log( replace_zero_with_min(data[args[1]].rolling(200).mean())) return data["volume_log"].rolling(int(args[0])).mean()