def get_data_alpaca(parameters): dividends = None splits = None api = REST(alpaca_keys.APCA_API_KEY_ID, alpaca_keys.APCA_API_SECRET_KEY) data = api.get_aggs(parameters['symbol'], multiplier=parameters['multiplier'], timespan=parameters['timespan'], _from=parameters['_from'], to=parameters['to']).df if parameters['timestamp_type'] == 'date': dividends, splits = get_actions_alpaca(parameters['symbol']) return create_tuple_alpaca(data, parameters['timestamp_type'], dividends=dividends, splits=splits)
def __init__(self, paper=True): key_names = Settings.keys_names if paper: key_id = key_names["Alpaca Paper Key ID"] secret_key = key_names["Alpaca Paper Secret Key"] base_url = "https://paper-api.alpaca.markets" else: key_id = key_names["Alpaca Live Key ID"] secret_key = key_names["Alpaca Live Secret Key"] base_url = "https://api.alpaca.markets" key_id = environ[key_id] secret_key = environ[secret_key] self.api = REST(key_id, secret_key, base_url) del key_id, secret_key
import os import alpaca_trade_api as tradeapi import pandas as pd from datetime import datetime from alpaca_trade_api import REST os.environ['APCA_API_KEY_ID'] = 'AKYKO5J4G4C4S1SECH81' os.environ['APCA_API_SECRET_KEY'] = 'jj4D0a9jWLO8t6vDiF7DM1jCzaFRO5bnbfEHevDH' api = REST() start = pd.Timestamp(2004, 6, 10, 12).isoformat() end = pd.Timestamp(2005, 6, 23, 12).isoformat() # print(api.polygon.historic_agg_v2('AAPL', 1, 'minute', _from=start, to=end).df) # print(api.polygon.dividends('AAPL')[0]._raw) # print(api.polygon.splits('TXG')[0]._raw) data = api.get_aggs('SPY', 1, 'day', '1900-01-01', '2020-01-20') for i, record in data.df.iterrows(): timestamp = i.to_pydatetime() print(timestamp) break # print(api.get_aggs('GRPN',1,'day','2020-06-05','2020-06-13')) # data = api.get_aggs(parameters['symbol'], # multiplier=parameters['multiplier'], # timespan=parameter['timespan'], # _from=parameters['_from'], # to=parameters['to']).df # thing = api.get_aggs('ABT',1,'minute','2000-01-01','2100-01-01').df # print(thing.columns) # print(thing.index[0]) # print(thing.index[len(thing) - 1]) # print(datetime.fromtimestamp(thing.df.columns))
from google.cloud import storage import pandas as pd pd.set_option('mode.chained_assignment', None) from alpaca_trade_api import REST from select_swing_stocks import select_swing_stocks import discord_webhook # Get Alpaca API key and secret storage_client = storage.Client() bucket = storage_client.get_bucket('derek-algo-trading-bucket') blob = bucket.blob('alpaca-api-key.txt') api_key = blob.download_as_text() blob = bucket.blob('alpaca-secret-key.txt') secret_key = blob.download_as_text() base_url = 'https://paper-api.alpaca.markets' api = REST(api_key, secret_key, base_url, 'v2') # Check if the market is open today nyc = timezone('America/New_York') today = datetime.today().astimezone(nyc) today_str = today.strftime('%Y-%m-%d') today = datetime.isoformat(pd.Timestamp(datetime.today().astimezone(nyc))) try: calendar = api.get_calendar(start=today, end=today)[0] except Exception as e: print(e) print('Market must not be open') calendar = None if calendar and calendar.date.strftime('%Y-%m-%d') == today_str: # Select the swing stocks to buy, sell, and hold
def select_swing_stocks(): # Get Alpaca API key and secret storage_client = storage.Client() bucket = storage_client.get_bucket('derek-algo-trading-bucket') blob = bucket.blob('alpaca-api-key.txt') api_key = blob.download_as_text() blob = bucket.blob('alpaca-secret-key.txt') secret_key = blob.download_as_text() base_url = 'https://paper-api.alpaca.markets' api = REST(api_key, secret_key, base_url, 'v2') # Get all stocks assets = api.list_assets('active') symbols = [asset.symbol for asset in assets if asset.tradable] # Get all currently held positions positions = api.list_positions() if positions: print('Current positions:') position_symbols = [position.symbol for position in positions] position_data = {} for position in positions: current_percent = (float(position.current_price) - float(position.avg_entry_price)) \ / float(position.avg_entry_price) * 100 print('{}: {}%'.format(position.symbol, '%.2f' % current_percent)) position_data[position.symbol] = position print() # Get past 50 days data for all stocks data = {} symbols_chunked = list(chunks(list(set(symbols)), 200)) for symbol_group in symbols_chunked: print(f'Retrieving {len(symbol_group)} symbol data') data_group = api.get_barset(','.join(symbol_group), '1D', limit=1000).df for symbol in symbol_group: data[symbol] = data_group[symbol] buy_df = pd.DataFrame() sell_df = pd.DataFrame() hold_df = pd.DataFrame() c = 0 for symbol in data.keys(): df = pd.DataFrame(data[symbol]) df = df.loc[df['close'] > 0] if symbol not in position_symbols and len(df) == 1000: df['symbol'] = symbol # bullish pattern detection # bullish = [''] * len(df) # bullish[len(bullish) - 1] = pattern.detect_bullish_patterns(df) df['bullish'] = pattern.detect_bullish_patterns(df) buy_df = buy_df.append(df.loc[df.index == df.index.max()]) elif symbol in position_symbols: print(f'\nCurrently holding {symbol}:') df['symbol'] = symbol df['qty'] = int(position_data[symbol].qty) df['market_value'] = float(position_data[symbol].market_value) latest_rsi = rsi(df).df.tail(1)['rsi'][0] latest_cci = cci(df).df.tail(1)['cci'][0] purchase_price = float(position_data[symbol].avg_entry_price) latest_price = float(position_data[symbol].current_price) df['purchase_price'] = purchase_price df['latest_price'] = latest_price # If it has dropped below the entry price, GET IT OUT if latest_price < purchase_price: print( f'Price ${latest_price} is below entry ${purchase_price}: SELL' ) sell_df = sell_df.append(df.loc[df.index == df.index.max()]) # Or if the RSI or CCI are too high, GET IT OUT elif latest_rsi >= 70 or latest_cci >= 100: print(f'Overbought, RSI={latest_rsi}, CCI={latest_cci}: SELL') sell_df = sell_df.append(df.loc[df.index == df.index.max()]) # If price is at/above entry # Check if the swing is still swinging elif latest_price >= purchase_price: print( f'Price ${latest_price} is at/above entry ${purchase_price}' ) obv_df = obv(df).df obv_df['obv_ema'] = obv_df['obv'].ewm(span=20).mean() # Is the OBV still above it's EMA if obv_df.tail(1)['obv'][0] > obv_df.tail(1)['obv_ema'][0]: print('OBV is still above OBV_EMA') slope = linregress([0, 1, 2], obv_df.tail(3)['obv'].tolist()).slope if slope > 0: print( f'OBV is increasing with a slope of {slope}: HOLD') hold_df = hold_df.append( df.loc[df.index == df.index.max()]) print() c += 1 if c % 100 == 0: print(f'{c}/{len(data.keys())}') print(f'{c}/{len(data.keys())}\n') # END SCREENING SECTION # Consolidate results print('DECISION:\n') hold_stocks = hold_df.loc[hold_df.index == hold_df.index.max()] if not hold_stocks.empty: print(f'Hold {len(hold_stocks)}:\n' + '\n'.join(hold_stocks['symbol'].tolist()) + '\n') sell_stocks = sell_df.loc[sell_df.index == sell_df.index.max()] if not sell_stocks.empty: print(f'Sell {len(sell_stocks)}:\n' + '\n'.join(sell_stocks['symbol'].tolist()) + '\n') portfolio_size = 20 purchase_size = portfolio_size - len(hold_stocks) # If there's room in the portfolio to buy more if purchase_size > 0: print(f'We can purchase {purchase_size} new stocks today.') buy_stocks = buy_df.loc[buy_df.index == buy_df.index.max()] buy_stocks = buy_stocks[buy_stocks['bullish'] != ''] buy_stocks = buy_stocks.sort_values( by='volume', ascending=False).head(purchase_size) account = api.get_account() holding_value = hold_stocks['market_value'].tolist().sum( ) if not hold_stocks.empty else 0.0 available_funds = (float(account.portfolio_value) + float(account.cash) - holding_value) * 0.95 print(f'Available funds to buy: ${available_funds}') # For now this will create equal-weight positions funds_per_stock = available_funds / len(buy_stocks) # Calculate quantity to buy for each stock buy_qty = [] symbols = buy_stocks['symbol'].tolist() prices = buy_stocks['close'].tolist() for i in range(0, len(symbols)): price = prices[i] qty = math.floor(funds_per_stock / price) buy_qty.append(qty) buy_stocks['qty'] = buy_qty buy_stocks['market_value'] = buy_stocks['close'] * buy_stocks['qty'] print(f'Buy {len(buy_stocks)}:') print(buy_stocks) else: print('There is no room to buy.') buy_stocks = pd.DataFrame() return (buy_stocks, sell_stocks, hold_stocks)
def select_swing_stocks(date: datetime, position_data: Dict, portfolio_amount: float): # Get Alpaca API key and secret storage_client = storage.Client() bucket = storage_client.get_bucket('derek-algo-trading-bucket') blob = bucket.blob('alpaca-api-key.txt') api_key = blob.download_as_text() blob = bucket.blob('alpaca-secret-key.txt') secret_key = blob.download_as_text() base_url = 'https://paper-api.alpaca.markets' api = REST(api_key, secret_key, base_url, 'v2') # Get all stocks assets = api.list_assets('active') symbols = [asset.symbol for asset in assets if asset.tradable] # Display currently held positions if position_data: print('Current positions:') else: print('No current positions') position_symbols = list(position_data.keys()) for symbol in position_symbols: current_price = float(position_data[symbol]['current_price']) entry_price = float(position_data[symbol]['avg_entry_price']) current_percent = (current_price - entry_price) / entry_price * 100 print('{}: {}%'.format(symbol, '%.2f' % current_percent)) # Get past 1000 days data for all stocks data = {} print(f'Retrieving {len(symbols)} symbol data...') symbols_chunked = list(chunks(list(set(symbols)), 200)) previous_day = datetime.isoformat(pd.Timestamp(date - timedelta(days=1))) for symbol_group in symbols_chunked: data_group = api.get_barset(','.join(symbol_group), '1D', end=previous_day, limit=1000).df for symbol in symbol_group: data[symbol] = data_group[symbol] buy_df = pd.DataFrame() sell_df = pd.DataFrame() hold_df = pd.DataFrame() # c = 0 print('Processing daily bars for all stocks...') for symbol in data.keys(): df = pd.DataFrame(data[symbol]) df = df.loc[df['close'] > 0] if symbol not in position_symbols and len(df) >= 1000: df['symbol'] = symbol df['bullish'] = pattern.detect_bullish_patterns(df) buy_df = buy_df.append(df.loc[df.index == df.index.max()]) elif symbol in position_symbols: df['symbol'] = symbol df['qty'] = int(position_data[symbol]['qty']) df['market_value'] = float(position_data[symbol]['market_value']) latest_rsi = rsi(df).df.tail(1)['rsi'][0] latest_cci = cci(df).df.tail(1)['cci'][0] purchase_price = float(position_data[symbol]['avg_entry_price']) latest_price = float(position_data[symbol]['current_price']) df['purchase_price'] = purchase_price df['latest_price'] = latest_price change_pct = (latest_price - purchase_price) / purchase_price * 100 print(f'\nHolding {symbol}: {round(change_pct, 2)}%') # If it has dropped below the stop loss percentage, GET IT OUT if change_pct <= -3: print(f'Price is below stop loss: SELL') sell_df = sell_df.append(df.loc[df.index == df.index.max()]) elif change_pct < 0 and (latest_rsi >= 70 or latest_cci >= 100): print(f'Overbought, RSI={round(latest_rsi, 0)}, CCI={round(latest_cci, 0)}: SELL') sell_df = sell_df.append(df.loc[df.index == df.index.max()]) # If price is at/above entry # Check if the swing is still swinging else: print(f'Price ${latest_price} is near/above entry ${purchase_price}') obv_df = obv(df).df obv_df['obv_ema'] = obv_df['obv'].ewm(span=20).mean() # Is the OBV still above it's EMA if obv_df.tail(1)['obv'][0] > obv_df.tail(1)['obv_ema'][0]: print('OBV is still above OBV_EMA') slope = linregress( [0, 1, 2], obv_df.tail(3)['obv'].tolist() ).slope if slope > 0: print(f'OBV is increasing with a slope of {slope}: HOLD') hold_df = hold_df.append(df.loc[df.index == df.index.max()]) else: print('OBV is above EMA but not increasing: SELL') sell_df = sell_df.append(df.loc[df.index == df.index.max()]) else: print('OBV is no longer above EMA: SELL') sell_df = sell_df.append(df.loc[df.index == df.index.max()]) print() # c += 1 # if c % 100 == 0: # print(f'{c}/{len(data.keys())}') # print(f'{c}/{len(data.keys())}\n') # END SCREENING SECTION # Consolidate results # hold_stocks = hold_df.loc[hold_df.index == hold_df.index.max()] # sell_stocks = sell_df.loc[sell_df.index == sell_df.index.max()] portfolio_size = 20 purchase_size = portfolio_size - len(hold_df) # If there's room in the portfolio to buy more if purchase_size > 0: print(f'We can purchase {purchase_size} new stocks today.') # buy_stocks = buy_df.loc[buy_df.index == buy_df.index.max()] buy_stocks = buy_df[buy_df['bullish'] != ''] buy_stocks = buy_stocks.sort_values(by='volume', ascending=False).head(purchase_size) holding_value = sum(hold_df['market_value'].tolist()) if not hold_df.empty else 0.0 available_funds = portfolio_amount - holding_value print(f'Available funds to buy: ${available_funds}') # For now this will create equal-weight positions funds_per_stock = available_funds / len(buy_stocks) # Calculate quantity to buy for each stock buy_qty = [] symbols = buy_stocks['symbol'].tolist() prices = buy_stocks['close'].tolist() for i in range(0, len(symbols)): price = prices[i] qty = math.floor(funds_per_stock / price) buy_qty.append(qty) buy_stocks['qty'] = buy_qty buy_stocks['market_value'] = buy_stocks['close'] * buy_stocks['qty'] else: print('There is no room to buy.') buy_stocks = pd.DataFrame() return (buy_stocks, sell_df, hold_df)
def __init__(self, account: Account, base_url: str): super().__init__() self.client = REST(key_id=account.get_access_key(), secret_key=account.get_secret_key(), base_url=URL(base_url))
def select_day_trade_stocks(event, context): # Get Alpaca API key and secret storage_client = storage.Client() bucket = storage_client.get_bucket('derek-algo-trading-bucket') blob = bucket.blob('alpaca-api-key.txt') api_key = blob.download_as_text() blob = bucket.blob('alpaca-secret-key.txt') secret_key = blob.download_as_text() base_url = 'https://paper-api.alpaca.markets' api = REST(api_key, secret_key, base_url, 'v2') # Get all stocks assets = api.list_assets('active') symbols = [asset.symbol for asset in assets if asset.tradable] # Get past 50 days data for all stocks data = {} symbols_chunked = list(chunks(list(set(symbols)), 200)) for symbol_group in symbols_chunked: print(f'Retrieving {len(symbol_group)} symbol data') data_group = api.get_barset(','.join(symbol_group), '1D', limit=50).df for symbol in symbol_group: data[symbol] = data_group[symbol] result_df = pd.DataFrame() for symbol in data.keys(): df = data[symbol] df = df.loc[df['close'] > 0] if len(df.index) >= 50: # Calculate day change percent dayChange = [] for i in df.index: try: high = df['high'][i] low = df['low'][i] if low and low > 0: dayChange.append(round(((high - low) / low) * 100, 2)) else: dayChange.append(0) except KeyError: dayChange.append(0) # Calculate averages df['dayChange'] = dayChange df['averageDayChange10'] = df['dayChange'].ewm(span=10).mean() df['averageVolume50'] = df['volume'].ewm(span=50).mean() df['averageVolume10'] = df['volume'].ewm(span=10).mean() df['symbol'] = symbol # Add most recent row i = len(df.index) - 1 result_df = result_df.append(df.iloc[i]) # Filter stocks by high volatility criteria filtered_df = result_df.query( 'averageDayChange10>4.5 & averageVolume50>4000000 & averageVolume10>4000000 & close>=5' ) # Sort descending by averageDayChange10 sorted_df = filtered_df.sort_values('averageDayChange10', ascending=False) # Grab top 5 stocks selected_stocks = sorted_df[:5] print(selected_stocks) symbols = list(selected_stocks['symbol'].values) print(symbols) # Store them in Alpaca watchlist watchlist = api.get_watchlist_by_name('day-trade-stocks') api.update_watchlist(watchlist.id, symbols=symbols) print('Success')
def get_actions_alpaca(symbol): api = REST(alpaca_keys.APCA_API_KEY_ID, alpaca_keys.APCA_API_SECRET_KEY) dividend_data = api.polygon.dividends(symbol) split_data = api.polygon.splits(symbol) return create_dict_actions(dividend_data, split_data)