Alpaca Trading API Guide – A Step-by-step Guide – AlgoTrading101 Blog

last Updated on February 28, 2021
Alpaca Trading Homepage Image Alpaca’s Homepage
Table of Contents

What is the Alpaca Trading API?

It is an interface that allows you to trade automatically with the stock certificate broke Alpaca .
More specifically, the trade API allows you to send orders directly to Alpaca ’ s servers to automate the procedure of trade, bypassing a traditional customer .

Why should I use the Alpaca Trading API?

There are several reasons you might want to use Alpaca ’ s trading API. A park use is to build an automatize trade system. But many people have used it for early purposes arsenic well such as creating a trading dashboard or a custom client app .
The chief drawing card to Alpaca is that it doesn ’ triiodothyronine charge commissions on trades. Have a look at our Alpaca Stock Brokerage Review where we discuss the pros and cons of the agent and outline how they actually make money .

Does the Alpaca API allow backtesting?

Alpaca ’ s trading API does not come with backtesting functionalities. however, they have created an consolidation with a backtesting library called Backtrader .
You can learn more about backtesting with Backtrader here : Backtrader for Backtesting ( Python ) – A Complete Guide

How do I get started with the Alpaca API?

  1. Create an account with Alpaca – You can either sign up for a live account or a paper trading account to get started. Navigate to the Alpaca home page – https://alpaca.markets/ and click on Sign up. At this time, Alpaca only accepts US clients for live accounts although you should still be able to open a paper trading account if you are not in the US. UPDATE – Alpaca announced on July 30, 2020 that they are now accepting Non-US residents as part of a beta program. The announcement on their website contains full details.
  2. Get an API Key – After creating an account, log in to view your API key and secret key. The endpoint used to make calls to the REST API should also be displayed. Take note of all three of these values.
  3. Install the Alpaca Python Library – Alpaca has a library, otherwise known as the client SDK, which simplifies connecting to the API. To install it, type in pip3 install alpaca-trade-api from your command prompt. 

Notes about the Alpaca library –

  • The Alpaca API library only works with Python 3.6 and above as it uses asynchronous functions that are not supported in older versions of Python.
  • Optional – rather than installing via pip, you can download the zip file from GitHub – https://github.com/alpacahq/alpaca-trade-api-python/ and place the alpaca_trade_api folder in your projects folder after extracting. The library has several dependencies, a full list can be found in the setup.py script.
  • Alpaca has launched V2 of their trading API and will discontinue the earlier version soon. For this reason, it is recommended to stick with V2 functions only.
  • Alpaca currently imposes a rate limit of 200 requests per minute

Testing for connectivity

import alpaca_trade_api as tradeapi

# authentication and connection details
api_key = 'Insert_your_api_key_here'
api_secret = 'Insert_your_api_secret_here'
base_url = 'https://paper-api.alpaca.markets'

# instantiate REST API
api = tradeapi.REST(api_key, api_secret, base_url, api_version='v2')

# obtain account information
account = api.get_account()
print(account)

The above code instantiates the REST class which will be used for all of the calls to the REST API. We then use the get_account() routine to get details about our account .
Your output should contain your account details in a dictionary format. If you received a 401 authentication error, your API key or secret might have been typed incorrectly .
Make certain the base URL matches the end point you noted down when obtaining your API key .
We ’ ve hardcoded our API key and hidden since we are testing Alpaca out with a paper trade explanation. In a live environment, however, it is a adept idea to take the extra security system precaution of storing your authentication details in environment variables .
A cool feature of the Alpaca library is that it can mechanically retrieve values you ’ ve stored as environment variables. Just make sure to use the succeed name conventionality :

APCA_API_KEY_ID=
APCA_API_SECRET_KEY=
APCA_API_BASE_URL=url

If you decide to store your API information as environment variables, you merely need to pass through the API version when instantiating the REST class, like this :

api = tradeapi.REST(api_version='v2')

How do I get historical data from the Alpaca API?

Alpaca offers both an in-house source for data angstrom well as a third-party solution via Polygon. Currently, the Polygon service is only offered to users that have a be funded report .
UPDATE : As of Feb 26, 2021, Alpaca has discontinued their Polygon datum extend. There are still two tiers of data, the remainder is they both come from Alpaca ( in-house ) .
The exempt interpretation offers data from the IEX substitution while the “ professional ” offer has a broader scope of data as it comes from the NYSE and Nasdaq exchanges. besides, there are no API or Websocket limits for the pro translation. The monetary value for pro datum is $ 49 per calendar month .
We will use the release reference to get historic data for Apple ( AAPL ) .

aapl = api.get_barset('AAPL', 'day')

In the above exemplar, we are making a predict for historic prices for Apple stock which has the heart AAPL. 
The data that is returned is within a custom class created by the library. There a few things we can do at this point .
If you like working with Pandas DataFrame ’ second, the library will automatically create a dataframe of the returned data. We can access it by appending .df at the end of the variable star we ’ ve created, like indeed :

print(aapl.df)

alternatively, if you ’ re not a fan of Pandas, the raw data can be accessed in a dictionary format as follows –

print(aapl._raw)

The model above retrieved day by day candles. We can easily change this for other fourth dimension frames. The valid intervals are : 1Min, 5Min, 15Min and 1D
here is a code case for obtaining 15-minute close price data for tesla :

tsla = api.get_barset('TSLA', '15Min')

By default, the data is limited to the last 100 bars. We can increase this to angstrom senior high school as 1000 bars by passing through a limit into the function .

aapl = api.get_barset('AAPL', 'day', limit=1000)

How do I use WebSockets to stream data with the Alpaca API?

Alpaca offers WebSockets which will push information to you without having to constantly make request calls to the API .
There are two main functions the Alpaca WebSocket provides – market price data updates and account updates. We will go through an exemplar of setting up a WebSocket to listen for account updates beginning .
This is a very useful function. Once you ’ ve sent your order, it can confirm that the order has been submitted to the exchange. It can besides let you know when the orders fills or if you merely got a partial fill .
here is the code :

conn = tradeapi.stream2.StreamConn(api_key, api_secret, base_url)

@conn.on(r'^account_updates$')
async def on_account_updates(conn, channel, account):
    print('account', account)

@conn.on(r'^trade_updates$')
async def on_trade_updates(conn, channel, trade):
    print('trade', trade)

def ws_start():
	conn.run(['account_updates', 'trade_updates'])

#start WebSocket in a thread
ws_thread = threading.Thread(target=ws_start, daemon=True)
ws_thread.start()

The last half of the code snip above serves to run the WebSocket in a thread. differently, it would block your main handwriting. Make certain to include import threading at the top of your script .
There are several other utilitarian pieces of information that can be had from implementing WebSockets, here is a full list : – hypertext transfer protocol : //alpaca.markets/docs/api-documentation/api-v2/streaming/ # common-events
Getting price data from the Alpaca WebSocket is a beneficial functionality that saves you from constantly having to poll the API for the latest prices .
There are three main types of data that you can obtain from the WebSocket pour :

  1. The last price a stock traded at
  2. The current quote (also known as the bid and ask prices)
  3. The latest one-minute bar data

If you plan to use the WebSocket for price data, the StreamConn classify will need to be instantiated slightly differently .

ws_url = 'wss://data.alpaca.markets'

conn = tradeapi.stream2.StreamConn(
    api_key, api_secret, base_url=base_url, data_url=ws_url, data_stream='alpacadatav1'
)

We ’ ve passed through two extra parameters compared to the earlier model where we instantiated StreamConn for just trade updates. First is the WebSocket URL and second is a data_stream parameter to let the library know we want to use Alpaca ’ s in-house data .
now we are able to receive updates for both our explanation and for prices. But we ’ ll motivation to write some functions to let the library know how we wish to consume our data .
recall that there are three types of data that we can request via the WebSocket. Let ’ s take a attend at an example of all three .

@conn.on(r'^T.AAPL$')
async def trade_info(conn, channel, bar):
    print('bars', bar)
    print(bar._raw)

The first exercise is for trade wind data. In other words, the WebSocket will update us for every barter that gets conducted and let us know at which price .
The authoritative part of the code is r'^T.AAPL$' .
The r’^$’ contribution of the code might be confusing if its the foremost clock you ’ re seeing it. This is character of the RegEx library. You don ’ t necessarily have to know what it does but if you ’ ra interested in learning more about it, you can do so at this connect .
The more significant part is T.AAPL. The T get ’ s the library know that we are looking for trade data. In this case we are looking for AAPL data but we can precisely as well change it to T.TSLA if we want to stream TSLA data .
We ’ ve named this function trade_info, but you can name it anything you want .
The price data we are after will be in the bar variable. This is a custom-made object from the library. With any custom object in this library, you can constantly view its contents by printing out its contents using the ._raw property .
The craft stream will return the trace variables : conditions, exchange, price, size, symbol, timestamp .
If you want to access only the price, you can do sol like this :

print(bar.price)

The same conventionality applies for any early data returned by the WebSocket .

@conn.on(r'^Q.AAPL$')
async def quote_info(conn, channel, bar):
    print('bars', bar)

The following case is for quote data, or otherwise known as offer and ask prices. You ’ ll notice that the format is about identical. The lone change here is that we are using Q for quote alternatively of T for deal .

@conn.on(r'^AM.AAPL$')
async def on_minute_bars(conn, channel, bar):
    print('bars', bar)

The last exemplar is for one-minute banish data. once again, the only real change here is that we are using AM alternatively of T or Q. besides keep in mind that each of these functions require a alone name. In this case, we ’ ve called it on_minute_bars .
We ’ ve nowadays defined a few functions which let the WebSocket know what we want to do with incoming data .
We still need to ‘ request ’ these data streams. We can do that as follows .

conn.run(['AM.AAPL'])

The above code will request one-minute bars for AAPL. In our function, we ’ ve instructed the library to print this datum to shield once it arrives .
We can request multiple streams at the lapp time .

conn.run(['account_updates', 'trade_updates', 'AM.AAPL'])

The above code subscribes to account updates, craft updates, and the AAPL one-minute barricade stream all from the same WebSocket connection. This is the best way to go about retrieving multiple streams as Alpaca will merely allow one WebSocket connection at a time .

How can I use indicators with the Alpaca API?

In the past, Alpaca offered data via the Alpha Vantage API which had built-in support for indicators. They have since transitioned to an in-house solution and do not offer indicator data through the API .
There are several options to get indicator values. You could continue to use the Alpha Vantage API by signing up directly for a keystone on their web site. Or, you can use a third-party library to calculate indicators .
Since the data returned by the Alpaca library comes in Pandas format, Pandas can be used to calculate assorted things like a go average or a standard diversion .
hera is an example of calculating the 20 moving average for the AAPL daily bars we retrieved earlier :

aapl.df.AAPL.close.rolling(20).mean()

The above code uses the mean ( ) function to calculate an average. The rolling function is where we can specify the size of the motivate average, in this case it is 20 .
If we wanted to calculate the standard diversion, all we need to do is substitute out the beggarly ( ) routine with the venereal disease ( ) routine, like this :

aapl.df.AAPL.close.rolling(20).std()

There are besides respective third-party libraries that simplify creating technical indicators. here are a few democratic ones :

  • Pandas TA – The Pandas Technical Analysis libraries offers over 120 indicators and works well in this scenario since the returned data is already in a Pandas Dataframe
  • TA-LIB – This is one of the most popular libraries out there. Several brokers use it in fact. It isn’t natively supported in Python but a wrapper is available.

How can I fire order in the Alpaca API?

api.submit_order(symbol='TSLA', 
		qty=1, 
		side='buy', 
		time_in_force='gtc', 
		type='limit', 
		limit_price=400.00, 
		client_order_id='001')

The above code snippets sends an order to buy one share of TSLA at a limit price of $ 400 .
If you ’ d like to submit a marketplace order, use type='market' and remove the limit_price parameter .
If you ’ d like to short sell, use side='sell'. It ’ s a thoroughly estimate to check first to make surely you ’ re able to sell that particular security .
We ’ ve assigned a string value of 001 as an regulate id to this order indeed that we can reference it with still belated on. This is optional. If you do decide to include a client_order_id, make indisputable the value is unique differently the library will raise an exception .
If you ’ re using the built-in WebSockets feature, you will mechanically be notified that the order has been submitted. otherwise, you can make a request to check on your side as follows .

