forked from joshfraser/robinhood-to-csv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsv-options-export.py
191 lines (168 loc) · 6.19 KB
/
csv-options-export.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
from __future__ import print_function
from Robinhood import Robinhood
from profit_extractor import profit_extractor
import getpass
import collections
import argparse
import ast
from dotenv import load_dotenv, find_dotenv
import os
logged_in = False
parser = argparse.ArgumentParser(
description='Export Robinhood trades to a CSV file')
parser.add_argument(
'--debug', action='store_true', help='store raw JSON output to debug.json')
parser.add_argument(
'--username', default='', help='your Robinhood username')
parser.add_argument(
'--password', default='', help='your Robinhood password')
parser.add_argument(
'--mfa_code', help='your Robinhood mfa_code')
parser.add_argument(
'--profit', action='store_true', help='calculate profit for each sale')
args = parser.parse_args()
username = args.username
password = args.password
mfa_code = args.mfa_code
load_dotenv(find_dotenv())
robinhood = Robinhood()
# login to Robinhood
while logged_in != True:
if username == "":
username = os.getenv("RH_USERNAME", "")
if username == "":
print("Robinhood username:", end=' ')
try:
input = raw_input
except NameError:
pass
username = input()
if password == "":
password = os.getenv("RH_PASSWORD", "")
if password == "":
password = getpass.getpass()
logged_in = robinhood.login(username=username, password=password)
if logged_in != True and logged_in.get('non_field_errors') == None and logged_in.get('mfa_required') == True:
mfa_code = os.getenv("RH_MFA")
if mfa_code == "":
print("Robinhood MFA:", end=' ')
try:
input = raw_input
except NameError:
pass
mfa_code = input()
logged_in = robinhood.login(username=username, password=password, mfa_code=mfa_code)
if logged_in != True:
password = ""
print("Invalid username or password. Try again.\n")
print("Pulling trades. Please wait...")
fields = collections.defaultdict(dict)
trade_count = 0
queued_count = 0
# fetch order history and related metadata from the Robinhood API
#orders = robinhood.get_endpoint('orders')
orders = robinhood.get_endpoint('optionsOrders');
# load a debug file
# raw_json = open('debug.txt','rU').read()
# orders = ast.literal_eval(raw_json)
# store debug
if args.debug:
# save the CSV
try:
with open("debug.txt", "w+") as outfile:
outfile.write(str(orders))
print("Debug infomation written to debug.txt")
except IOError:
print('Oops. Unable to write file to debug.txt')
# Vignesh save the CSV
try:
with open("stocks.txt", "w+") as outfile:
outfile.write(str(orders))
except IOError:
print("Oops. Unable to write options file to ", filename)
#Vignesh end
# do/while for pagination
paginated = True
page = 0
row = 0
while paginated:
for i, order in enumerate(orders['results']):
for j, leg in enumerate(order['legs']):
counter = row + (page * 100)
executions = leg['executions']
#Fetch meta info such as strike price, expiration, ticker name of this order
contract = robinhood.get_custom_endpoint(leg['option'])
fields[counter]['Leg'] = j + 1
fields[counter]['Ticker'] = contract['chain_symbol']
fields[counter]['Strike_price'] = contract['strike_price']
fields[counter]['Expiration_date'] = contract['expiration_date']
# Read thro all the data under the order and add it to the csv row
for key, value in enumerate(leg):
if value != 'executions':
fields[counter][value] = leg[value]
for key, value in enumerate(order):
if value != "legs":
fields[counter][value] = order[value]
# Update trade count if order was filled to report at the end about how many trades were exported
if order['state'] == "filled":
trade_count += 1
# Since the order is filled, read all the leg and execution information such as date placed, amount paid, drag them over to csv
for key, value in enumerate(executions[0]):
fields[counter][value] = executions[0][value]
elif order['state'] == "queued":
queued_count += 1
#Add a calculation for the amount this trade will have effected on the buying power, this will help calculate total profit.
if leg['side'] == 'sell':
fields[counter]['Change_in_Buying_Power'] = order['processed_premium']
else:
fields[counter]['Change_in_Buying_Power'] = "-" + (order['processed_premium']);
row += 1
# paginate
if orders['next'] is not None:
page = page + 1
orders = robinhood.get_custom_endpoint(str(orders['next']))
else:
paginated = False
# for i in fields:
# print fields[i]
# print "-------"
# check we have trade data to export
if trade_count > 0 or queued_count > 0:
print("%d queued trade%s and %d executed trade%s found in your account." %
(queued_count, "s" [queued_count == 1:], trade_count,
"s" [trade_count == 1:]))
# print str(queued_count) + " queded trade(s) and " + str(trade_count) + " executed trade(s) found in your account."
else:
print("No trade history found in your account.")
quit()
# CSV headers
keys = fields[0].keys()
#keys = sorted(keys)
csv = ','.join(keys) + "\n"
# CSV rows
for row in fields:
for idx, key in enumerate(keys):
if (idx > 0):
csv += ","
try:
csv += str(fields[row][key])
except:
csv += ""
csv += "\n"
# choose a filename to save to
print("Choose a filename or press enter to save to `option-trades.csv`:")
try:
input = raw_input
except NameError:
pass
filename = input().strip()
if filename == '':
filename = "option-trades.csv"
# save the CSV
try:
with open(filename, "w+") as outfile:
outfile.write(csv)
except IOError:
print("Oops. Unable to write file to ", filename, ". Close the file if it is open and try again.")
if args.profit:
profit_csv = profit_extractor(csv, filename)