Example #1
0
    def take_and_stop(self, symbol):


        last_quote_url = self.quote_url + symbol

        r = requests.get(last_quote_url,
                        headers=self.headers,
                        timeout=5)
        
        debug_logger.debug("""API called by take_and_stop() for '{}'""".format(symbol))

        quote = json.loads(r.content)
        bid = quote['last']['bidprice']
        ask = quote['last']['askprice']

        take_profit = {
                       'limit_price': str((bid / 100) * 130)
                       }
        
        stop_loss = {
                    'stop_price': str(round((ask / 100) * 90, 2)),
                    'limit_price': str(round((ask / 100) * 88, 2))
                    }
        
        return take_profit, stop_loss
Example #2
0
def get_all_yahoo_watchlist_symbols(url_list):
    """
    From a list of watchlist urls, retrieve symbols for potential stocks
    according to basic criteria
    """
    global yahoo_home_url
    
    watchlist_symbols = set()
    stocks_analyzed = 0

    for url in url_list:

        debug_logger.debug("Analyzing '{}'".format(url))
        
        watchlist_url = yahoo_home_url + url
        watchlist_r = requests.get(watchlist_url).text
        watchlist_soup = BeautifulSoup(watchlist_r, 'lxml')
        watchlist_table = watchlist_soup.find(class_='cwl-symbols').tbody.contents

        for row in watchlist_table:

            filter_stocks(watchlist_symbols, row)
            stocks_analyzed += 1

        sleep(0.2)

    debug_logger.debug("A Total of {} stocks analyzed".format(stocks_analyzed))

    return watchlist_symbols
Example #3
0
    def place_order(self, symbol, side, qty, type='stop_limit', 
                    time_in_force='gtc', order_class='bracket'):

        params = {
            'symbol': symbol,
            'side': side,
            'qty': str(qty),
            'type': type,
            'time_in_force': time_in_force,
            'order_class': order_class,
            'take_profit': self.take_and_stop(symbol)[0],
            'stop_loss': self.take_and_stop(symbol)[1]
            }
        
        if self.is_tradable(symbol):
            
            try:
                r = requests.post(self.orders_url,
                                  params=params,
                                  headers=self.headers,
                                  timeout=5)
            except HTTPError:
                return False

        debug_logger.debug("""API called to place order for '{}'""".format(symbol))

        return True
Example #4
0
    def get_tactical_data(self):
        """
        - Get data for the second timeframe
        - Calculate stochastic values for the given time windows
        - Return last 20 rows
        """

        if self.tactical_timeframe == '60Min':

            data = self.get_data('15Min', limit=0)
            data_resampled = self.alpaca_data_resample(data)
            tactical = self.get_stochastic(data_resampled)
            debug_logger.debug("Calculated Stochastic for '{}'".format(
                self.symbol))

            return tactical.iloc[-20:]

        else:

            data = self.get_data(self.tactical_timeframe, limit=0)
            tactical = self.get_stochastic(data)
            debug_logger.debug("Calculated Stochastic for '{}'".format(
                self.symbol))

            return tactical.iloc[-20:]
Example #5
0
    def get_tactical_potential(self):

        self.potential = 0  # Initialize potential signal

        tactical_data = self.get_tactical_data()

        debug_logger.debug("get_tactical_data() called for '{}'".format(
            self.symbol))

        last_k = tactical_data['k'].iloc[-1]
        last_d = tactical_data['d'].iloc[-1]

        stock_logger.info("'{}' Last K: {}".format(self.symbol, last_k))
        stock_logger.info("'{}' Last D: {}".format(self.symbol, last_d))

        if self.is_in_range(last_k, last_d):

            # Weak buy signal
            self.potential = 1

            if last_k >= last_d:
                # Strong buy signal
                self.potential = 2

        stock_logger.info("'{}' potential is now: {}".format(
            self.symbol, self.potential))
Example #6
0
def filter_stocks(symbol_set, row):
    """
    RULES OUT:
    - stocks already in list
    - penny stocks
    - too expensive stocks
    - stocks with negative change
    
    Also, double checks for Crypto symbols (separated by '-')
    """
    
    stock = {}

    stock['symbol'] = row.find('a')['title']


    if '-' not in stock['symbol']:
        
        try:
            stock['price'] = float(row.find(class_='data-col2').text)
            stock['change'] = float(row.find(class_='data-col3').span.text)
        except (ValueError, AttributeError):
            pass
        else:
            if (20 < stock['price'] < 800 and
                stock['change'] > 0.5):
                
                symbol_set.add(stock['symbol'])
                debug_logger.debug("Added '{}' to watchlist".format(stock['symbol']))

    return symbol_set