position = api.get_position('TSLA')

alternatively, you can check on positions based on the order id you ’ ve assigned as follows :

position = api.get_order_by_client_order_id('001')

How do I set a stop loss or take profit?

When submitting an ordain, you can attach either a hold on passing, take profit, or both. here is an exercise :

api.submit_order(symbol='TSLA', 
		qty=1, 
		side='buy', 
		time_in_force='gtc', 
		type='limit', 
		limit_price=400.00, 
		client_order_id=001, 
		order_class='bracket', 
		stop_loss=dict(stop_price='360.00'), 
		take_profit=dict(limit_price='440.00'))

We ’ ve added a argument to indicate this is a bracket club which is required when setting a stop loss and take profit. Further, the intercept passing and take profit need to be nested, so we use dict() with the want parameters and the price point as a string .

Which stocks can you trade with Alpaca?

active_assets = api.list_assets(status='active')

The above code snip will return all the active voice stocks available for deal with Alpaca. It will include information such as the exchange the stock trades on and if you can short it .
You can reverse search as well. Say if you already have a stock that you want to trade, you can check to make surely Alpaca offers it with the follow code :

aapl_asset = api.get_asset('AAPL')

If an asset is not found on Alpaca ’ randomness system, it will raise an error. For this rationality, its a good mind to use a try/except obstruct when running the above code .

How do I find out what time the market closes?

print(api.get_clock())

This is a utilitarian affair as it returns when the market closes, when it will open next, vitamin a well as the server time .
This direction you can make certain you are using the same time format the API is using and you can pause your algo when the grocery store is not open .

Putting it all together – a fully functioning trading script

We will go through a amply automated trade organization that utilizes the Alpaca API. The objective is to show a practical use case for the functionality described in the lead thus far. therefore, there is not much vehemence on the actual trade strategy, and we don ’ metric ton expect it to be a profitable one .
The scheme we will use is a elementary break system .
Breakout Example
The visualize above provides a ocular of the scheme .
The grey box contains ten candles and we will filter out the absolute eminent and low. If the monetary value rallies above the high, we will buy. If it falls below the low, we will submit a sell order .
The chart above finally provided a sell sign. The future footstep is to determine our break loss and take net income. To do that, we calculate the distance between the range high and range first gear of the grey box $ 251.74 – $ 250.67 = $ 1.07.

We will set our break loss $ 1.07 higher than our entry point and our film profit $ 1.07 lower than our entrance detail .
Let ’ s catch started .

import logging
from time import sleep

import alpaca_trade_api as tradeapi
import pandas as pd

# init
logging.basicConfig(
	filename='errlog.log',
	level=logging.WARNING,
	format='%(asctime)s:%(levelname)s:%(message)s',
)

We start with our imports. The alone third-party library we are using hera is lesser panda which will be used to make calculations for our trade entries. apart from that, a basic lumberman has been created to log any errors that may come up .

api_key = 'insert_api_key'
api_secret = 'insert_api_secret'
base_url = 'https://paper-api.alpaca.markets'
data_url = 'wss://data.alpaca.markets'

Next we declare a few constant variables. Again, if you ’ ra deal in a live account, it is better to store your API key as environment variables quite than hard coding them. The base URL will be used to instantiate the API and the datum URL is needed to initialize the WebSocket as shown in the code below .

# instantiate REST API
api = tradeapi.REST(api_key, api_secret, base_url, api_version='v2')

# init WebSocket
conn = tradeapi.stream2.StreamConn(
	api_key,
	api_secret,
	base_url=base_url,
	data_url=data_url,
	data_stream='alpacadatav1',
)

There will be a few instances where we will need to check if the market is open or not. The surveil two methods will make it easier to get this information belated on .

def time_to_market_close():
	clock = api.get_clock()
	return (clock.next_close - clock.timestamp).total_seconds()


