def get_state(self, t): """ return the state (define state here) given time t """ # time feature d = t - self.window_size if d <= 0: state = np.zeros((5, 5)) else: feature1 = volume.acc_dist_index( high=self.OHLCV_df[d - 1:t]["High"], low=self.OHLCV_df[d - 1:t]["Low"], close=self.OHLCV_df[d - 1:t]["Adj Close"], volume=self.OHLCV_df[d - 1:t]['Volume']) feature2 = volatility.average_true_range( high=self.OHLCV_df[d - 1:t]["High"], low=self.OHLCV_df[d - 1:t]["Low"], close=self.OHLCV_df[d - 1:t]["Adj Close"]) feature3 = trend.macd(close=self.OHLCV_df[d - 1:t]["Adj Close"], n_slow=self.window_size, n_fast=self.window_size // 2, fillna=True) feature4 = momentum.rsi(close=self.OHLCV_df[d - 1:t]["Adj Close"]) feature5 = others.daily_return( close=self.OHLCV_df[d - 1:t]["Adj Close"]) state = pd.concat( [feature1, feature2, feature3, feature4, feature5], axis=1).values[-5:, :] # block = self.timeseries[d-1:t] # state = np.diff(np.log(block)) state = state.flatten() state = np.append(state, (self.inventory, self.cash)) return state
def AddIndicators(df): # Add Simple Moving Average (SMA) indicators df["sma7"] = SMAIndicator(close=df["Close"], window=7, fillna=True).sma_indicator() df["sma25"] = SMAIndicator(close=df["Close"], window=25, fillna=True).sma_indicator() df["sma99"] = SMAIndicator(close=df["Close"], window=99, fillna=True).sma_indicator() # Add Bollinger Bands indicator indicator_bb = BollingerBands(close=df["Close"], window=20, window_dev=2) df['bb_bbm'] = indicator_bb.bollinger_mavg() df['bb_bbh'] = indicator_bb.bollinger_hband() df['bb_bbl'] = indicator_bb.bollinger_lband() # Add Parabolic Stop and Reverse (Parabolic SAR) indicator indicator_psar = PSARIndicator(high=df["High"], low=df["Low"], close=df["Close"], step=0.02, max_step=2, fillna=True) df['psar'] = indicator_psar.psar() # Add Moving Average Convergence Divergence (MACD) indicator df["MACD"] = macd(close=df["Close"], window_slow=26, window_fast=12, fillna=True) # mazas # Add Relative Strength Index (RSI) indicator df["RSI"] = rsi(close=df["Close"], window=14, fillna=True) # mazas return df
def AddIndicators(df): # Add Moving Average Convergence Divergence (MACD) indicator df["MACD"] = macd(close=df["Close"], window_slow=26, window_fast=12, fillna=True) return df
def test_macd(self): target = 'MACD_line' result = macd(close=self._df['Close'], n_slow=26, n_fast=12, fillna=False) pd.testing.assert_series_equal(self._df[target].tail(), result.tail(), check_names=False)
def test_macd(self): target = "MACD_line" result = macd(close=self._df["Close"], window_slow=26, window_fast=12, fillna=False) pd.testing.assert_series_equal(self._df[target].tail(), result.tail(), check_names=False)
def MACD(df0): df = df0 df['macd'] = macd(df['close'], n_slow=26, n_fast=12, fillna=False) df['macd_signal'] = macd_signal(df['close'], n_slow=26, n_fast=12, n_sign=9, fillna=False) df['macd_hist'] = macd_diff(df['close'], n_slow=26, n_fast=12, n_sign=9, fillna=False) return df
def updateStockSet(self, stocks): for stock in stocks: quote = self.alpaca.polygon.last_quote(stock) lastPrice = quote.askprice timestamp = quote.timestamp row = pd.DataFrame( index=[timestamp], data=[[lastPrice, 0, 0, 0]], columns=['price', 'macdLong', 'macdShort', 'macdSignal']) self.stocks[stock] = pd.concat([self.stocks[stock], row]) prices = self.stocks[stock]['prices'] m = macd(prices) prices = self.stocks[stock]['macdLong'] = m.macd() prices = self.stocks[stock]['macdShort'] = m.macd_diff() prices = self.stocks[stock]['macdSignal'] = m.macd_signal()
async def on_minute_bars(conn, channel, data): now = datetime.strptime(datetime.now().strftime("%y-%m-%d %H:%M"), "%y-%m-%d %H:%M") master_dct[data.symbol].loc[now] = { "open": data.open, "high": data.high, "low": data.low, "close": data.close, "volume": data.volume, } # if the macd is above one, make a purchase of 1 share closes = master_dct[data.symbol].close[:now] hist = macd(closes, n_fast=n_fast, n_slow=n_slow) order_history = {} # only buy if macd is positive and symbol not already bought or open_order submitted if hist[-1] > 0 and not (positions.get(data.symbol, None) or open_orders.get(data.symbol, None)): try: buy = api.submit_order( symbol=data.symbol, qty=1, side="buy", type="limit", time_in_force="gtc", limit_price=str(data.close), order_class="bracket", take_profit=dict(limit_price=f"{data.close * 1.02}"), stop_loss=dict( stop_price=f"{data.close * 0.99}", limit_price=f"{data.close * 0.99}", ), ) open_orders[data.symbol] = buy logging.info(f"Submitted order 1 share of {data.symbol}") except Exception as e: logging.debug(e) logging.debug(f"buy order for {data.symbol} not processed...") cancel_old_orders(api, open_orders, data.symbol, time_zone)
def macd_cb_pressed(stock_analysis_tool: QMainWindow, cb: QCheckBox) -> None: """ :param cb: :return: """ if cb.isChecked(): # Add MACD to Display Graph stock_analysis_tool.df['MACD'] = macd(close=stock_analysis_tool.df['close'], n_slow=stock_analysis_tool.macd_slow, n_fast=stock_analysis_tool.macd_fast) - \ macd_signal(close=stock_analysis_tool.df['close'], n_slow=stock_analysis_tool.macd_slow, n_fast=stock_analysis_tool.macd_fast, n_sign=stock_analysis_tool.macd_sign) stock_analysis_tool.add_column_to_graph(column_name='MACD') else: # Remove MACD from Display Graph stock_analysis_tool.remove_column_from_graph( column_name='MACD') stock_analysis_tool.df = stock_analysis_tool.df.drop("MACD", axis=1)
def engineer_data_over_single_interval(df: pd.DataFrame, indicators: list, ticker: str = "", rsi_n: int = 14, cmo_n: int = 7, macd_fast: int = 12, macd_slow: int = 26, macd_sign: int = 9, roc_n: int = 12, cci_n: int = 20, dpo_n: int = 20, cmf_n: int = 20, adx_n: int = 14, mass_index_low: int = 9, mass_index_high: int = 25, trix_n: int = 15, stochastic_oscillator_n: int = 14, stochastic_oscillator_sma_n: int = 3, ultimate_oscillator_short_n: int = 7, ultimate_oscillator_medium_n: int = 14, ultimate_oscillator_long_n: int = 28, ao_short_n: int = 5, ao_long_n: int = 34, kama_n: int = 10, tsi_high_n: int = 25, tsi_low_n: int = 13, eom_n: int = 14, force_index_n: int = 13, ichimoku_low_n: int = 9, ichimoku_medium_n: int = 26): from ta.momentum import rsi, wr, roc, ao, stoch, uo, kama, tsi from ta.trend import macd, macd_signal, cci, dpo, adx, mass_index, trix, ichimoku_a from ta.volume import chaikin_money_flow, acc_dist_index, ease_of_movement, force_index # Momentum Indicators if Indicators.RELATIVE_STOCK_INDEX in indicators: Logger.console_log(message="Calculating " + Indicators.RELATIVE_STOCK_INDEX.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.RELATIVE_STOCK_INDEX.value] = rsi(close=df['close'], n=rsi_n) if Indicators.WILLIAMS_PERCENT_RANGE in indicators: Logger.console_log(message="Calculating " + Indicators.WILLIAMS_PERCENT_RANGE.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.WILLIAMS_PERCENT_RANGE.value] = wr( df['high'], df['low'], df['close']) if Indicators.CHANDE_MOMENTUM_OSCILLATOR in indicators: Logger.console_log(message="Calculating " + Indicators.CHANDE_MOMENTUM_OSCILLATOR.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.CHANDE_MOMENTUM_OSCILLATOR. value] = chande_momentum_oscillator(close_data=df['close'], period=cmo_n) if Indicators.RATE_OF_CHANGE in indicators: Logger.console_log(message="Calculating " + Indicators.RATE_OF_CHANGE.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.RATE_OF_CHANGE.value] = roc(close=df['close'], n=roc_n) if Indicators.STOCHASTIC_OSCILLATOR in indicators: Logger.console_log(message="Calculating " + Indicators.STOCHASTIC_OSCILLATOR.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.STOCHASTIC_OSCILLATOR.value] = stoch( high=df['high'], low=df['low'], close=df['close'], n=stochastic_oscillator_n, d_n=stochastic_oscillator_sma_n) if Indicators.ULTIMATE_OSCILLATOR in indicators: Logger.console_log(message="Calculating " + Indicators.ULTIMATE_OSCILLATOR.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.ULTIMATE_OSCILLATOR.value] = uo( high=df['high'], low=df['low'], close=df['close'], s=ultimate_oscillator_short_n, m=ultimate_oscillator_medium_n, len=ultimate_oscillator_long_n) if Indicators.AWESOME_OSCILLATOR in indicators: Logger.console_log(message="Calculating " + Indicators.AWESOME_OSCILLATOR.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.AWESOME_OSCILLATOR.value] = ao(high=df['high'], low=df['low'], s=ao_short_n, len=ao_long_n) if Indicators.KAUFMAN_ADAPTIVE_MOVING_AVERAGE in indicators: Logger.console_log(message="Calculating " + Indicators.KAUFMAN_ADAPTIVE_MOVING_AVERAGE.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.KAUFMAN_ADAPTIVE_MOVING_AVERAGE.value] = kama( close=df['close'], n=kama_n) if Indicators.TRUE_STRENGTH_INDEX in indicators: Logger.console_log(message="Calculating " + Indicators.TRUE_STRENGTH_INDEX.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.TRUE_STRENGTH_INDEX.value] = tsi(close=df['close'], r=tsi_high_n, s=tsi_low_n) # Trend Indicator if Indicators.MOVING_AVERAGE_CONVERGENCE_DIVERGENCE in indicators: Logger.console_log( message="Calculating " + Indicators.MOVING_AVERAGE_CONVERGENCE_DIVERGENCE.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.MOVING_AVERAGE_CONVERGENCE_DIVERGENCE.value] = macd(close=df['close'], n_slow=macd_slow, n_fast=macd_fast) - \ macd_signal(close=df['close'], n_slow=macd_slow, n_fast=macd_fast, n_sign=macd_sign) if Indicators.COMMODITY_CHANNEL_INDEX in indicators: Logger.console_log(message="Calculating " + Indicators.COMMODITY_CHANNEL_INDEX.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.COMMODITY_CHANNEL_INDEX.value] = cci(high=df['high'], low=df['low'], close=df['close'], n=cci_n) if Indicators.DETRENDED_PRICE_OSCILLATOR in indicators: Logger.console_log(message="Calculating " + Indicators.DETRENDED_PRICE_OSCILLATOR.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.DETRENDED_PRICE_OSCILLATOR.value] = dpo( close=df['close'], n=dpo_n) if Indicators.AVERAGE_DIRECTIONAL_INDEX in indicators: Logger.console_log(message="Calculating " + Indicators.AVERAGE_DIRECTIONAL_INDEX.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.AVERAGE_DIRECTIONAL_INDEX.value] = adx(high=df['high'], low=df['low'], close=df['close'], n=adx_n) if Indicators.MASS_INDEX in indicators: Logger.console_log(message="Calculating " + Indicators.MASS_INDEX.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.MASS_INDEX.value] = mass_index(high=df['high'], low=df['low'], n=mass_index_low, n2=mass_index_high) if Indicators.TRIPLE_EXPONENTIALLY_SMOOTHED_MOVING_AVERAGE in indicators: Logger.console_log( message="Calculating " + Indicators.TRIPLE_EXPONENTIALLY_SMOOTHED_MOVING_AVERAGE.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.TRIPLE_EXPONENTIALLY_SMOOTHED_MOVING_AVERAGE. value] = trix(close=df['close'], n=trix_n) if Indicators.ICHIMOKU_A in indicators: Logger.console_log(message="Calculating " + Indicators.ICHIMOKU_A.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.ICHIMOKU_A.value] = ichimoku_a(high=df['high'], low=df['low'], n1=ichimoku_low_n, n2=ichimoku_medium_n) # Volume Indicator if Indicators.CHAIKIN_MONEY_FLOW in indicators: Logger.console_log(message="Calculating " + Indicators.CHAIKIN_MONEY_FLOW.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.CHAIKIN_MONEY_FLOW.value] = chaikin_money_flow( high=df['high'], low=df['low'], close=df['close'], volume=df['volume'], n=cmf_n) if Indicators.ACCUMULATION_DISTRIBUTION_INDEX in indicators: Logger.console_log(message="Calculating " + Indicators.ACCUMULATION_DISTRIBUTION_INDEX.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.ACCUMULATION_DISTRIBUTION_INDEX.value] = acc_dist_index( high=df['high'], low=df['low'], close=df['close'], volume=df['volume']) if Indicators.EASE_OF_MOVEMENT in indicators: Logger.console_log(message="Calculating " + Indicators.EASE_OF_MOVEMENT.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.EASE_OF_MOVEMENT.value] = ease_of_movement( high=df['high'], low=df['low'], volume=df['volume'], n=eom_n) if Indicators.FORCE_INDEX in indicators: Logger.console_log(message="Calculating " + Indicators.FORCE_INDEX.value + " for stock " + ticker, status=Logger.LogStatus.EMPHASIS) df[Indicators.FORCE_INDEX.value] = force_index(close=df['close'], volume=df['volume'], n=force_index_n)
from ta.momentum import wr #William Percent Range from ta.trend import macd # Moving Average Convergence/Divergence # *************************** DATA PREPROCESSING ****************************** # Load Data df = pd.read_csv('^GSPC.csv') # Data Augmentation df['Relative_Strength_Index'] = rsi(df['Close']) df['Money_Flow_Index'] = money_flow_index(df['High'], df['Low'], df['Close'], df['Volume']) df['Stoch_Oscilator'] = stoch(df['High'], df['Low'], df['Close']) df['Ultimate_Oscilator'] = uo(df['High'], df['Low'], df['Close']) df['William_Percent'] = wr(df['High'], df['Low'], df['Close']) df['MACD'] = macd(df['Close']) # Some indicators require many days in advance before they produce any # values. So the begining rows of our df may have NaNs. Lets drop them: df = df.dropna() # Scaling Data from sklearn.preprocessing import MinMaxScalern sc = MinMaxScaler(feature_range=(0, 1)) scaled_df = sc.fit_transform(df.iloc[:, 1:].values) # Creating a data structure with 60 timesteps and 1 output X_train = np.array( [scaled_df[i:i + 60, :] for i in range(len(scaled_df) - 60)]) y_train = np.array([scaled_df[i + 60, 0] for i in range(len(scaled_df) - 60)])
def scan(stock_detail,stock_budget): # scan the macd on the stock stock_macd = {} stock_macd_signal = {} stock_macd_diff = {} stock_sma = {} # get the macd of all the stocks for sym in stock_detail: # perform a macd on the aggregated data stock_macd[sym] = macd( close = stock_detail[sym]['close'].dropna(), ) stock_macd_signal[sym] = macd_signal( close = stock_detail[sym]['close'].dropna(), ) stock_macd_diff[sym] = macd_diff( close = stock_detail[sym]['close'].dropna(), ) # get 200 day sma stock_sma[sym] = sma_indicator( close = stock_detail[sym]['close'].dropna(), n = 200 ) for sym in stock_macd: curr_price = currentClosePrice(sym,'day') print('PRICE: ' + str(curr_price)) print("MACD: "+ str(stock_macd[sym][-1])) print("MACD SIGNAL: " + str(stock_macd_signal[sym][-1])) print("MACD DIFF:" + str(stock_macd_diff[sym][-1])) print("SMA: " + str(stock_sma[sym][-1])+'\n') # Buy Signal if ((stock_macd[sym][-1]<stock_macd_diff[sym][-1] and stock_macd_signal[sym][-1]<stock_macd_diff[sym][-1]) and #check for macd and signal neg ovr hist not(stock_macd_diff[sym][-3]>0 and stock_macd_diff[sym][-2]>0 and stock_macd_diff[sym][-1]>0) and #hist is not going neg (curr_price<stock_macd[sym][-1])): #close price below 200 moving average # check how many share that the budget can afford shares = determineShare(sym, stock_budget[sym]) # so macd looks good, so maybe want to buy? if shares>0 and clock.is_open(): stock_shares[sym] = shares #update the shares about to buy api.submit_order(sym,shares,'buy','market','day') print("Buying Stock {symbol}".format(symbol=sym)) # Sell Signal elif((stock_macd[sym][-1]>stock_macd_diff[sym][-1] and stock_macd_signal[sym][-1]>stock_macd_diff[sym][-1]) and #check for macd and signal pos ovr hist not(stock_macd_diff[sym][-3]<0 and stock_macd_diff[sym][-2]<0 and stock_macd_diff[sym][-1]<0) and #hist is not going pos (curr_price>stock_macd[sym][-1])): #close price above 200 moving average # check if we have any shares of this stock if stock_shares[sym]>0 and clock.is_open(): print(stock_shares[sym]) # sell all the shares api.submit_order(sym,stock_budget[sym],'sell','market','day') stock_shares[sym] = 0 #update the shares dictionary to 0, b/c sold all print("Selling Stock {symbol}".format(symbol=sym))
def features_df(stocks, rsi_vals=False, macd_vals=False, ppo=False, awesome_oscillator_val=False, daily_log_return=False, _return=False, change=False, volatility=False, min5=False, min10=False, min30=False, hband_indicator=False, lband_indicator=False, corr=False): """ Calculates the momentum, RSI, moving average convergence/divergence (MACD), Percentage Price Oscillator, awesome oscillator indicator, daily log return column, return, change, volatility, 5-10 and 30 mins moving average, high band indicator, lower band indicator, correlation of the given stock dataframe. :param stocks: dataframe of stocks :param rsi_vals: Default value False. If you want the RSI column, set True :param macd_vals: Default value False. If you want the MACD column, set True :param ppo: Default value False. If you want the Percentage Price Oscillator column, set True :param awesome_oscillator_val: Default value False. If you want the awesome oscillator indicator column, set True :param daily_log_return: Default value False. If you want the daily log return column, set True :param _return: Default value False. If you want the return column, set True :param change: Default value False. If you want the change column, set True :param volatility: Default value False. If you want the volatility column, set True :param min5: Default value False. If you want the min5 column, set True :param min10: Default value False. If you want the min10 column, set True :param min30: Default value False. If you want the min30 column, set True :param hband_indicator: Default value False. If you want the high band indicator column, set True :param lband_indicator: Default value False. If you want the lower band indicator column, set True :param corr: Default value False. If you want the correlation column, set True :return: a dataframe with the different features of said stock Default value False. If you want the RSI column, set True """ if rsi_vals is True: stocks['rsi_vals'] = RSIIndicator(close=stocks.Close, window=10).rsi() if macd_vals is True: stocks['macd_vals'] = macd(stocks.Close, window_slow=26, window_fast=12) if ppo is True: stocks['Ppo'] = np.array( PercentagePriceOscillator(stocks.Close, window_slow=26, window_fast=12).ppo()) if awesome_oscillator_val is True: stocks['awesome_oscillator'] = awesome_oscillator(stocks.High, stocks.Low, window1=5, window2=29) if daily_log_return is True: stocks['daily_log_return'] = daily_return(close=stocks.Close) if _return is True: stocks['Return'] = round(stocks['Close'] / stocks['Open'] - 1, 3) if change is True: stocks['Change'] = (stocks.Close - stocks.Close.shift(1)).fillna(0) if volatility is True: stocks['Volatility'] = stocks.Close.ewm(21).std() if min5 is True: stocks['min5'] = stocks.Close.rolling(5).mean() if min10 is True: stocks['min10'] = stocks.Close.rolling(10).mean() if min30 is True: stocks['min30'] = stocks.Close.rolling(30).mean() if hband_indicator is True: stocks['hband_indicator'] = BollingerBands( close=stocks.Close).bollinger_hband_indicator() if lband_indicator is True: stocks['lband_indicator'] = BollingerBands( close=stocks.Close).bollinger_lband_indicator() if corr is True: stocks['Corr'] = stocks.Close.rolling(window=10).corr(stocks['min10']) return stocks.iloc[-1, :]
df = pd.DataFrame(data, columns=columns) Symbols = df['Symbol'] lst = [] for k in range(500): if k == 344: # This index gives an error when fitting the model pass else: print(k, Symbols[k]) data = yf.Ticker(Symbols[k]) reader = data.history(day, interval='1m') y = np.where(reader['Close'].shift(-1) > reader['Close'], 1, -1)[30:] reader['rsi_vals'] = RSIIndicator(close=reader.Close, window=10).rsi() reader['macd_vals'] = macd(reader.Close, window_slow=26, window_fast=12) reader['Ppo'] = PercentagePriceOscillator(reader.Close, window_slow=26, window_fast=12).ppo() reader['awesome_oscillator'] = awesome_oscillator(reader.High, reader.Low, window1=5, window2=29) reader['daily_log_return'] = daily_return(close=reader.Close) reader['Return'] = round(reader['Close'] / reader['Open'] - 1, 3) reader['Change'] = (reader.Close - reader.Close.shift(1)).fillna(0) reader['Volatility'] = reader.Close.ewm(21).std() reader['min5'] = reader.Close.rolling(5).mean() reader['min10'] = reader.Close.rolling(10).mean() reader['min30'] = reader.Close.rolling(30).mean()
def calculate_Trend_Indicators(): JSON_sent = request.get_json() if len(JSON_sent[0]) > 0: df = pd.DataFrame(JSON_sent[0]) _, sma, ema, macdDict, macdSignal, adxDict, adxPos, adxNeg, VIpos, VIneg, trixDict, mi, dpoDict = JSON_sent if sma['displaySMA']: indicator_sma = sma_indicator(close=df['close'], n=sma['nForSMA']) df['sma'] = indicator_sma if ema['displayEMA']: indicator_ema = ema_indicator(close=df['close'], n=ema['nForEMA']) df['ema'] = indicator_ema if macdDict['displayMACD']: indicator_macd = macd(close=df['close'], n_slow=macdDict['nSlowForMACD'], n_fast=macdDict['nFastForMACD']) df['macd'] = indicator_macd if macdSignal['displayMACDsignal']: indicator_macdSignal = macd_signal( close=df['close'], n_slow=macdSignal['nSlowForMACDsignal'], n_fast=macdSignal['nFastForMACDsignal'], n_sign=macdSignal['nSignForMACDsignal']) df['macds'] = indicator_macdSignal if adxDict['displayADX']: indicator_ADX = adx(high=df['high'], low=df['low'], close=df['close'], n=adxDict['nForADX']) df['adx'] = indicator_ADX if adxPos['displayADXP']: indicator_ADXpositive = adx_pos(high=df['high'], low=df['low'], close=df['close'], n=adxPos['nForADXP']) df['adxp'] = indicator_ADXpositive if adxNeg['displayADXN']: indicator_ADXnegative = adx_neg(high=df['high'], low=df['low'], close=df['close'], n=adxNeg['nForADXN']) df['adxn'] = indicator_ADXnegative if VIpos['displayVIPOS']: indicator_VIpositive = vortex_indicator_pos(high=df['high'], low=df['low'], close=df['close'], n=VIpos['nForVIPOS']) df['vipos'] = indicator_VIpositive if VIneg['displayVINEG']: indicator_VInegative = vortex_indicator_neg(high=df['high'], low=df['low'], close=df['close'], n=VIneg['nForVINEG']) df['vineg'] = indicator_VInegative if trixDict['displayTRIX']: indicator_TRIX = trix(close=df['close'], n=trixDict['nForTRIX']) df['trix'] = indicator_TRIX if mi['displayMI']: indicator_MassIndex = mass_index(high=df['high'], low=df['low'], n=mi['nForMI'], n2=mi['n2ForMI']) df['mi'] = indicator_MassIndex if dpoDict['displayDPO']: indicator_dpo = dpo(close=df['close'], n=dpoDict['nForDPO']) df['dpo'] = indicator_dpo df.fillna(0, inplace=True) return (json.dumps(df.to_dict('records'))) else: df = pd.DataFrame([]) return (json.dumps(df.to_dict('records')))
async def handle_second_bar(conn, channel, data): symbol = data.symbol # First, aggregate 1s bars for up-to-date MACD calculations ts = data.start ts -= timedelta(seconds=ts.second, microseconds=ts.microsecond) try: current = minute_history[data.symbol].loc[ts] except KeyError: current = None new_data = [] if current is None: new_data = [ data.open, data.high, data.low, data.close, data.volume ] else: new_data = [ current.open, data.high if data.high > current.high else current.high, data.low if data.low < current.low else current.low, data.close, current.volume + data.volume ] minute_history[symbol].loc[ts] = new_data # Next, check for existing orders for the stock existing_order = open_orders.get(symbol) if existing_order is not None: # Make sure the order's not too old submission_ts = existing_order.submitted_at.astimezone( timezone('America/New_York')) order_lifetime = ts - submission_ts if order_lifetime.seconds // 60 > 1: # Cancel it so we can try again for a fill api.cancel_order(existing_order.id) return # Now we check to see if it might be time to buy or sell since_market_open = ts - market_open_dt until_market_close = market_close_dt - ts if (since_market_open.seconds // 60 > 15 and since_market_open.seconds // 60 < 60): # Check for buy signals # See if we've already bought in first position = positions.get(symbol, 0) if position > 0: return # See how high the price went during the first 15 minutes lbound = market_open_dt ubound = lbound + timedelta(minutes=15) high_15m = 0 try: high_15m = minute_history[symbol][lbound:ubound]['high'].max() except Exception as e: # Because we're aggregating on the fly, sometimes the datetime # index can get messy until it's healed by the minute bars return # Get the change since yesterday's market close daily_pct_change = ((data.close - prev_closes[symbol]) / prev_closes[symbol]) if (daily_pct_change > .04 and data.close > high_15m and volume_today[symbol] > 30000): # check for a positive, increasing MACD hist = macd(minute_history[symbol]['close'].dropna(), n_fast=12, n_slow=26) if (hist[-1] < 0 or not (hist[-3] < hist[-2] < hist[-1])): return hist = macd(minute_history[symbol]['close'].dropna(), n_fast=40, n_slow=60) if hist[-1] < 0 or np.diff(hist)[-1] < 0: return # Stock has passed all checks; figure out how much to buy stop_price = find_stop(data.close, minute_history[symbol], ts) stop_prices[symbol] = stop_price target_prices[symbol] = data.close + ( (data.close - stop_price) * 3) shares_to_buy = portfolio_value * risk // (data.close - stop_price) if shares_to_buy == 0: shares_to_buy = 1 shares_to_buy -= positions.get(symbol, 0) if shares_to_buy <= 0: return print('Submitting buy for {} shares of {} at {}'.format( shares_to_buy, symbol, data.close)) try: o = api.submit_order(symbol=symbol, qty=str(shares_to_buy), side='buy', type='limit', time_in_force='day', limit_price=str(data.close)) open_orders[symbol] = o latest_cost_basis[symbol] = data.close except Exception as e: print(e) return if (since_market_open.seconds // 60 >= 24 and until_market_close.seconds // 60 > 15): # Check for liquidation signals # We can't liquidate if there's no position position = positions.get(symbol, 0) if position == 0: return # Sell for a loss if it's fallen below our stop price # Sell for a loss if it's below our cost basis and MACD < 0 # Sell for a profit if it's above our target price hist = macd(minute_history[symbol]['close'].dropna(), n_fast=13, n_slow=21) if (data.close <= stop_prices[symbol] or (data.close >= target_prices[symbol] and hist[-1] <= 0) or (data.close <= latest_cost_basis[symbol] and hist[-1] <= 0)): print('Submitting sell for {} shares of {} at {}'.format( position, symbol, data.close)) try: o = api.submit_order(symbol=symbol, qty=str(position), side='sell', type='limit', time_in_force='day', limit_price=str(data.close)) open_orders[symbol] = o latest_cost_basis[symbol] = data.close except Exception as e: print(e) return elif (until_market_close.seconds // 60 <= 15): # Liquidate remaining positions on watched symbols at market try: position = api.get_position(symbol) except Exception as e: # Exception here indicates that we have no position return print('Trading over, liquidating remaining position in {}'.format( symbol)) api.submit_order(symbol=symbol, qty=position.qty, side='sell', type='market', time_in_force='day') symbols.remove(symbol) if len(symbols) <= 0: conn.close() conn.deregister(['A.{}'.format(symbol), 'AM.{}'.format(symbol)])
def __init__(self, N1, N2): super().__init__(indicator=lambda x: macd(x, n_fast=N1, n_slow=N2)) self.lookback_window = max(N1, N2)