Esempio n. 1
0
def maybe_invest(api: tradeapi.REST) -> None:
    target_symbols = ['AAPL', 'VOO']
    user_context = UserContext()
    user_context.set_account(api.get_account())
    stock_context_list = [
        StockContext(target_symbol) for target_symbol in target_symbols
    ]
    # Populate stock context list for potential investment.
    for stock_context in stock_context_list:
        last_trade = api.get_last_trade(stock_context.symbol)
        stock_context.set_last_trade(last_trade)
    # Filter out a list of stocks that should be considered
    # for investment at the moment.
    stock_feasibility_checker = StockFeasibilityChecker(user_context)
    filtered_stock_context_list = filter(stock_feasibility_checker,
                                         stock_context_list)
    # Rank the potential list of stocks to invest based on
    # the potential growth.
    stock_comparator = StockComparator(user_context)
    ranked_stock_context_list = sorted(filtered_stock_context_list,
                                       key=stock_comparator)
    # Send order to invest if fund is sufficient
    stock_action_executor = StockActionExecutor(user_context)
    for ranked_stock_context in ranked_stock_context_list:
        stock_action_executor(ranked_stock_context)
    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
Esempio n. 3
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)
class AlpacaAccount:
    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

    def get_api(self):
        return self.api

    def list_assets(self,
                    shortable=False,
                    fractionable=False,
                    show_names=False):
        active_assets = self.api.list_assets(status='active')
        myfilter = []
        if shortable and fractionable:
            for asset in active_assets:
                if asset.easy_to_borrow and asset.marginable and asset.fractionable:
                    myfilter.append(asset)

        elif shortable:
            for asset in active_assets:
                if asset.easy_to_borrow and asset.marginable:
                    myfilter.append(asset)

        elif fractionable:
            for asset in active_assets:
                if asset.fractionable:
                    myfilter.append(asset)

        else:
            myfilter = active_assets

        if show_names:
            return [f"{i.name} :: '{i.symbol}'" for i in myfilter]
        else:
            return [i.symbol for i in myfilter]
Esempio n. 5
0
class TickerFilter:
    def __init__(self, key, secret):
        self.api = Alpaca(key, secret, 'https://paper-api.alpaca.markets')
        self.cached_tickers = {}

    def ticker_exists(self, ticker):
        try:
            if ticker in self.cached_tickers:
                return self.cached_tickers[ticker]
            asset = self.api.get_asset(ticker)
            self.cached_tickers[ticker] = asset.tradable
            return asset.tradable
        except:
            self.cached_tickers[ticker] = False
            return False

    def filter_pass(self, comment):
        words = alnum.sub('', comment).split()
        tickers = [word for word in words if word.isupper() and len(word) in RedditSentimentSource._VALID_TICKER_LENGTHS]
        for word in words:
            if self.ticker_exists(word):
                return True
        return False
Esempio n. 6
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))
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)
Esempio n. 8
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)
from datetime import datetime
from google.cloud import storage
import pandas as pd
pd.set_option('mode.chained_assignment', None)
from alpaca_trade_api import REST
from select_historic_swing_stocks import 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')

nyc = timezone('America/New_York')


def get_open_price(date: datetime, symbol: Text):
    today = datetime.isoformat(pd.Timestamp(date))
    bar = api.get_barset(symbol, '1D', start=today, end=today, limit=1).df
    return bar[symbol]['open'][bar.index.max()]