def wait_for_market_open():
	clock = api.get_clock()
	if not clock.is_open:
		time_to_open = (clock.next_open - clock.timestamp).total_seconds()
		sleep(round(time_to_open))

Both use the get_clock ( ) function of the API. The beginning method in the code snip above will let us know how many seconds are left until the market closes. We need this data as we don ’ triiodothyronine want to trigger any new trades 120 seconds, or 2 minutes, before the market closes for the day .
The second base officiate will merely put the handwriting to sleep until the market reopens again .

def set_trade_params(df):
	return {
		'high': df.high.tail(10).max(),
		'low': df.low.tail(10).min(),
		'trade_taken': False,
	}

The set barter params function takes in a giant panda DataFrame and then returns the high and low over the last ten bars, in a dictionary format. This will be used to determine our trade wind entries .
The adjacent officiate is a long one. This one will be used to send an order once we ’ ve established an submission .

def send_order(direction, bar):
	if time_to_market_close() > 120:
		print(f'sent {direction} trade')
		range_size = trade_params['high'] - trade_params['low']

		if direction == 'buy':
			sl = bar.high - range_size
			tp = bar.high + range_size
		elif direction == 'sell':
			sl = bar.low + range_size
			tp = bar.low - range_size

			api.submit_order(
			symbol='AAPL',
			qty=100,
			side=direction,
			type='market',
			time_in_force='day',
			order_class='bracket',
			stop_loss=dict(stop_price=str(sl)),
			take_profit=dict(limit_price=str(tp)),
		)

		return True

	wait_for_market_open()
	return False

The first thing this function does is check to see if there is at least 120 seconds left until the market closes. If this condition is not met, it skips sending the craft and puts the script to sleep until the market reopens .
It will besides return False if this were to happen, barely to let the handwriting know that an holy order was not sent, even though this function was called .
If there is more than 120 seconds until the marketplace close, the script will calculate the range size and determine the stop loss and take profit values. After that, a market order is submitted. ultimately, True is returned to confirm that a deal went through .
That ’ s it for our functions. We can immediately move on to creating recall functions for the WebSocket .
There are two callbacks we will want to create. One is for the one-minute legal profession data that we will be requesting. The second base is for the craft updates stream we discussed and showed an example of earlier on in this article .
One thing that is singular about this trade strategy is that we will be writing most of it within the WebSocket recall itself .
There are advantages and disadvantages of taking this set about .
A big advantage is that we don ’ t need to constantly put our script to sleep and keep control to see if modern data has arrived. angstrom soon as the WebSocket receives newfangled data, our necessity code will run .
The disadvantage of this is that running code in a WebSocket will block it from receiving farther messages .
In this case, we are only expecting updates once a moment. And our code shouldn ’ t take more than a irregular to run anyhow .
But if you were working with tick data, a better approach would be to write your code outside the recall serve and then use either the thread module or an asynchronous model to ensure the WebSocket is not being blocked .

@conn.on(r'^AM.AAPL$')
async def on_minute_bars(conn, channel, bar):
	if isinstance(candlesticks.df, pd.DataFrame):
		ts = pd.to_datetime(bar.timestamp, unit='ms')
		candlesticks.df.loc[ts] = [bar.open, bar.high, bar.low, bar.close, bar.volume]

	if not trade_params['trade_taken']:
		if bar.high > trade_params['high']:
			trade_params['trade_taken'] = send_order('buy', bar)

		elif bar.low < trade_params['low']:
			trade_params['trade_taken'] = send_order('sell', bar)

	if time_to_market_close() > 120:
		wait_for_market_open()

The above code will execute everytime the Alpaca WebSocket pushes a raw one-minute bar to us .
In the first block of code, the latest browning automatic rifle gets appended to candlesticks.df. We haven ’ triiodothyronine created candlesticks.df but will get to it concisely .
The idea hera is that he WebSocket only pushes out one bar at a clock. But we need ten bars to calculate our compass high and first gear .
What we can do is call the API once to get the initial 10 bars needed for our calculation. then, this part of the code will keep our data up to date sol that we don ’ t have to query the API for historical data next time we want to calculate our entry parameters .
After that, we check to see if the current high gear took out the 10-bar high calculated in the trade parameters dictionary. If sol, a trade holy order is sent using the function we created earlier. The same applies if the 10-bar broken gets taken out .
We only want to be in one trade at a clock time, therefore we use ‘ trade_taken ’ to inform the script if an candid craft exits or not .
last, we do a bridle here to make sure there is at least 120 seconds left until the market closes. If not, the script goes to sleep until the market adjacent reopens again .
The second function will handle any craft updates from the WebSocket

