-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfn_alpaca_trades_v1.py
256 lines (194 loc) · 9.29 KB
/
fn_alpaca_trades_v1.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
'''
import pandas as pd
import requests
import json
import dtale
from collections import Counter
import fn_flatten_and_expand_df
import robin_stocks.robinhood as r
from pandasgui import show
'''
'''
#get pickle file
print(r.__file__)
#login to robinhood wrapper api
r.login('*** @gmail.com', '')
#get portfolio holdings data and convert to dataframe
holdings = r.account.build_holdings()
'''
'''
base_url = 'https://data.alpaca.markets/v2/stocks/trades'
#enclosed_tickers = tickers
start_date ='2024-04-29' # <<< format: RFC-3339 or YYYY-MM-DD
end_date = '2024-04-29'
limit = 10000 # <<< max number of datapoints; next page token will generate if limit is exceeded for another call
feed = 'sip' # <<< the source feed of the data. "sip' contains all US exchanges, 'iex' contains only the Investors Exchange; 'otc' contains over the counter exchanges
next_page_token = '' # <<< copy paste token or comment out
sort = 'asc'
'''
'''
headers = {
"accept": "application/json",
"APCA-API-KEY-ID": "******",
"APCA-API-SECRET-KEY": "******"
}
'''
'''
iterations = range(5) # <<< set number of loops
'''
# - ALPACA API Documentation: https://docs.alpaca.markets/reference/stockbars-1
def fn_alpaca_trades_v1( holdings, start_date, end_date, limit, feed, next_page_token, sort, iterations, headers, base_url, show_final=None):
print('''ReadMe: ''')
print('''Robin$tocks API Docs: https://robin-stocks.readthedocs.io/en/latest/robinhood.html''')
print('''Alpaca API Docs: https://docs.alpaca.markets/reference/stocktrades-1''')
#-------------------------------------------------------------------------------------------------------
##### 1. Set initial loop, lists, counters, & import packages etc
#-------------------------------------------------------------------------------------------------------
import pandas as pd
import requests
import json
import robin_stocks.robinhood as r
from pandasgui import show
from collections import Counter
#initialize counters
string_cnt = 0
none_cnt = 0
#initialize lists
foo = {1:0}
foo[1]=(0)
dictionary_list=[]
trade_list=[]
#-------------------------------------------------------------------------------------------------------
##### 2. "Next Page Token" API Function
#-------------------------------------------------------------------------------------------------------
## - function iterates the Alpaca API call and retrieves tokens and bar data
def api_npt(i,next_page_token):
if i < 1:
response = requests.get(f"{base_url}?symbols={enclosed_tickers}&start={start_date}&end={end_date}&limit={limit}&feed={feed}&sort={sort}", headers=headers)
print(
'''____________________________________________________________________________________________________________________________________
''')
print(f'URL {i}:',f"{base_url}?symbols={enclosed_tickers}&start={start_date}&end={end_date}&limit={limit}&feed={feed}&sort={sort}") # <<< print first url address
else:
response = requests.get(f"{base_url}?symbols={enclosed_tickers}&start={start_date}&end={end_date}&limit={limit}&feed={feed}&page_token={next_page_token}&sort={sort}", headers=headers)
print(
'''____________________________________________________________________________________________________________________________________
''')
print(f'URL {i}:',f"{base_url}?symbols={enclosed_tickers}&start={start_date}&end={end_date}&limit={limit}&feed={feed}&page_token={next_page_token}&sort={sort}") # <<< print rest of url addresses
response_json = response.json()
## - get bar data and store in list
for symbol, trades in response_json['trades'].items():
for trade in trades:
trade['symbol'] = symbol
trade_list.append(trade)
## - appends dictionaries into a list
trades = response_json.get('trades')
dictionary_list.append(trades)
npt = response_json.get('next_page_token')
print(f'Next Token ->',npt)
return(npt)
#-------------------------------------------------------------------------------------------------------
##### 3. Extract Robinhood Portfolio Tickers
#-------------------------------------------------------------------------------------------------------
print(
'''
---------------------------------------------
Portfolio Holdings
---------------------------------------------
''')
#holdings_data = r.account.build_holdings()
holdings_df = pd.DataFrame(holdings).transpose()
## - rename the 'index' column to 'symbol'; dont run more than once otherwise there will be more than one symbol column
holdings_df = holdings_df.reset_index().rename(columns={'index': 'symbol'})
holdings_df.info()
print(
'''
---------------------------------------------
Stock Tickers
---------------------------------------------
''')
## - filter down only tickers
holdings_df = holdings_df.filter(['symbol'])
holdings = holdings_df.transpose()
print(holdings)
## - concatenate all tickers as one string; using %2 as separator per api requirements
tickers = "%2C".join(holdings_df["symbol"])
enclosed_tickers = tickers
#print(tickers)
#-------------------------------------------------------------------------------------------------------
##### 4. Main Token Loop
#-------------------------------------------------------------------------------------------------------
for i in iterations:
j = (i + 1)
if i < 1:
print(next_page_token)
#next_page_token = api_npt(i,next_page_token)
next_page_token = next_page_token
foo[1]=(next_page_token)
else:
next_page_token = api_npt(i,next_page_token)
foo[i+1] = (next_page_token)
print(
'''____________________________________________________________________________________________________________________________________
''')
## - print list of all tokens retrieved
print(">>> List of all tokens in Alpaca call:", foo)
## - the show() function is for the pandasGUI package; is optional to include; https://pypi.org/project/pandasgui/
#dictionary_list=[]
#show(dictionary_list)
#show(bar_list)
## - count all tokens
for value in foo.values():
if isinstance(value, str):
string_cnt += 1
elif value is None:
none_cnt += 1
print(">>> Number of Tokens:", string_cnt-1)
print(
'''____________________________________________________________________________________________________________________________________
''')
#-------------------------------------------------------------------------------------------------------
##### 5. Final Table
#-------------------------------------------------------------------------------------------------------
trade_df = pd.DataFrame(trade_list)
#show(trade_df)
final_df = fn_flatten_and_expand_df.flatten_and_expand_df(trade_df)
print(
'''
---------------------------------------------
Final Table
---------------------------------------------
''')
print('''
>>> Final DataFrame name can be referenced as "final_df".
''')
final_df.info()
final_df.describe()
if show_final == 'Y':
show(final_df)
print("""
>>> Final Table set to show in pandasGUI; pip install pandasgui if error occurs.
PandasGUI Docs: https://pypi.org/project/pandasgui/ """)
print("""
>>> Variables in Query:
t | date-time | Timestamp in RFC-3339 format with nanosecond precision
x | string | Exchange code. See v2/stocks/meta/exchanges for more details.
p | double | Trade price
s | uint32 | Trade size
i | uint64 | Trade ID sent by the exchange
c | array of strings | Condition flags. See https://docs.alpaca.markets/reference/stockmetaconditions-1 for more details.
z | string | Tape A is the New York Stock Exchange, Tape B is NYSE Arca, Bats, IEX and other regional exchanges, Tape C is NASDAQ, Tape O is OTC; A B C O""")
else:
print("""
>>> Final Table set to NOT show; change keyword function argument to final='Y' to display final DataFrame.""")
print("""
>>> Variables in Query:
t | date-time | Timestamp in RFC-3339 format with nanosecond precision
x | string | Exchange code. See v2/stocks/meta/exchanges for more details.
p | double | Trade price
s | uint32 | Trade size
i | uint64 | Trade ID sent by the exchange
c | array of strings | Condition flags. See https://docs.alpaca.markets/reference/stockmetaconditions-1 for more details.
z | string | Tape A is the New York Stock Exchange, Tape B is NYSE Arca, Bats, IEX and other regional exchanges, Tape C is NASDAQ, Tape O is OTC; A B C O
""")
return(final_df)