Algorithmic Trading

Here is a simple python script that can be built further for algorithmic trading. You will need to get an API key from Alpha Advantage or similar service to get the quotes.

To make the trades, you will need to link the script to a trading API from TDAmeritrade or your favorite broker who has an API. This part of the script is not included here.

The algorithm shown is a very simple one. Basically, buy the stock and then wait till the price is [1]% more than the purchase price. and then sell. Wait of [nn] minutes. Repeat.

You can program more complex strategies by building upon this mechanism.

def stock_price(stk='QQQ',end_hr=16, end_min=00, after_sell_minutes=0):
    import urllib
    import urllib2
    import time
    import re
    import json
    import os
    import sys
    import datetime
    import random

    # Get API key from Alpha Vantage
    st_sym = stk
    st_ind = 'nyse'
    run_time_min = 30
    run_time_int = 1    # default wait time in seconds for next check 
    
    cash_bal = 10000.0
    wig = 5.0
    
    url_prefix = "https://www.alphavantage.co/query?function=BATCH_STOCK_QUOTES&symbols="
    
    url_symbols = st_sym.upper()
    url_postfix = "&apikey=__YOUR API KEY__"

    url_to_query = url_prefix + url_symbols + url_postfix
    print '' + 'Query made: ' + url_to_query + ''

    response = urllib2.urlopen(url_to_query)
    headers = response.info()
    data = response.read()

    # do a loop for nnn minutes
    run_loops = int(run_time_min * 60 / run_time_int)
    t_h = datetime.datetime.now().hour
    t_m = datetime.datetime.now().minute
    
    min_price = 0.
    max_price = 0.
    
    loopcount = 0
   
    print "Run till %d:%d"%(end_hr,end_min)
    print 'Run  | SYM  | Time     | Price   | Act  | Shares | Cash | Portfolio' 
    print '--------------------------------------------------------------' 
    
    while (t_h <= end_hr) & (t_m <= end_min):
        urlreq = urllib2.Request(url_to_query)
        try:
            response = urllib2.urlopen(urlreq)   #open the link to get the data
            data = response.read()
            response.close()   #this closes the open URL link
            # convert the data to dict.
            decoded_data = json.loads(data)
            # for k,v in decoded_data.items(): print k,v
            
            sq1 = decoded_data['Stock Quotes']
            sq2 = sq1[0]
            sq2s = sq2['1. symbol']
            sq2t = sq2['4. timestamp'][11:]
            sq2v = int(sq2['3. volume'])
            sq2p = float(sq2['2. price'])
            
            all_well = True
        except:
            all_well = False

        if all_well:            
            # see if this is a buy opport or sell.
            act_now = "HOLD"
            random_wait = 0
            show_res = False
            if cash_bal > 5000:
                buy_shr = int((cash_bal - wig) / sq2p) - 1
                cash_bal = cash_bal - (buy_shr * sq2p + wig)
                buy_price = sq2p
                shr_owned = buy_shr
                act_now = "BUY"
                # FUNCTION BUY_STOCK() --- not included in this script
                show_res = True
            else:
                # see if this is sell situation
                if sq2p > buy_price * 1.01:
                    sell_shr = shr_owned
                    sell_price = sq2p
                    cash_bal = cash_bal + (sell_price * sell_shr - wig)
                    shr_owned = shr_owned - sell_shr
                    act_now = "SELL"
                    # FUNCTION SELL_STOCK() --- not included in this script
                    show_res = True
                    # estimate the random wait time for next trade.
                    r1 = int(after_sell_minutes * 60 * 0.9)
                    r2 = int(after_sell_minutes * 60 * 1.1)
                    random_wait = random.randrange(r1,r2)
                else:
                    pass
            
            port_val = cash_bal + shr_owned * sq2p
            
            # update the min and max price
            if min_price == 0.: min_price = sq2p
            if max_price == 0.: max_price = sq2p
            
            if sq2p < min_price: min_price = sq2p
            if sq2p > max_price: max_price = sq2p           
            
            t_s = datetime.datetime.now().second
            if t_s % 10 == 0: show_res = True

            # only show results every 10 secs or when there is buy or sell
            if show_res: print "%4d | %4s | %s | %7.3f | %4s | %.1f | %.1f | %.1f" %(loopcount, sq2s, sq2t, sq2p, act_now, shr_owned, cash_bal, port_val)
            
            sys.stdout.flush()  #make sure that the data is written out before sleep
        else:
            pass
            
        # ----- now to sleep ------
        t_h = datetime.datetime.now().hour
        t_m = datetime.datetime.now().minute
        loopcount = loopcount + 1
        #now go to sleep - use a random element 
        # that is prespefied based on whether there was a sale or not.
        time.sleep(run_time_int + random_wait)        

    # write summary.
    print 'Process end: %s'%time.ctime()
    print 'Min price: %.2f'%min_price
    print 'Max price: %.2f'%max_price
    print 'Min Max Range: %.1f%%'%((max_price/min_price-1)*100)
    print 'End Portfolio Value: %.1f'%port_val