@conn.on(r'^trade_updates$')
async def on_trade_updates(conn, channel, trade):
	if trade.order['order_type'] != 'market' and trade.order['filled_qty'] == '100':
		# trade closed - look for new trade
		trade_params = set_trade_params(candlesticks.df.AAPL)

All we are doing here is checking to see if a message has come in that indicates our trade has closed. If so, we can check for modern trade wind parameters for the future trade .
We do this by checking the regulate type. Any introduction orders we sent are market orders. If a trade is closed, it will either be by a terminus ad quem decree ( take profit ) or a break order ( end loss ) .
then if we have any order character that is not a market order with a satiate quantity of 100, we know that means our last trade was closed .
We are done with our methods and callbacks. normally, this is where the main handwriting starts. But in this case, we are closely finished .
The three lines of code below is all that ’ mho needed for the main depart of our script .

candlesticks = api.get_barset('AAPL', 'minute', limit=10)
trade_params = set_trade_params(candlesticks.df.AAPL)
conn.run(['AM.AAPL', 'trade_updates'])

The first line makes the call for the initial 10 bars of historic data. This is the like object that the WebSocket will append new bars to .
We ’ ve besides set the trade parameters for our first base trade, and started the WebSocket .
note that we are not running the WebSocket in a weave. Since all the code takes place in the recall functions, there is no need to run two separate threads, or even any loops for that matter .

A fully functioning trading script – without WebSocket data

When this article was first written, Alpaca didn ’ deoxythymidine monophosphate offer a data WebSocket. So we had take an entirely different approach compared to the example above .
This trade exemplar achieves the accurate same thing as the end example but relies on making API calls for new one-minute bars .
The follow script uses nested loops. The advantage of nest loops, in this case, is that it is clear code that offers clear logic as we progress through the assorted parts of a barter cycle .
The disadvantage is that nest loops can be slowly. This is not an issue in this case because we are dealing with one-minute data but if you ’ ra strategy involves tick data, it might be something to consider .
Loops are besides a bit dangerous in programming in general but more then in trade. If something goes wrong, the script could accidently send multiple unintended orders. Extra caution should constantly be taken when working with loops .

import alpaca_trade_api as tradeapi
import threading
from time import sleep 
import json
import logging

These are all our imports. We have gone over the first two already. The clock faculty will be used to put the script at sleep when needed. The JSON module is needed then that we can export a list of our trades to a CSV. last, we will use logging to keep a log file of any errors that may pop up .

#init
logging.basicConfig(filename='errlog.log',level=logging.WARNING,  format='%(asctime)s:%(levelname)s:%(message)s')

api_key = 'insert_api_key'
api_secret = 'insert_api_secret'
base_url = 'https://paper-api.alpaca.markets'

api = tradeapi.REST(api_key, api_secret, base_url, api_version='v2')

trade_msg = []
order_msg = []
past_trades = []

searching_for_trade = False
order_sent = False
order_submitted = False
active_trade = False
done_for_the_day = False

hera we initialize the API and the log affair. We are besides defining respective variables. Their use will become clear as we go through the script .

api.cancel_all_orders()

In this adjacent part, we have our inaugural feel with the API. We are calling API to cancel any afford orders. It ’ randomness there in lawsuit our script got interrupted for whatever reason and we have to restart in the middle of a market day .

#check if market is open
clock = api.get_clock()

if clock.is_open:
	pass
else:
	time_to_open = clock.next_open - clock.timestamp
	sleep(time_to_open.total_seconds())

following, we use the clock routine to see if the markets are open. ideally, we would start the handwriting before the markets open. The code above checks what clock the markets open and sleeps until then .