Example #7
0
    def close_position(self, symbol):

        params = {
            'symbol': symbol,
            }

        r = requests.delete(positions_url,
                            params=params,
                            headers=self.headers,
                            timeout=5)

        debug_logger.debug("""API called to close position for '{}'""".format(symbol))
Example #8
0
    def get_watchlist_symbols(self):
            
        r = requests.get(self.watchlist_url,
                        headers=self.headers,
                        timeout=5)
        
        debug_logger.debug("API called for watchlist")
        
        watchlist = json.loads(r.content)

        watchlist_symbols = {asset['symbol'] for asset in watchlist['assets']}
        
        return watchlist_symbols
Example #9
0
def yahoo_watchlist():

    global yahoo_home_url

    top_gainers_url = yahoo_home_url + '/watchlists/category/section-gainers'

                    
    url_list = get_yahoo_watchlist_urls(top_gainers_url)
    symbol_set = get_all_yahoo_watchlist_symbols(url_list)

    debug_logger.debug("A total of {} stocks added to watchlist".format(len(symbol_set)))

    return symbol_set
Example #10
0
    def get_positions_symbols(self):

        r = requests.get(self.positions_url,
                headers=self.headers,
                timeout=5)
        
        debug_logger.debug("API called for positions")
        
        positions = json.loads(r.content)

        positions_symbols = {asset['symbol'] for asset in positions['assets']}
        
        return positions_symbols
Example #11
0
    def get_open_position(self):

        url = 'https://paper-api.alpaca.markets/v2/positions'

        params = {
            'symbol': self.symbol,
        }

        r = requests.get(url, params=params, headers=self.headers, timeout=5)

        debug_logger.debug("API called for positions")

        position = json.loads(r.content)

        position['cost_basis'] = float(position['cost_basis'])
        position['unrealized_plpc'] = float(position['unrealized_plpc'])

        return position
Example #12
0
    def is_tradable(self, symbol):

        
        asset_url = self.assets_url + symbol
        
        r = requests.get(asset_url,
                        headers=self.headers,
                        timeout=5)
        
        debug_logger.debug("""API called by is_tradable() for '{}'""".format(symbol))
        
        asset = json.loads(r.content)

        if (asset['status'] == 'active' and
            asset['tradable'] == True):

            return True
        
        else:
            return False
Example #13
0
def initialize_data():
    """    
    Create a dict of:
        
        - initial set of Stock objects from:
            - Manually created Alpaca watchlist            
            - Automatic selection of stocks from Yahoo Finance watchlists        
        
        - 3 empty sets to be populated by stocks that:
            - show strong potential after trend scan
            - show weak potential after tactical scan
            - show strong potential after tactical scan, are ready to buy
        
        - a set of dictionaries containing information on open positions
        
        - a list of completed trades to be saved and later analized
    """

    trades = {}
    trades[datetime.now().strftime('%Y-%m-%d')] = set()

    a = Alpaca()
    watchlist = a.get_watchlist_symbols()
    watchlist.update(yahoo_watchlist())

    stock_logger.info("Initialized watchlist with '{}' symbols".format(
        len(watchlist)))

    stocks = {
        'initial': {Stock(symbol)
                    for symbol in watchlist},
        'potential': set(),
        'standby': set(),
        'buy': set(),
        'bought': record.get_open_positions(),
        'trades': trades
    }

    debug_logger.debug("Created stocks dictionary")

    return stocks
Example #14
0
    def get_execution_potential(self):

        self.potential = 0  # Initialize potential signal

        execution_data = self.get_execution_data()

        debug_logger.debug("get_execution_data() called for '{}'".format(
            self.symbol))

        last_three_highs = execution_data['high'].iloc[-3:].values

        stock_logger.info("'{}' Last 3 highs: {}".format(
            self.symbol, last_three_highs))

        if self.is_trending_up(last_three_highs):

            # Strong buy signal
            self.potential = 2

        stock_logger.info("'{}' potential is now: {}".format(
            self.symbol, self.potential))
Example #15
0
    def get_trend_potential(self):

        trend_data = self.get_trend_data()

        debug_logger.debug("get_trend_data() called for '{}'".format(
            self.symbol))

        last_month_smas = trend_data['sma50'].iloc[-30:].values
        last_lows = trend_data['low'].iloc[-6:].values
        last_low = trend_data['low'].iloc[-1]
        last_sma = trend_data['sma50'].iloc[-1]

        if (trend_data['close'].ge(trend_data['sma50']).all()
                and self.is_trending_up(last_month_smas, step=10)
                and not self.is_trending_up(last_lows)
                and self.is_in_range(last_low, last_sma)):

            self.potential = 2

        stock_logger.info("'{}' potential is now: {}".format(
            self.symbol, self.potential))
