oanda_api 0.9.5 → 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +15 -0
  4. data/CHANGELOG.md +24 -9
  5. data/Gemfile +2 -3
  6. data/README.md +11 -9
  7. data/lib/oanda_api.rb +1 -0
  8. data/lib/oanda_api/client/client.rb +13 -7
  9. data/lib/oanda_api/configuration.rb +57 -24
  10. data/lib/oanda_api/resource/order.rb +5 -6
  11. data/lib/oanda_api/resource/transaction.rb +3 -4
  12. data/lib/oanda_api/resource_collection.rb +4 -2
  13. data/lib/oanda_api/streaming/request.rb +6 -1
  14. data/lib/oanda_api/throttling/throttling.rb +105 -0
  15. data/lib/oanda_api/version.rb +1 -1
  16. data/oanda_api.gemspec +4 -4
  17. data/spec/fixtures/vcr_cassettes/accounts_get.yml +7 -5
  18. data/spec/fixtures/vcr_cassettes/accounts_id_get.yml +18 -14
  19. data/spec/fixtures/vcr_cassettes/calendar_events_period_get.yml +20 -14
  20. data/spec/fixtures/vcr_cassettes/calendar_instrument_and_period_get.yml +24 -21
  21. data/spec/fixtures/vcr_cassettes/calendar_period_get.yml +20 -14
  22. data/spec/fixtures/vcr_cassettes/candles_options_get.yml +12 -10
  23. data/spec/fixtures/vcr_cassettes/client_helper_accounts.yml +48 -5
  24. data/spec/fixtures/vcr_cassettes/instrument_EUR_USD.yml +11 -9
  25. data/spec/fixtures/vcr_cassettes/instrument_USD_JPY.yml +10 -8
  26. data/spec/fixtures/vcr_cassettes/instruments_get.yml +25 -19
  27. data/spec/fixtures/vcr_cassettes/instruments_options_get.yml +8 -6
  28. data/spec/fixtures/vcr_cassettes/order_id_close.yml +159 -313
  29. data/spec/fixtures/vcr_cassettes/order_id_get.yml +103 -21
  30. data/spec/fixtures/vcr_cassettes/order_options_create.yml +9 -7
  31. data/spec/fixtures/vcr_cassettes/order_options_update.yml +62 -20
  32. data/spec/fixtures/vcr_cassettes/orders_get.yml +46 -137
  33. data/spec/fixtures/vcr_cassettes/orders_options_get.yml +29 -50
  34. data/spec/fixtures/vcr_cassettes/positions_get.yml +19 -15
  35. data/spec/fixtures/vcr_cassettes/positions_instrument_close.yml +35 -27
  36. data/spec/fixtures/vcr_cassettes/positions_instrument_get.yml +17 -13
  37. data/spec/fixtures/vcr_cassettes/prices_options_get.yml +12 -10
  38. data/spec/fixtures/vcr_cassettes/spread_history_get.yml +17 -13
  39. data/spec/fixtures/vcr_cassettes/spreads_get.yml +17 -13
  40. data/spec/fixtures/vcr_cassettes/trade_id_close.yml +115 -52
  41. data/spec/fixtures/vcr_cassettes/trade_id_get.yml +278 -16
  42. data/spec/fixtures/vcr_cassettes/trade_options_modify.yml +58 -16
  43. data/spec/fixtures/vcr_cassettes/trades_filter_get.yml +44 -19
  44. data/spec/fixtures/vcr_cassettes/trades_get.yml +55 -16
  45. data/spec/fixtures/vcr_cassettes/transaction_id_get.yml +271 -149
  46. data/spec/fixtures/vcr_cassettes/transactions_options_get.yml +258 -133
  47. data/spec/fixtures/vcr_cassettes/with_throttling_and_max_requests_per_second.yml +28 -22
  48. data/spec/fixtures/vcr_cassettes/with_throttling_new_connections.yml +443 -0
  49. data/spec/fixtures/vcr_cassettes/with_throttling_with_multiple_threads.yml +57 -45
  50. data/spec/fixtures/vcr_cassettes/without_throttling.yml +91 -71
  51. data/spec/oanda_api/configuration_spec.rb +31 -0
  52. data/spec/oanda_api/examples/request_throttling_spec.rb +39 -4
  53. data/spec/oanda_api/examples/spread_history_spec.rb +3 -3
  54. data/spec/oanda_api/resource_collection_spec.rb +9 -0
  55. data/spec/oanda_api/streaming/client_spec.rb +5 -5
  56. data/spec/oanda_api/streaming/request_spec.rb +23 -8
  57. data/spec/spec_helper.rb +0 -3
  58. data/spec/support/client_helper.rb +6 -2
  59. metadata +13 -12
  60. data/spec/fixtures/vcr_cassettes/client_helper_account.yml +0 -45
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 917e6e85db408d8170f0ca102acdeb9cb4317d32
4
- data.tar.gz: eb4b600f105084b22ae46d7575ed087f5333f1b4
3
+ metadata.gz: fe9221763d8af2c5e760f9bf92f39a87d134b0dd
4
+ data.tar.gz: b3120a6829a80db2d462367edc8ba2bbbc936121
5
5
  SHA512:
6
- metadata.gz: 0c71a4f00c50f36066e7ed8c1d36333e4b171a0bc57f5fe07484ede19207bfc497a8c15f8623120aac2464e2bcdef075207aee6750592884dc18c7de6693e814
7
- data.tar.gz: e539247dc8ab06155d0d87844e81e85650a52b7e8be08de01491429a0171000de410e23b16bc1f9d1acbca8549bd69916122776ed012ac556abf6082c1a01ba5
6
+ metadata.gz: 95fbda40ef9be5550d5ff7e5ec36e7a3dcb51a3461eabef9b984b2ab429c779942e7c796cea3c1644460ef5d59538fa82d6942cccff1f61c25f6f86c61b4da61
7
+ data.tar.gz: 025b92634204f157b543275075a98afdee985bfbd83dfc643f280622038a7987c67057c0028586fd2771a0f3f4b4d35767af869b5669f751a9c073697e61441b
data/.gitignore CHANGED
@@ -36,3 +36,4 @@ spec/reports
36
36
  .rubocop*
37
37
  .rvmrc
38
38
  .yardoc
39
+ .byebug_history
@@ -0,0 +1,15 @@
1
+ env:
2
+ global:
3
+ - OANDA_API_TESTING_TOKEN=test
4
+ language: ruby
5
+ rvm:
6
+ - 2.4.0
7
+ before_script:
8
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
9
+ - chmod +x ./cc-test-reporter
10
+ - ./cc-test-reporter before-build
11
+ script:
12
+ - bundle exec rspec
13
+ after_script:
14
+ - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
15
+
@@ -1,5 +1,20 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.9.6
4
+ * 2018-01-12 Fix streaming issue [#18](https://github.com/nukeproof/oanda_api/issues/18) Thanks [josacar](https://github.com/josacar)!
5
+ * 2018-01-10 Add support for latest version of httparty (0.15). Support Ruby MRI 2.4 & 2.5. Fixes [#19](https://github.com/nukeproof/oanda_api/issues/19)
6
+ * 2016-06-06 Fixed request rate throttling to correct calculation of wait times. Prior to this fix, under heavy loads from multiple threads, wait times could be calculated incorrectly and result in excessive delays between requests. Thanks [LifeBCE](https://github.com/lifeBCE)!
7
+ * 2016-04-11 Added support for rate limiting new connections. See [Connection Limits](http://developer.oanda.com/rest-live/best-practices/#connection_limits) for details on limits. Rate limiting is NOT enabled by default. To enable rate limiting:
8
+
9
+ ```ruby
10
+ OandaAPI.configure do |config|
11
+ config.use_request_throttling = true
12
+ config.max_new_connections_per_second = 1
13
+ end
14
+ ```
15
+
16
+ `config.use_request_throttling = true` can prevent exceeding Oanda's limit on the rate of creating new connections (you'll receive an HTTP 429 response, and a message stating: "Rate limit violation of newly established connections" if you exceed the limit). Note that this is a completely separate rate limit from the maximum number of requests allowed per second on an established connection (use `config.max_requests_per_second` to configure that).
17
+
3
18
  ## 0.9.5
4
19
  * 2016-03-18 Fixed `OandaAPI::Resource::Order#initialize` to correctly initialize `#order_opened`, `#trade_opened`, `#trade_reduced`, and `#trades_closed` from the response data.
5
20
 
@@ -9,23 +24,23 @@
9
24
  require 'oanda_api'
10
25
  # If you want to use sugar like: 1.day, 1.hour, 1.week, etc.
11
26
  require 'active_support/core_ext/numeric/time'
12
-
13
- client = OandaAPI::Client::TokenClient.new(:practice, ENV.fetch("OANDA_PRACTICE_TOKEN"))
27
+
28
+ client = OandaAPI::Client::TokenClient.new(:practice, ENV.fetch("OANDA_PRACTICE_TOKEN"))
14
29
  spreads = client.spreads(instrument: "EUR_USD", period: 1.day).get
15
-
30
+
16
31
  spreads.class # OandaAPI::Resource::Labs::SpreadHistory
17
32
  spreads.averages.size # => 94
18
33
  spreads.maximums.size # => 76
19
34
  spreads.averages.size # => 50
20
-
35
+
21
36
  spreads.averages.first.spread # => 1.81711
22
37
  spreads.averages.first.timestamp # => 1458081900
23
38
  spreads.averages.first.time # => 2016-03-15 23:00:00 UTC
24
-
39
+
25
40
  spreads.maximums.first.spread # => 2.1
26
41
  spreads.maximums.first.timestamp # => 1458082800
27
42
  spreads.maximums.first.time # => 2016-03-15 23:00:00 UTC
28
-
43
+
29
44
  spreads.minimums.first.spread # => 1.6
30
45
  spreads.minimums.first.timestamp # => 1458081900
31
46
  spreads.minimums.first.time # => 2016-03-15 23:00:00 UTC
@@ -43,9 +58,9 @@
43
58
  require 'oanda_api'
44
59
  # If you want to use sugar like: 1.day, 1.hour, 1.week, etc.
45
60
  require 'active_support/core_ext/numeric/time'
46
-
61
+
47
62
  client = OandaAPI::Client::TokenClient.new(:practice, ENV.fetch("OANDA_PRACTICE_TOKEN"))
48
-
63
+
49
64
  client.calendar_events(period: 1.day).get.each do |event|
50
65
  event.class # => OandaAPI::Resource::CalendarEvent
51
66
  event.title # => "Industrial Production"
@@ -60,7 +75,7 @@
60
75
  event.time # => 2016-03-08 07:00:00 UTC
61
76
  end
62
77
  ```
63
-
78
+
64
79
  * 2016-03-14 Deprecated `OandaAPI::Client::UsernameClient`. The `http://api-sandbox.oanda.com/` endpoint that this client used is no longer supported by Oanda. Instead, you can use `OandaAPI::Client::TokenClient` with a practice account.
65
80
 
66
81
  ## 0.9.4
data/Gemfile CHANGED
@@ -16,7 +16,6 @@ end
16
16
 
17
17
  group :test do
18
18
  gem "simplecov", :require => false
19
- gem "codeclimate-test-reporter", :group => :test, :require => nil
20
- # gem "yajl-ruby" # install this if you're running under mri or rubinius
21
- # gem "gson" # install this if you're running under jruby
19
+ # gem "yajl-ruby" # install this if you're running under mri or rubinius
20
+ # gem "gson" # install this if you're running under jruby
22
21
  end
data/README.md CHANGED
@@ -2,9 +2,10 @@
2
2
  [![Gem Version](https://badge.fury.io/rb/oanda_api.svg)](https://rubygems.org/gems/oanda_api)
3
3
  [![Code Climate](https://codeclimate.com/github/nukeproof/oanda_api/badges/gpa.svg)](https://codeclimate.com/github/nukeproof/oanda_api)
4
4
  [![Test Coverage](https://codeclimate.com/github/nukeproof/oanda_api/badges/coverage.svg)](https://codeclimate.com/github/nukeproof/oanda_api)
5
+ [![Build Status](https://travis-ci.org/nukeproof/oanda_api.svg?branch=master)](https://travis-ci.org/nukeproof/oanda_api)
5
6
 
6
7
  Access Oanda FX accounts, get market data, trade, build trading strategies using Ruby.
7
- ## Synopsis
8
+ ## Synopsis
8
9
  OandaAPI is a simple Ruby wrapper for the [Oanda REST API](http://developer.oanda.com/rest-live/introduction/).
9
10
 
10
11
  This style of API wrapper is typically called a [fluent](http://en.wikipedia.org/wiki/Fluent_interface) interface. The wrapper translates native Ruby objects to and from JSON representations that the API understands.
@@ -12,8 +13,8 @@ This style of API wrapper is typically called a [fluent](http://en.wikipedia.org
12
13
  For example,
13
14
 
14
15
  ```ruby
15
- client = OandaAPI::Client::TokenClient.new(:practice, "practice_account_token")
16
- account = client.account(12345).get
16
+ client = OandaAPI::Client::TokenClient.new(:practice, "practice_account_token")
17
+ account = client.account(12345).get
17
18
  ```
18
19
 
19
20
  returns an `OandaAPI::Resource::Account`, with method accessors for all of the [Account](http://developer.oanda.com/rest-live/accounts/) attributes defined by the Oanda API.
@@ -85,7 +86,7 @@ require 'oanda_api'
85
86
  client = OandaAPI::Client::TokenClient.new(:practice, ENV.fetch("OANDA_PRACTICE_TOKEN"))
86
87
 
87
88
  order = client.account(12345)
88
- .order(instrument: "USD_JPY",
89
+ .order(instrument: "USD_JPY",
89
90
  type: "market",
90
91
  side: "buy",
91
92
  units: 10_000)
@@ -93,7 +94,7 @@ order = client.account(12345)
93
94
 
94
95
  order.price # => 114.887
95
96
  order.time # => 2014-12-20 21:25:57 UTC
96
- order.trade_opened.id # => 175491416
97
+ order.trade_opened.id # => 175491416
97
98
  ```
98
99
 
99
100
  ### Closing a position
@@ -107,7 +108,7 @@ position = account.position("USD_JPY").get # => OandaAPI::Resource::Position
107
108
 
108
109
  position.ave_price # => 114.898
109
110
  position.side # => "buy"
110
- position.units # => 30_000
111
+ position.units # => 30_000
111
112
 
112
113
  # Close out the 30_000 long position
113
114
  closed_position = account.position("USD_JPY").close # => OandaAPI::Resource::Position
@@ -153,7 +154,7 @@ OandaAPI also supports the [Oanda realtime streaming API](http://developer.oanda
153
154
  For example to stream live prices,
154
155
 
155
156
  ```ruby
156
- client = OandaAPI::Streaming::Client.new(:practice, ENV.fetch("OANDA_PRACTICE_TOKEN"))
157
+ client = OandaAPI::Streaming::Client.new(:practice, ENV.fetch("OANDA_PRACTICE_TOKEN"))
157
158
  prices = client.prices(account_id: 1234, instruments: %w[AUD_CAD AUD_CHF])
158
159
  prices.stream do |price|
159
160
  # Note: The code in this block should handle the price
@@ -161,7 +162,7 @@ prices.stream do |price|
161
162
  # For example, you could publish the tick on a queue to be handled
162
163
  # by some other thread or process.
163
164
  price # => OandaAPI::Resource::Price
164
- end
165
+ end
165
166
  ```
166
167
 
167
168
 
@@ -229,6 +230,7 @@ OandaAPI.configure do |config|
229
230
  config.use_compression = true
230
231
  config.use_request_throttling = true
231
232
  config.max_requests_per_second = 10
233
+ config.max_new_connections_per_second = 1
232
234
  end
233
235
  ```
234
236
 
@@ -240,7 +242,7 @@ OandaAPI works with Ruby 2.0 and higher.
240
242
  Tested on:
241
243
 
242
244
  * MRI 2.1, 2.2, 2.3
243
- * JRuby 1.7, 9.0.0.0.pre
245
+ * JRuby 9.0.0, 9.0.5
244
246
  * Rubinius 2.4, 2.5
245
247
 
246
248
  Contributing
@@ -29,4 +29,5 @@ require_relative 'oanda_api/resource/transaction'
29
29
  require_relative 'oanda_api/resource/transaction_history'
30
30
  require_relative 'oanda_api/resource/labs/calendar_event'
31
31
  require_relative 'oanda_api/resource/labs/spread_history'
32
+ require_relative 'oanda_api/throttling/throttling'
32
33
  require_relative 'oanda_api/version'
@@ -116,9 +116,9 @@ module OandaAPI
116
116
  params_key => Utils.stringify_keys(conditions.merge(default_params)),
117
117
  :headers => OandaAPI.configuration.headers.merge(headers),
118
118
  :open_timeout => OandaAPI.configuration.open_timeout,
119
- :read_timeout => OandaAPI.configuration.read_timeout
119
+ :read_timeout => OandaAPI.configuration.read_timeout,
120
+ :timeout => OandaAPI.configuration.open_timeout
120
121
  end
121
-
122
122
  handle_response response, resource_descriptor
123
123
  rescue Http::Exceptions::HttpException => e
124
124
  raise OandaAPI::RequestError, e.message
@@ -159,10 +159,15 @@ module OandaAPI
159
159
  #
160
160
  # @return [void]
161
161
  def self.throttle_request_rate
162
+ last_request_time = last_request_at
162
163
  now = Time.now
163
- delta = now - (last_request_at || now)
164
- _throttle(delta, now) if delta < OandaAPI.configuration.min_request_interval &&
165
- OandaAPI.configuration.use_request_throttling?
164
+
165
+ if last_request_time
166
+ delta = now - last_request_time
167
+ _throttle(delta, now) if delta < OandaAPI.configuration.min_request_interval &&
168
+ OandaAPI.configuration.use_request_throttling?
169
+ end
170
+
166
171
  self.last_request_at = Time.now
167
172
  end
168
173
 
@@ -205,9 +210,10 @@ module OandaAPI
205
210
  # @return [OandaAPI::ResourceBase, OandaAPI::ResourceCollection] see {#execute_request}
206
211
  def handle_response(response, resource_descriptor)
207
212
  if resource_descriptor.is_collection?
208
- ResourceCollection.new response, resource_descriptor
213
+ location = response.respond_to?(:location) ? response.location : nil
214
+ ResourceCollection.new response.parsed_response, resource_descriptor, location: location
209
215
  else
210
- resource_descriptor.resource_klass.new response
216
+ resource_descriptor.resource_klass.new response.parsed_response
211
217
  end
212
218
  end
213
219
 
@@ -3,15 +3,16 @@ module OandaAPI
3
3
 
4
4
  # Configures client API settings.
5
5
  class Configuration
6
- DATETIME_FORMAT = :rfc3339
7
- LABS_API_VERSION = "labs/v1"
8
- MAX_REQUESTS_PER_SECOND = 15
9
- OPEN_TIMEOUT = 10
10
- READ_TIMEOUT = 10
11
- REST_API_VERSION = "v1"
12
- USE_COMPRESSION = false
13
- USE_REQUEST_THROTTLING = false
14
- CONNECTION_POOL_SIZE = 2
6
+ DATETIME_FORMAT = :rfc3339
7
+ LABS_API_VERSION = "labs/v1"
8
+ MAX_NEW_CONNECTIONS_PER_SECOND = 2
9
+ MAX_REQUESTS_PER_SECOND = 15
10
+ OPEN_TIMEOUT = 10
11
+ READ_TIMEOUT = 10
12
+ REST_API_VERSION = "v1"
13
+ USE_COMPRESSION = false
14
+ USE_REQUEST_THROTTLING = false
15
+ CONNECTION_POOL_SIZE = 2
15
16
 
16
17
  # Maximum size of the persistent connection pool.
17
18
  # @return [Numeric]
@@ -27,7 +28,7 @@ module OandaAPI
27
28
  end
28
29
 
29
30
  # The format in which dates will be returned by the API (`:rfc3339` or `:unix`).
30
- # See the Oanda Development Guide for more details about {http://developer.oanda.com/rest-live/development-guide/#date_Time_Format DateTime formats}.
31
+ # See the Oanda Development Guide for more details about {http://developer.oanda.com/rest-live/development-guide/#date_Time_Format DateTime formats}.
31
32
  # @return [Symbol]
32
33
  def datetime_format
33
34
  @datetime_format ||= DATETIME_FORMAT
@@ -54,8 +55,34 @@ module OandaAPI
54
55
  @labs_api_version = value
55
56
  end
56
57
 
58
+ # The maximum number of new connections per second allowed to be made
59
+ # to the API. Only enforced if {#use_request_throttling?} is `true`.
60
+ #
61
+ # @return [Numeric]
62
+ def max_new_connections_per_second
63
+ @max_new_connections_per_second ||= MAX_NEW_CONNECTIONS_PER_SECOND
64
+ end
65
+
66
+ # See {#max_new_connections_per_second}.
67
+ # @param [Numeric] value
68
+ # @return [void]
69
+ def max_new_connections_per_second=(value)
70
+ fail ArgumentError, "must be a number > 0" unless value.is_a?(Numeric) && value > 0
71
+ @min_new_connection_interval = nil
72
+ @max_new_connections_per_second = value
73
+ end
74
+
75
+ # The minimum amount of time in seconds that must elapse between
76
+ # new connection attempts to the API.
77
+ # Determined by {#max_new_connections_per_second}. Only enforced if
78
+ # {#use_request_throttling?} is `true`.
79
+ # @return [Float]
80
+ def min_new_connection_interval
81
+ @min_new_connection_interval ||= (1.0 / max_new_connections_per_second)
82
+ end
83
+
57
84
  # The maximum number of requests per second allowed to be made through the
58
- # API. Only enforced if {#use_request_throttling?} is `true`.
85
+ # API. Only enforced if {#use_request_throttling?} is `true`.
59
86
  #
60
87
  # @return [Numeric]
61
88
  def max_requests_per_second
@@ -71,15 +98,17 @@ module OandaAPI
71
98
  @max_requests_per_second = value
72
99
  end
73
100
 
74
- # The minimum amount of time in seconds that must elapse between consecutive requests to the API.
75
- # Determined by {#max_requests_per_second}. Only enforced if {#use_request_throttling?} is `true`.
101
+ # The minimum amount of time in seconds that must elapse between
102
+ # consecutive requests to the API. Determined by
103
+ # {#max_requests_per_second}. Only enforced if {#use_request_throttling?}
104
+ # is `true`.
76
105
  # @return [Float]
77
106
  def min_request_interval
78
107
  @min_request_interval ||= (1.0 / max_requests_per_second)
79
108
  end
80
109
 
81
- # The number of seconds the client waits for a new HTTP connection to be established before
82
- # raising a timeout exception.
110
+ # The number of seconds the client waits for a new HTTP connection to be
111
+ # established before raising a timeout exception.
83
112
  # @return [Numeric]
84
113
  def open_timeout
85
114
  @open_timeout ||= OPEN_TIMEOUT
@@ -94,7 +123,7 @@ module OandaAPI
94
123
  end
95
124
 
96
125
  # The number of seconds the client waits for a response from the API before
97
- # raising a timeout exception.
126
+ # raising a timeout exception.
98
127
  # @return [Numeric]
99
128
  def read_timeout
100
129
  @read_timeout ||= READ_TIMEOUT
@@ -121,8 +150,9 @@ module OandaAPI
121
150
  @rest_api_version = value
122
151
  end
123
152
 
124
- # Specifies whether the API uses compressed responses. See the Oanda Development Guide
125
- # for more information about {http://developer.oanda.com/rest-live/best-practices/#compression compression}.
153
+ # Specifies whether the API uses compressed responses. See the Oanda
154
+ # Development Guide for more information about
155
+ # {http://developer.oanda.com/rest-live/best-practices/#compression compression}.
126
156
  #
127
157
  # @return [Boolean]
128
158
  def use_compression
@@ -140,12 +170,12 @@ module OandaAPI
140
170
  end
141
171
 
142
172
  # Throttles the rate of requests made to the API. See the Oanda Developers
143
- # Guide for information about
144
- # {http://developer.oanda.com/rest-live/best-practices/ connection limits}.
145
- # If enabled, requests will not exceed {#max_requests_per_second}. If the
146
- # rate of requests received by the client exceeds this limit, the client
147
- # delays the rate-exceeding request for the minimum amount of time needed
148
- # to satisfy the rate limit.
173
+ # Guide for information about
174
+ # {http://developer.oanda.com/rest-live/best-practices/ connection limits}.
175
+ # If enabled, requests will not exceed {#max_requests_per_second}. If the
176
+ # rate of requests received by the client exceeds this limit, the client
177
+ # delays the rate-exceeding request for the minimum amount of time needed
178
+ # to satisfy the rate limit.
149
179
  #
150
180
  # @return [Boolean]
151
181
  def use_request_throttling
@@ -160,6 +190,9 @@ module OandaAPI
160
190
  # @return [void]
161
191
  def use_request_throttling=(value)
162
192
  @use_request_throttling = !!value
193
+ #
194
+ # See OandaAPI::Throttling
195
+ Net::HTTP.limit_connection_rate !!value
163
196
  end
164
197
 
165
198
  # @private
@@ -22,12 +22,11 @@ module OandaAPI
22
22
  :upper_bound
23
23
 
24
24
  def initialize(attributes = {})
25
- attribs = attributes.dup
26
- self.order_opened = attribs.delete(:order_opened) || {}
27
- self.trade_opened = attribs.delete(:trade_opened) || {}
28
- self.trade_reduced = attribs.delete(:trade_reduced) || {}
29
- self.trades_closed = attribs.delete(:trades_closed) || []
30
- super attribs
25
+ self.order_opened = {}
26
+ self.trade_opened = {}
27
+ self.trade_reduced = {}
28
+ self.trades_closed = []
29
+ super
31
30
  end
32
31
 
33
32
  def expiry=(v)
@@ -31,10 +31,9 @@ module OandaAPI
31
31
  :upper_bound
32
32
 
33
33
  def initialize(attributes = {})
34
- attribs = attributes.dup
35
- self.trade_opened = attribs.delete(:trade_opened) || {}
36
- self.trade_reduced = attribs.delete(:trade_reduced) || {}
37
- super attribs
34
+ self.trade_opened = {}
35
+ self.trade_reduced = {}
36
+ super
38
37
  end
39
38
 
40
39
  def expiry=(v)
@@ -26,7 +26,9 @@ module OandaAPI
26
26
  #
27
27
  # @param [OandaAPI::Client::ResourceDescriptor] resource_descriptor metadata
28
28
  # about the resource collection and its elements.
29
- def initialize(attributes, resource_descriptor)
29
+ #
30
+ # @param [String] location optional may contain a URI to related resources
31
+ def initialize(attributes, resource_descriptor, location:nil)
30
32
  attributes = {} if attributes.nil? || attributes.respond_to?(:empty) && attributes.empty?
31
33
  if attributes.kind_of?(Array)
32
34
  h = {}
@@ -38,7 +40,7 @@ module OandaAPI
38
40
  @attributes = Utils.rubyize_keys attributes
39
41
  @collection = @attributes.delete(resource_descriptor.collection_name) || []
40
42
  @collection.map! { |resource| resource_descriptor.resource_klass.new resource }
41
- @location = attributes.location if attributes.respond_to? :location
43
+ @location = location
42
44
  end
43
45
 
44
46
  # @yield [OandaAPI::ResourceBase]
@@ -89,11 +89,16 @@ module OandaAPI
89
89
  @running = true
90
90
  # @http.set_debug_output $stderr
91
91
  @http.request(@request) do |response|
92
+ buffer = ""
92
93
  response.read_body do |chunk|
93
- handle_response(chunk).each do |resource|
94
+ buffer << chunk
95
+ next unless chunk.match(/\r\n\Z/)
96
+ buffer.gsub!(/\r\n/,"")
97
+ handle_response(buffer).each do |resource|
94
98
  block.call(resource, @client)
95
99
  return if stop_requested?
96
100
  end
101
+ buffer = ""
97
102
  return if stop_requested?
98
103
  sleep 0.01
99
104
  end