if len(api.list_positions()) == 0:
	searching_for_trade = True
else:
	active_trade = True

The follow if statement checks to see if we have any candid positions. Again, this is just some extra error check in case our script was interrupted in the middle of a market day. In most cases, we won ’ t have a trade open when starting the script .

#init WebSocket
conn = tradeapi.stream2.StreamConn(api_key, api_secret, base_url)

@conn.on(r'^account_updates$')
async def on_account_updates(conn, channel, account):
	order_msg.append(account)

@conn.on(r'^trade_updates$')
async def on_trade_updates(conn, channel, trade):
	trade_msg.append(trade)
	if 'fill' in trade.event:
		past_trades.append([trade.order['updated_at'], trade.order['symbol'], trade.order['side'], 
			trade.order['filled_qty'], trade.order['filled_avg_price']])
		with open('past_trades.csv', 'w') as f:
			json.dump(past_trades, f, indent=4) 
		print(past_trades[-1])

def ws_start():
	conn.run(['account_updates', 'trade_updates'])

#start WebSocket in a thread
ws_thread = threading.Thread(target=ws_start, daemon=True)
ws_thread.start()
sleep(10)

We ’ ve already discussed the WebSocket. A small addition hera is that some of the parameters from filled orders are appended to a number and then saved to a file. This way, we will have a clean list of any orders we ’ ve executed for our records .
The script sleeps for 10 seconds after the WebSocket is called equitable to give it adequate time to start and authenticate .

# functions
def time_to_market_close():
    clock = api.get_clock()
    closing = clock.next_close - clock.timestamp
    return round(closing.total_seconds() / 60)


def send_order(direction):
    if time_to_market_close() > 20:
        if direction == 'buy':
            sl = high - range_size
            tp = high + range_size
        elif direction == 'sell':
            sl = low + range_size
            tp = low - range_size

        api.submit_order(
            symbol='AAPL',
            qty=100,
            side=direction,
            type='market',
            time_in_force='day',
            order_class='bracket',
            stop_loss=dict(stop_price=str(sl)),
            take_profit=dict(limit_price=str(tp)),
        )
        return True, False

    else:
        return False, True

Our functions come following. The first base one merely calculates how many minutes are left until the marketplace close. We will need to check this as we don ’ t want to execute any new orders precisely before the market closes. The intention is not to carry any trades overnight .
The second function is what we will use to submit orders. We first check to see if there is at least 20 minutes left until the market close. If then, we do a quick calculation of our bring profit and stop loss and then submit a grocery store decree, alike to our anterior model .

# main loop
while True:

    try:

We will now start the chief loop. We ’ ve enclosed the entire loop in a try/except block as the Alpaca API raises an exception if something goes wrong .

candlesticks = api.get_barset('AAPL', 'minute', limit=10)
high = candlesticks['AAPL'][0].h
low = candlesticks['AAPL'][0].l
range_size = high - low
if range_size / candlesticks['AAPL'][0].c < 0.003:
	range_size = candlesticks['AAPL'][0].c * 0.003
for candle in candlesticks['AAPL']:
	if candle.h > high:
		high = candle.h
	elif candle.l < low:
		low = candle.l
range_size = high - low

The first part of our main closed circuit is the code used to determine our range. It utilizes the barset serve of the Alpaca API to get the last 10 bars. At that point, it iterates through the bars to pick out the highest and lowest values .
The API won ’ t allow us to send orders if the stop loss or take profit is less than 0.1 % away from that price. For this reason, we ’ ve added an extra assay to ensure our range is bigger than 0.3 % of the current price. Although it only needs to be 0.1 %, we added the extra buffer as there could be a price deviation between the time we send the arrange and when it executes .
Our main script will have five main loops. We will go through them now .

while searching_for_trade:
	clock = api.get_clock()
	sleep(60 - clock.timestamp.second)
	candlesticks = api.get_barset('AAPL', 'minute', limit=1)
	if candlesticks['AAPL'][0].c > high:
		searching_for_trade = False
		order_sent, done_for_the_day = send_order('buy')

	elif candlesticks['AAPL'][0].c < low:
		searching_for_trade = False
		order_sent, done_for_the_day = send_order('sell')