Example #16
0
def standby_scan(stocks, lock, sleep_time=120):
    """
    Re-scan the tactical timeframe for stocks that showed weak potential
    """

    while market_open():

        lock.acquire()
        debug_logger.debug("Lock acquired by standby_scan()")

        for stock in stocks['standby']:

            if not stock.open:

                stock.get_tactical_potential()

                debug_logger.debug(
                    "get_tactical_potential() called for '{}'".format(
                        stock.symbol))

                if stock.potential == 2:
                    stocks['buy'].add(stock)

            sleep(1)

        lock.release()
        debug_logger.debug("Lock released by standby_scan()")

        stock_logger.info("{} have potential after standby scan".format(
            len(stocks['buy'])))

        sleep(sleep_time)
Example #17
0
def trend_scan(stocks, lock, sleep_time=1800):
    """
    Scan the trend data timeframe for potential, then populate the 
    potential stocks set and discard the stock if it shows no potential
    """

    while market_open():

        lock.acquire()
        debug_logger.debug("Lock acquired by trend_scan()")

        for stock in stocks['initial']:

            if not stock.open:

                stock.get_trend_potential()

                debug_logger.debug(
                    "get_trend_potential() called for '{}'".format(
                        stock.symbol))

                if stock.potential == 2:
                    stocks['potential'].add(stock)

                sleep(0.2)

        lock.release()
        debug_logger.debug("Lock released by trend_scan()")

        stock_logger.info("{} stocks have potential after trend scan".format(
            len(stocks['potential'])))

        sleep(sleep_time)
Example #18
0
def execute_scan(stocks, lock, sleep_time=60):
    """
    - Scan price action to find the optimal moment for placing BUY order
    - Place order
    - Create dictionary with information on the position
    """

    while market_open():

        lock.acquire()
        debug_logger.debug("Lock acquired by execute_scan()")

        for stock in stocks['buy']:

            if not stock.open:

                stock.get_execution_potential()

                debug_logger.debug(
                    "get_execution_potential() called for '{}'".format(
                        stock.symbol))

                if stock.potential == 2:

                    a = Alpaca()
                    # TO-DO! Add functionality to calculate optimal position?
                    # Temporarily, an arbitrary amount of 10 shares is established
                    if a.place_order(stock.symbol, 'buy', 10):

                        stock.open_position()
                        stocks['bought'].add(stock)
                        stock_logger.info(
                            "Placed order of 10 stocks of '{}'".format(
                                stock.symbol))

                    else:
                        continue

                sleep(2)

        lock.release()
        debug_logger.debug("Lock released by execute_scan()")

        stock_logger.info("Stocks of {} symbol were bought".format(
            len(stocks['bought'])))

        sleep(sleep_time)
Example #19
0
def tactical_scan(stocks, lock, sleep_time=600):
    """
    Scan the tactical timeframe data of each stock for potential,
    discard the stock if it shows no potential, then populate the
    standby set or buy set
    """

    while market_open():

        lock.acquire()
        debug_logger.debug("Lock acquired by tactical_scan()")

        for stock in stocks['potential']:

            if not stock.open:

                stock.get_tactical_potential()

                debug_logger.debug(
                    "get_tactical_potential() called for '{}'".format(
                        stock.symbol))

                if stock.potential == 2:
                    stocks['buy'].add(stock)

                elif stock.potential == 1:
                    stocks['standby'].add(stock)

            sleep(1)

        lock.release()
        debug_logger.debug("Lock released by tactical_scan()")

        stock_logger.info(
            "{} stocks have potential after tactical scan".format(
                len(stocks['buy'])))
        stock_logger.info(
            "{} stocks remain in standby after tactical scan".format(
                len(stocks['standby'])))

        sleep(sleep_time)
Example #20
0
def sell_scan(stocks, lock, sleep_time=300):
    """
    Scans open position's unrealized profit for optimal sell signal
    """

    while market_open():

        lock.acquire()
        debug_logger.debug("Lock acquired by sell_scan()")

        for stock in stocks['bought']:

            stock.get_sell_signal()
            debug_logger.debug("get_sell_signal() called for '{}'".format(
                stock.symbol))

            if stock.sell:

                a = Alpaca()
                a.close_position(stock.symbol)
                stock.close_position()

                stock_logger.info(
                    "Closed position of 10 stocks of '{}'".format(
                        stock.symbol))
                stocks['trades'].add(stock.position_record)

            else:
                continue

            sleep(2)

        lock.release()
        debug_logger.debug("Lock released by sell_scan()")

        stock_logger.info("{} stocks were sold".format(len(stocks['trades'])))

        sleep(sleep_time)

    record.store_new_trades(stocks['trades'])