def buy_stock(date: datetime, symbol: Text, qty: int):
    buy_price = get_open_price(date, symbol)
    position_data[symbol] = {
        'qty': str(qty),
        'avg_entry_price': str(buy_price),
Esempio n. 10
0
def all_alpaca_assets(client: alpaca_trade_api.REST) -> list:
    return [_.symbol for _ in client.list_assets()]
Esempio n. 11
0
 def __init__(self, key, secret):
     self.api = Alpaca(key, secret, 'https://paper-api.alpaca.markets')
     self.cached_tickers = {}
Esempio n. 12
0
import time
from google.cloud import storage
import pandas as pd
pd.set_option('mode.chained_assignment', None)
from alpaca_trade_api import REST
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')

positions = api.list_positions()

alert = '**End of Week Liquidations**\n\n**Sell**\n'

# Market sell every position
for position in positions:
    symbol = position.symbol
    qty = position.qty
    price = position.current_price
    api.submit_order(
        symbol=symbol, qty=str(qty), side='sell',
        type='limit', limit_price=str(price), time_in_force='day'
    )
    alert += f'{symbol}: {qty}\n'
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
Esempio n. 14
0
from google.cloud import storage
import pandas as pd
pd.set_option('mode.chained_assignment', None)
from alpaca_trade_api import REST
import discord_webhook
import statistics as stats

# 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')

# Retrieve all trade activities for the week
today = datetime.today()
monday = today - timedelta(days=4)
today_str = f'{today.date()}T23:59:59Z'
monday_str = f'{monday.date()}T00:00:00Z'
print(f'Results from {monday_str} to {today_str}')
activities = api.get_activities(activity_types='FILL',
                                after=monday_str,
                                until=today_str)

# Retrieve all currently owned symbols
positions = api.list_positions()
owned_symbols = [position.symbol for position in positions]
Esempio n. 15
0
class AlpacaExchange(Exchange):
    client: REST

    access_key: str
    secret_key: str

    @staticmethod
    def build(account: Account, is_paper=False):
        base_url_live = "https://api.alpaca.markets"
        base_url_paper = "https://paper-api.alpaca.markets"

        return AlpacaExchange(
            account=account,
            base_url=base_url_paper if is_paper else base_url_live)

    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 get_day_candles(self, ticker: str, start: str,
                        end: str) -> List[Candle]:
        pass

    def get_last_candle(self, ticker: str) -> Candle:
        snapshot = self.client.get_snapshot(symbol=ticker)
        return BarAdapter(ticker=ticker, bar=snapshot.minute_bar)

    def get_all_assets(self) -> List[Asset]:
        account = self.client.get_account()
        positions = self.client.list_positions()

        cash = AccountAdapter(account.__dict__.get('_raw'))
        stocks = [
            PositionAdapter(position.__dict__.get('_raw'))
            for position in positions
        ]
        return [cash, *stocks]

    def buy(self, ticker: str, amount: Decimal) -> Optional[Order]:
        return self.__order(side="buy", ticker=ticker, amount=amount)

    def sell(self, ticker: str, volume: Decimal) -> Optional[Order]:
        return self.__order(side="sell", ticker=ticker, volume=volume)

    def get_order(self, order_id: str) -> Optional[Order]:
        order = self.client.get_order_by_client_order_id(
            client_order_id=order_id)
        return OrderAdapter(AlpacaOrder(**order.__dict__.get("_raw")))

    def __order(self,
                side: str,
                ticker: str,
                amount: Decimal = None,
                volume: Decimal = None) -> Optional[Order]:
        if amount is None and volume is None:
            raise ValueError("order amount or volume should not be None")

        if not self.__is_open_now():
            return None

        custom_order_id = str(uuid.uuid4())
        qty = float(volume) if volume is not None else None
        notional = float(amount) if amount is not None else None

        order = self.client.submit_order(symbol=ticker,
                                         qty=qty,
                                         notional=notional,
                                         side=side,
                                         type="market",
                                         client_order_id=custom_order_id)
        return OrderAdapter(AlpacaOrder(**order.__dict__.get("_raw")))

    def __is_open_now(self):
        """check if US exchanges (NYSE, NASDAQ, etc) are open
		09:30 (EST) ~ 16:00 (EST)
		"""
        clock = self.client.get_clock()
        return clock.is_open
Esempio n. 16
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')
Esempio n. 17
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)
from datetime import datetime, timedelta
from time import time
from typing import Dict
from btalib.indicators.cci import cci
from btalib.indicators.obv import obv
from btalib.indicators.rsi import rsi
from google.cloud import storage
import math
import pandas as pd

pd.set_option('mode.chained_assignment', None)
from alpaca_trade_api import REST
from scipy.stats import linregress
import detect_pattern as pattern

# 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')

bars = api.get_barset('AAPL', '1D', 5)['AAPL']

print(bars)
Esempio n. 19
0
class AlpacaTradeInterface(TradeInterface):
    def __init__(self, key, secret, endpoint):
        self.api = Alpaca(key, secret, endpoint)
        self.pending_orders = {}
        self.cached_tickers = {}

    def initialize(self, env: Environment):
        try:
            # Load cash balance
            account = self.api.get_account()
            env.get_portfolio().cash = float(
                account.cash)  # We have margin but shouldn't use it

            # Load open orders
            orders = self.api.list_orders(status='open', limit=500)
            self.pending_orders = {
                order.id: Order(order.symbol,
                                OrderType(order.order_type),
                                order.qty,
                                order.side == 'buy',
                                order_id=order.id,
                                limit_price=order.limit_price,
                                stop_price=order.stop_price)
                for order in orders
            }

            # Load open positions
            positions = self.api.list_positions()
            for pos in positions:
                env.get_portfolio()._add_position(
                    Position(pos.symbol, pos.qty, pos.avg_entry_price,
                             pos.current_price))

        except Exception:
            logger.exception('Failed to pull current orders and cash balance')
            return False
        return True

    def update(self, env: Environment):
        orders = self.api.list_orders(status='closed',
                                      after=datetime.now() - timedelta(days=2),
                                      limit=500)
        for order in orders:
            if order.id in self.pending_orders:
                logger.info(f'Order {order.id} executed')
                env.notify_order_completed(
                    ExecutedOrder(order.symbol, order.filled_qty,
                                  order.filled_avg_price, order.side == 'buy'))

    def place_order(self, order: Order):
        logger.info(f'Placing order for {order.quantity} {order.ticker}')
        try:
            result = self.api.submit_order(order.ticker,
                                           order.quantity,
                                           'buy' if order.is_buy else 'sell',
                                           order.order_type.value,
                                           'day',
                                           limit_price=order.limit_price,
                                           stop_price=order.stop_price)
            order.order_id = result.id
            self.pending_orders[result.id] = order
            return True

        except Exception:
            logger.exception(
                f'Failed to place order for {order.quantity} {order.ticker}')
            return False

    def cancel_order(self, order_id):
        logger.info(f'Canceling order {order_id}')
        try:
            self.api.cancel_order(order_id)
            self.pending_orders.pop(order_id, None)
            return True
        except Exception:
            logger.exception(f'Failed to cancel order {order_id}')
            return False

    def market_open(self):
        clock = self.api.get_clock()
        return clock.is_open  # TODO - we also have open/close times. May want to avoid holding overnight

    def open_orders(self):
        return [order for order in self.pending_orders.values()]

    def ticker_exists(self, ticker):
        try:
            if ticker in self.cached_tickers:
                return self.cached_tickers[ticker]
            asset = self.api.get_asset(ticker)
            self.cached_tickers[ticker] = asset.tradable
            return asset.tradable
        except:
            self.cached_tickers[ticker] = False
            return False
Esempio n. 20
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))
Esempio n. 21
0
 def __init__(self, key, secret, endpoint):
     self.api = Alpaca(key, secret, endpoint)
     self.pending_orders = {}
     self.cached_tickers = {}