At this point, as the variable suggests, we are searching for a trade. The beginning pace is to check the meter and put the handwriting to sleep until a fresh one-minute barroom is available .
once we have a new bar, we check to see if the price has crossed a modern moo or high. If then, we will send the allow buy or sell order .
When we send an order, we set the searching_for_trade variable star to False, which signals to our script that its time to move on to the future loop .
The exception to this is if there is less than 20 minutes left to the market close as we don ’ triiodothyronine want to initiate new positions at that time. In that encase, we set done_for_the_day to True so that the script can skip to the last coil which we will cover curtly .

while order_sent:
	sleep(1)
	for item in trade_msg:
		if item.event == 'new':
			order_submitted = True
			order_sent = False

The holy order sent loop is straight forward. Recall that we are storing our WebSocket datum as a tilt item into a varying. We are plainly checking this list to see if a contains a new event, or in other words, a modern deal order .
This is an oversimplify error check. It works, but in your script, you might be matter to in a more comprehensive check .
We ’ ve added a one second sleep here in order to avoid overusing the CPU as an infinite loop is being used .

while order_submitted:
	sleep(1)
	for item in trade_msg:
		if item.order['filled_qty'] == '100':
			order_submitted = False
			active_trade = True
			trade_msg = []

future is the order_submitted closed circuit which is very similar to the last loop. The dispute here is that we are checking to make surely the regulate is filled earlier moving to the following pace .
once the order is filled, we are besides clearing out our trade message list. We do this to prepare it for the future trade wind. We didn ’ t see any habit to keeping this data as you can always access honest-to-god orders through the API .

while active_trade:
	for i in range(time_to_market_close() - 5):
		sleep(60)
		if len(api.list_positions()) == 0:
			active_trade = False
			searching_for_trade = True
			break
	if active_trade:
		done_for_the_day = True
		active_trade = False

We now move on to the active_trade loop. This is an significant one as we need to keep an eye on when the marketplace closes. If we are still in a trade about five minutes to market close, we will just close it at commercialize to avoid holding a position overnight .
This loop will query the API for open positions every infinitesimal. If no open positions have been found, it tells us that our stop loss or take net income has been hit. In this scenario, we can break out of the cringle and start the action of searching for a new trade bespeak over again .
If the for loop runs out and we are still in an open position, the active_trade variable will hush be True. This means there is five minutes left until the market close so we will signal that we are done for the day .

while done_for_the_day:
	api.close_all_positions()
	clock = api.get_clock()
	next_market_open = clock.next_open - clock.timestamp
	sleep(next_market_open.total_seconds())
	searching_for_trade = True

The done for the day loop plainly closes all open positions. We can call this command as our strategy only has one open position at a time .
adjacent, we call the clock officiate to found out when the market opens next and put the handwriting back to sleep until then. finally, we set searching_for_trade = True so that the handwriting can start the process all over again once it wakes up at the future market clear .

except Exception as e:
	logging.exception(e)

last, we will log any exceptions so that we can keep an eye on any errors that might come up with the API .
And there you have it, a full trade script using the Alpaca API .
You are welcome to use this code and build on it. We would recommend doing some further error check and besides looking into handling specific exceptions that are normally raised by the API .

Final thoughts on the Alpaca API

overall, the Alpaca API does a thoroughly job at what it is supposed to do .
We did run into a few quirks in our testing. For example, response times took longer than average when making calls for historical data in our screen. For deal systems where speed is of the kernel, running far tests on reaction time is recommended .
There were besides a few discrepancies in the Alpaca software documentation. Although to be fair, they appear to be in the middle of a migration to a new version .
There are a total of early functions in the library that we haven ’ deoxythymidine monophosphate covered, we recommend taking a look at the rest.py reference file included in the library to get a better reason of all of the functions available .

help(tradeapi.REST)

You can besides run the above line of code to get all of the functions available within the REST class .

The code used in the examples is available on GitHu b. From the GitHub page, click the green button on the right “ Clone or download ” to download or clone the code .

source : https://coinselected
Category : coin 4u

Leave a Reply

Your email address will not be published.