Exemple #1
0
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
Exemple #3
0
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
Exemple #5
0
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)
Exemple #7
0
 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))
Exemple #8
0
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')
Exemple #9
0
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)