robinhood-api 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/robinhood.rb +228 -0
  3. metadata +45 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5eafffd0082069b55d5e87d645ec492f3f7ff820
4
+ data.tar.gz: ae43535494aded6f2384a7bdfc68bca1cc219d23
5
+ SHA512:
6
+ metadata.gz: 030ed5bc0e1af38e8e51bddf58cdb22403f47286a4064c3b624ef54a2d6206f90cd30bf748812947fb1c7e39948c2586455f11bd2446da4cef6f018517f2d78b
7
+ data.tar.gz: 9859a690e826b17d881374f2a677eb6972066cf3e4c64b9968a904ac0f6da909b2c1d618fc18ec6f154018746a9ae6185b0a233ea87ec8a3af9f0dc38eb632af
@@ -0,0 +1,228 @@
1
+ module RobinhoodModule
2
+ def self.before(*names)
3
+ names.each do |name|
4
+ m = instance_method(name)
5
+ define_method(name) do |*args, &block|
6
+ # yield
7
+ if token_compliant(name)
8
+ m.bind(self).(*args, &block)
9
+ else
10
+ puts "You have to run the login(<username>, <password>) method or a Robinhood.new instance before running the #{name} method"
11
+ exit 1
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ module RobinhoodModule
19
+ require 'httparty'
20
+ require 'json'
21
+
22
+ include HTTParty
23
+
24
+ attr_accessor :errors
25
+
26
+ def initialize
27
+ end
28
+
29
+ def login(username, password)
30
+ raw_response = HTTParty.post(
31
+ endpoints[:login],
32
+ body: {
33
+ 'password' => password,
34
+ 'username'=> username
35
+ },
36
+ headers: headers
37
+ )
38
+ response = JSON.parse(raw_response.body)
39
+ if response['token']
40
+ response = response['token']
41
+ @headers['Authorization'] = "Token #{response}"
42
+ end
43
+ return response
44
+ end
45
+
46
+ def investment_profile
47
+ raw_response = HTTParty.get(endpoints[:investment_profile], headers: headers)
48
+ JSON.parse(raw_response.body)
49
+ end
50
+
51
+ def orders(order_id=nil)
52
+ url = order_id ? "#{endpoints[:orders]}#{order_id}" : endpoints[:orders]
53
+ raw_response = HTTParty.get(url, headers: headers)
54
+ JSON.parse(raw_response.body)
55
+ end
56
+
57
+ def accounts
58
+ raw_response = HTTParty.get(endpoints[:accounts], headers: headers)
59
+ JSON.parse(raw_response.body)
60
+ end
61
+
62
+ def portfolio
63
+ raw_response = HTTParty.get("https://api.robinhood.com/accounts/#{ENV['ROBINHOOD_ACCOUNT_NUMBER']}/portfolio/", headers: headers)
64
+ JSON.parse(raw_response.body)
65
+ end
66
+
67
+ def instruments(symbol)
68
+ raw_response = HTTParty.get(endpoints[:instruments], query: {'query' => symbol.upcase}, headers: headers)
69
+ JSON.parse(raw_response.body)
70
+ end
71
+
72
+ def quote(symbol)
73
+ raw_response = HTTParty.post("https://api.robinhood.com/quotes/#{symbol}/", headers: headers)
74
+ JSON.parse(raw_response.body)
75
+ end
76
+
77
+ def buy(symbol, instrument_id, price, quantity)
78
+ raw_response = HTTParty.post(
79
+ endpoints[:orders],
80
+ body: {
81
+ 'account' => "https://api.robinhood.com/accounts/#{ENV['ROBINHOOD_ACCOUNT_NUMBER']}/",
82
+ 'instrument' => "https://api.robinhood.com/instruments/#{instrument_id}/",
83
+ 'price' => price,
84
+ 'quantity' => quantity,
85
+ 'side' => "buy",
86
+ 'symbol' => symbol,
87
+ 'time_in_force' => 'gfd',
88
+ 'trigger' => 'immediate',
89
+ 'type' => 'market'
90
+ }.to_json,
91
+ headers: headers
92
+ )
93
+ end
94
+
95
+ def limit_buy(symbol, instrument_id, price, quantity)
96
+ raw_response = HTTParty.post(
97
+ endpoints[:orders],
98
+ body: {
99
+ 'account' => "https://api.robinhood.com/accounts/#{ENV['ROBINHOOD_ACCOUNT_NUMBER']}/",
100
+ 'instrument' => "https://api.robinhood.com/instruments/#{instrument_id}/",
101
+ 'price' => price,
102
+ 'quantity' => quantity,
103
+ 'side' => "buy",
104
+ 'symbol' => symbol,
105
+ 'time_in_force' => 'gfd',
106
+ 'trigger' => 'immediate',
107
+ 'type' => 'limit'
108
+ }.to_json,
109
+ headers: headers
110
+ )
111
+ end
112
+
113
+ def sell(symbol, instrument_id, price, quantity)
114
+ raw_response = HTTParty.post(
115
+ endpoints[:orders],
116
+ body: {
117
+ 'account' => "https://api.robinhood.com/accounts/#{ENV['ROBINHOOD_ACCOUNT_NUMBER']}/",
118
+ 'instrument' => "https://api.robinhood.com/instruments/#{instrument_id}/",
119
+ 'price' => price,
120
+ 'quantity' => quantity,
121
+ 'side' => "sell",
122
+ 'symbol' => symbol,
123
+ 'time_in_force' => 'gfd',
124
+ 'trigger' => 'immediate',
125
+ 'type' => 'market'
126
+ }.to_json,
127
+ headers: headers
128
+ )
129
+ end
130
+
131
+ def limit_sell(symbol, instrument_id, price, quantity)
132
+ raw_response = HTTParty.post(
133
+ endpoints[:orders],
134
+ body: {
135
+ 'account' => "https://api.robinhood.com/accounts/#{ENV['ROBINHOOD_ACCOUNT_NUMBER']}/",
136
+ 'instrument' => "https://api.robinhood.com/instruments/#{instrument_id}/",
137
+ 'price' => price,
138
+ 'quantity' => quantity,
139
+ 'side' => "sell",
140
+ 'symbol' => symbol,
141
+ 'time_in_force' => 'gfd',
142
+ 'trigger' => 'immediate',
143
+ 'type' => 'limit'
144
+ }.to_json,
145
+ headers: headers
146
+ )
147
+ end
148
+
149
+ def stop_loss_sell(symbol, instrument_id, price, quantity)
150
+ raw_response = HTTParty.post(
151
+ endpoints[:orders],
152
+ body: {
153
+ 'account' => "https://api.robinhood.com/accounts/#{ENV['ROBINHOOD_ACCOUNT_NUMBER']}/",
154
+ 'instrument' => "https://api.robinhood.com/instruments/#{instrument_id}/",
155
+ 'stop_price' => price,
156
+ 'quantity' => quantity,
157
+ 'side' => "sell",
158
+ 'symbol' => symbol,
159
+ 'time_in_force' => 'gtc',
160
+ 'trigger' => 'stop',
161
+ 'type' => 'market'
162
+ }.to_json,
163
+ headers: headers
164
+ )
165
+ end
166
+
167
+ def cancel_order(order_id)
168
+ raw_response = HTTParty.post("https://api.robinhood.com/orders/#{order_id}/cancel/", headers: headers)
169
+ raw_response.code == 200
170
+ end
171
+
172
+ def positions(instrument_id)
173
+ raw_response = HTTParty.get("https://api.robinhood.com/accounts/#{ENV['ROBINHOOD_ACCOUNT_NUMBER']}/positions/#{instrument_id}/", headers: headers)
174
+ JSON.parse(raw_response.body)
175
+ end
176
+
177
+ private
178
+
179
+ def endpoints
180
+ {
181
+ login: 'https://api.robinhood.com/api-token-auth/',
182
+ investment_profile: 'https://api.robinhood.com/user/investment_profile/',
183
+ accounts: 'https://api.robinhood.com/accounts/',
184
+ ach_iav_auth: 'https://api.robinhood.com/ach/iav/auth/',
185
+ ach_relationships: 'https://api.robinhood.com/ach/relationships/',
186
+ ach_transfers: 'https://api.robinhood.com/ach/transfers/',
187
+ applications: 'https://api.robinhood.com/applications/',
188
+ dividends: 'https://api.robinhood.com/dividends/',
189
+ edocuments: 'https://api.robinhood.com/documents/',
190
+ instruments: 'https://api.robinhood.com/instruments/',
191
+ margin_upgrade: 'https://api.robinhood.com/margin/upgrades/',
192
+ markets: 'https://api.robinhood.com/markets/',
193
+ notifications: 'https://api.robinhood.com/notifications/',
194
+ orders: 'https://api.robinhood.com/orders/',
195
+ password_reset: 'https://api.robinhood.com/password_reset/request/',
196
+ quotes: 'https://api.robinhood.com/quotes/',
197
+ document_requests: 'https://api.robinhood.com/upload/document_requests/',
198
+ user: 'https://api.robinhood.com/user/',
199
+ watchlists: 'https://api.robinhood.com/watchlists/'
200
+ }
201
+ end
202
+
203
+ def headers
204
+ @headers ||= {
205
+ 'Accept' => 'application/json',
206
+ }
207
+ end
208
+
209
+ def token_compliant(method)
210
+ methodlist = [:investment_profile, :accounts, :ach_iav_auth, :ach_relationships, :ach_transfers, :applications, :dividends, :edocuments, :margin_upgrade, :notifications, :orders, :password_reset, :document_requests, :user, :watchlists]
211
+
212
+ if methodlist.include?(method)
213
+ if headers.key?('Authorization')
214
+ return true
215
+ else
216
+ return false
217
+ end
218
+ else
219
+ return true
220
+ end
221
+ end
222
+
223
+ before(*instance_methods) { puts "start" }
224
+ end
225
+
226
+ class Robinhood
227
+ include RobinhoodModule
228
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: robinhood-api
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - Thomas Alcala
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: 'Get the most of Robinhood: get accounts, positions, portfoligo, buy
14
+ and sell quotes, etc.'
15
+ email: thomas.alcala@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/robinhood.rb
21
+ homepage: https://github.com/ThomasMarcel/robinhood-api
22
+ licenses:
23
+ - MIT
24
+ metadata: {}
25
+ post_install_message:
26
+ rdoc_options: []
27
+ require_paths:
28
+ - lib
29
+ required_ruby_version: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ required_rubygems_version: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 2.6.11
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: Calling the Robinhood API
45
+ test_files: []