You've successfully subscribed to Alpaca Learn | Developer-First API for Crypto and Stocks
Great! Next, complete checkout for full access to Alpaca Learn | Developer-First API for Crypto and Stocks
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.
Billing info update failed.
Search
Algorithmic Trading Basics

PythonAnywhere to Run a Simple Trading Algorithm

Alpaca Team
Alpaca Team

Using PythonAnywhere When Running an Algorithm Live in the Cloud

After first getting into quant trading and writing algos on your local machine, the biggest area of resistance for newbie quant traders is running an algorithm live in the cloud.

This is a code snippet for a sample trading algorithm that we use for this post.

Alpaca Sample Algo - 5 Minute EMA Crossover
Alpaca Sample Algo - 5 Minute EMA Crossover. GitHub Gist: instantly share code, notes, and snippets.

There are many cloud services on the market, including AWS, Google Cloud, Heroku, Digital Ocean, and PythonAnywhere. This walkthrough focuses on setting up PythonAnywhere and running a sample algorithm in Python and the Alpaca Trade API.

Host, run, and code Python in the cloud: PythonAnywhere
Host, run, and code Python in the cloud: PythonAnywhere
Documentation | Alpaca
Alpaca API lets you build and trade with real-time market data for free.

PythonAnywhere has a free tier of accounts, but only with access to whitelisted URLs. To access the Alpaca endpoints, you will need a paid account ($5/month).

PythonAnywhere is a nice option because it gives you some manner of GUI for accessing consoles, files, notebooks, and even scheduling tasks that automatically restart if they go down (excellent for algo trading).

Let’s jump in with a fresh account.

Step 1.) Setting up PythonAnywhere.

Step A.) Make a new PythonAnywhere account.

https://www.pythonanywhere.com/

You’re welcomed with a dashboard like below.

Step B.) Install alpaca-trade-api.

Under “Consoles”, open a new Bash console.

Run the following:

pip3 install --user alpaca-trade-api

Step 2.) Set up algo.

Our sample algo for this walkthrough is a simple 5/20 period ema (exponential moving average) crossover on the 5-minute timeframe, checking every 1 minute for signals.

import alpaca_trade_api as tradeapi
import time
import datetime
from datetime import timedelta
from pytz import timezone
tz = timezone('EST')

api = tradeapi.REST('your key',
                    'your secret',
                    'https://paper-api.alpaca.markets')

import logging
logging.basicConfig(filename='./new_5min_ema.log', format='%(name)s - %(levelname)s - %(message)s')
logging.warning('{} logging started'.format(datetime.datetime.now().strftime("%x %X")))

def get_data_bars(symbols, rate, slow, fast):
    data = api.get_barset(symbols, rate, limit=20).df
    for x in symbols:
        data.loc[:, (x, 'fast_ema')] = data[x]['close'].rolling(window=fast).mean()
        data.loc[:, (x, 'slow_ema')] = data[x]['close'].rolling(window=slow).mean()
    return data

def get_signal_bars(symbol_list, rate, ema_slow, ema_fast):
    data = get_data_bars(symbol_list, rate, ema_slow, ema_fast)
    signals = {}
    for x in symbol_list:
        if data[x].iloc[-1]['fast_ema'] > data[x].iloc[-1]['slow_ema']: signal = 1
        else: signal = 0
        signals[x] = signal
    return signals

def time_to_open(current_time):
    if current_time.weekday() <= 4:
        d = (current_time + timedelta(days=1)).date()
    else:
        days_to_mon = 0 - current_time.weekday() + 7
        d = (current_time + timedelta(days=days_to_mon)).date()
    next_day = datetime.datetime.combine(d, datetime.time(9, 30, tzinfo=tz))
    seconds = (next_day - current_time).total_seconds()
    return seconds

def run_checker(stocklist):
    print('run_checker started')
    while True:
        # Check if Monday-Friday
        if datetime.datetime.now(tz).weekday() >= 0 and datetime.datetime.now(tz).weekday() <= 4:
            # Checks market is open
            print('Trading day')
            if datetime.datetime.now(tz).time() > datetime.time(9, 30) and datetime.datetime.now(tz).time() <= datetime.time(15, 30):
                signals = get_signal_bars(stocklist, '5Min', 20, 5)
                for signal in signals:
                    if signals[signal] == 1:
                        if signal not in [x.symbol for x in api.list_positions()]:
                            logging.warning('{} {} - {}'.format(datetime.datetime.now(tz).strftime("%x %X"), signal, signals[signal]))
                            api.submit_order(signal, 1, 'buy', 'market', 'day')
                            # print(datetime.datetime.now(tz).strftime("%x %X"), 'buying', signals[signal], signal)
                    else:
                        try:
                            api.submit_order(signal, 1, 'sell', 'market', 'day')
                            logging.warning('{} {} - {}'.format(datetime.datetime.now(tz).strftime("%x %X"), signal, signals[signal]))
                        except Exception as e:
                            # print('No sell', signal, e)
                            pass

                time.sleep(60)
            else:
                # Get time amount until open, sleep that amount
                print('Market closed ({})'.format(datetime.datetime.now(tz)))
                print('Sleeping', round(time_to_open(datetime.datetime.now(tz))/60/60, 2), 'hours')
                time.sleep(time_to_open(datetime.datetime.now(tz)))
        else:
            # If not trading day, find out how much until open, sleep that amount
            print('Market closed ({})'.format(datetime.datetime.now(tz)))
            print('Sleeping', round(time_to_open(datetime.datetime.now(tz))/60/60, 2), 'hours')
            time.sleep(time_to_open(datetime.datetime.now(tz)))

stocks = ['AA','AAL','AAPL','AIG','AMAT','AMC','AMD','AMGN','AMZN','APA','BA','BABA','BAC','BBY','BIDU','BP','C','CAT','CMG',]

run_checker(stocks)

Upload the algo as a file, or go to “Open another file” on the dashboard.

Enter it as /home/yourusername/algoname.py

You can run this right from the terminal editor, and see if it works. If you’re missing any dependencies, install them in the Bash console.

If the algo runs, you can leave it up and check results in the log file.

Step 3.) Set as task.

Go to “Tasks”, and go down to “Always On Tasks”.

You can schedule your algo to automatically restart if it crashes by entering “python3.6 /home/yourusername/algoname.py”.

This works especially well with our sample algo, which dynamically finds the amount of time to sleep until next market open.

Checking our Alpaca account, using the below as an example, we can see it’s generating signals about every minute:

Please note that this example is for illustrative purposes only. Past performance is not indicative of future results.


Technology and services are offered by AlpacaDB, Inc. Brokerage services are provided by Alpaca Securities LLC (alpaca.markets), member FINRA/SIPC. Alpaca Securities LLC is a wholly-owned subsidiary of AlpacaDB, Inc.

You can find us @AlpacaHQ, if you use twitter.

Algorithmic Trading BasicsUse CasesPython

Alpaca Team

API-first stock brokerage. *Securities are offered through Alpaca Securities LLC* http://alpaca.markets/#disclosures