@axg5068 What timeframe (ie the length of each bar) are you expecting. Specifying ‘12M’ means you are requesting bars which are 12 months long. Is that what was intended? The allowable values are in the docs and are:
[1-59]Min / T
[1-23]Hour / H
1Day / D
1Week / W
[1,2,3,4,6,12]Month / M
Also note how each bar is labeled. The day, week, and month bars are all labeled with a time of midnight market time (America/New_York). The week bars always begin on Monday and the month bars always begin on the first of the month. For example here are some example bar labels (ie timestamps)
Daily bars
timestamp
2023-08-24 00:00:00-04:00
4.788
4.8500
4.175
4.325
762940
36505
4.409000
IDEX
2023-08-25 00:00:00-04:00
3.800
4.3800
3.250
4.300
2044336
15996
3.852685
IDEX
2023-08-28 00:00:00-04:00
3.960
4.0985
3.350
3.480
1070353
9753
3.582292
IDEX
Weekly bars
timestamp
2023-08-28 00:00:00-04:00
3.96
4.0985
2.95
2.97
4406089
36147
3.232392
IDEX
2023-09-04 00:00:00-04:00
2.97
2.9700
2.04
2.07
2541074
26358
2.476772
IDEX
Monthly bars
timestamp
2023-07-01 00:00:00-04:00
9.775
13.36
9.55
11.61
4731765
345316
11.368918
IDEX
2023-08-01 00:00:00-04:00
11.460
12.25
2.95
3.02
14257496
539822
5.499967
IDEX
2023-09-01 00:00:00-04:00
3.100
3.24
2.04
2.07
3461414
32728
2.634436
IDEX
Another convention to note is when the ‘multiple’ numbering starts. For months this is always January. For example, a 12Month timeframe will always start on January 01.
Why is this important? When fetching bars, both the date and time are considered. For example, fetching 1Month bars after 2023-07-01 09:030:00-04:00 won’t return the 2023-07-01 00:00:00-04:00 bar. Be aware of this when specifying the start and end times.
specifies “fetch up to 20 12month bars with labels/timestamps between 2020-09-01T0:00:00Z thru 2020-09-02T0:00:00Z”. This won’t return any bars. A 12Month bar is always labeled with January 1. The following are valid labels/timestamps for 12Month bars
timestamp
2019-01-01 00:00:00-05:00
153.75
355.00
71.25
106.96
1163889
466216
206.575391
IDEX
2020-01-01 00:00:00-05:00
106.79
593.75
34.50
248.75
36963391
10196817
255.440216
IDEX
2021-01-01 00:00:00-05:00
250.00
691.25
138.75
150.00
41660442
12447064
378.825054
IDEX
Notice there are no bars with timestamps 2020-09-01T0:00:00Z thru 2020-09-02T0:00:00Z". That is why no bars are returned.
Thanks Dan. That’s helpful and that fixed it - I used the “T” instead of “M” for minute timestamp and then I was able to get an API response.
I have a few follow-up questions:
I can’t tell what all the symbols that are part of the bar mean and they aren’t listed in the Alpaca documentation. For instance, I know Open, High, Low, Close. I believe “v” is for volume. What is “vw”? Also, what does “n” stand for?
The other issue I came across is data accuracy. The API states that Tesla’s opening price on 09-01-2020 was $530.04 and the volume was 126,594. However, when I checked the Nasdaq site for historical price data, the actual opening price that day was closer to $167. Can you help me understand why there is such a large discrepancy here?
Is there any way to run an API call that looks at every publicly traded stock (e.g. including NYSE, Nasdaq, and other exchanges).
If #3 is not possible, is it possible to run an API call that returns stocks for a given period that open each day X% above their close price the previous trading day?
The vw attribute is the ‘volume weighted price’ for that bar. The price and volume for each trade is multiplied then these are summed and finally divided by the total volume. It’s an ‘average price’ for the bar. The n attribute is the number of trades during the bar. There is a bit more description in the docs here.
The API states that Tesla’s opening price on 09-01-2020 was $530.04 and the volume was 126,594 … However, when I checked the Nasdaq for historical price data, the actual opening price that day was closer to $167
I wasn’t able to reproduce the API data you posted. When I fetch the daily open for TSLA on 09-01-2020 I get $502.14 with no adjustment (ie adjustment='raw') and $167.38 adjusted for splits (ie adjustment='split') which matches the NASDAQ open price. Typically any discrepancy is whether the data is adjusted for splits or not.
Is there any way to run an API call that looks at every publicly traded stock (e.g. including NYSE, Nasdaq, and other exchanges).
All market data calls accept multiple symbols, so in theory one can request all tradable symbols in a single call. However, as a practical matter the number is limited to about 3500 symbols/call. The reason is the symbols are a ‘query parameter’ and become part of the URL. With a lot of symbols the URL becomes very long and some/most networks cannot handle such long URLs.
So, fetching all data for all symbols is a 2 step process. 1) fetch a list of all tradable assets. Use the assets endpoint to get that list, and 2) fetch the data for those assets by dividing the list into chunks of 3500 symbols.
…is it possible to run an API call that returns stocks for a given period that open each day X% above their close price the previous trading day?
There is an endpoint for the top and bottom gainers for the day which may be what you are looking for. Check out the movers endpoint.
The API is working and I’m able to pull data. However, I’m only seeing the first 25 records of the request accompanied by a “next page” token.
I read in a different forum that to get the subsequent pages, I could use a while loop or get the Alpaca.Markets.Extension. Is such an extension available for Python?
What is the easiest/most straightforward way to obtain subsequent pages of data?
@axg5068 The trades, quotes, and bars endpoints can each return up to 10,000 items in a single call. If more than that are requested, a page_token is returned allowing one to make a subsequent call starting where the previous one stopped. So, if you know you won’t be fetching more than 10,000 items (eg bars) the simplest may be to simply specify limit=10000. No paging necessary.
However, a more generalized approach is to use one of the Alpaca SDKs such as alpaca_trade_api or alpaca-py. Both of those packages do the paging for you behind the scenes. Just enter the start and end dates.
Here is an example, using the alpaca_trade_api SDK, for getting a month of minute bars for 10 stocks (over 100,000 bars).
#First install and import the Alpaca python API SDK 'wrapper'
!pip install -q alpaca_trade_api
import alpaca_trade_api as alpacaapi
#set the desired symbols and dates
symbols = ['A', 'CAT', 'IBM', 'SPY', 'F', 'BHP', 'BTU', 'SPY', 'TSLA', 'META']
start_time = pd.to_datetime("2023-03-01 00:00:00").tz_localize('America/New_York')
end_time = pd.to_datetime("2023-04-01 00:00:00").tz_localize('America/New_York')
#fetch the minute bars
#convert to a dataframe indexed by the bar time with market timezone
minute_bars = api_data.get_bars(symbols,
'1Min',
start=start_time.isoformat(),
end=end_time.isoformat(),
).df.tz_convert('America/New_York')
I’ve been tinkering with the API this evening but have run into some roadblocks. Specifically, I can’t load in the environmental variable that stores the secret Alpaca keys. It returns “None” when I try to print the keys after loading them from the .env file. More detail below.
I began building my Python project based on the following example on Github:
The only difference is that I used the Python dotenv package (instead of os.environ) to load the APCA_API_KEY_ID and APCA_API_SECRET_KEY.
Here is the code from the top of my base.py file:
from dynaconf import FlaskDynaconf
from flask import render_template
from flask import request
from flask import Flask, redirect, url_for, request, jsonify, make_response
import requests
from alpaca.data.historical import CryptoHistoricalDataClient
from alpaca.data.requests import CryptoBarsRequest
from alpaca.data.timeframe import TimeFrame
import datetime
import pandas as pd
import json
import socket
import os
from dotenv import load_dotenv
import alpaca_trade_api as tradeapi
from alpaca_trade_api.rest import TimeFrame, URL, REST
from alpaca_trade_api.rest_async import gather_with_concurrency, AsyncRest
load_dotenv()
app = Flask(__name__)
Here is the code for starting the program on localhost and pulling in the env variables: