oanda_api 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +67 -6
  3. data/README.md +31 -3
  4. data/lib/oanda_api.rb +3 -1
  5. data/lib/oanda_api/client/client.rb +17 -12
  6. data/lib/oanda_api/client/namespace_proxy.rb +2 -2
  7. data/lib/oanda_api/client/resource_descriptor.rb +25 -9
  8. data/lib/oanda_api/client/username_client.rb +7 -0
  9. data/lib/oanda_api/configuration.rb +14 -0
  10. data/lib/oanda_api/resource/account.rb +22 -3
  11. data/lib/oanda_api/resource/candle.rb +1 -1
  12. data/lib/oanda_api/resource/labs/calendar_event.rb +25 -0
  13. data/lib/oanda_api/resource/labs/spread_history.rb +61 -0
  14. data/lib/oanda_api/resource/order.rb +4 -4
  15. data/lib/oanda_api/resource/transaction_history.rb +0 -1
  16. data/lib/oanda_api/resource_base.rb +64 -2
  17. data/lib/oanda_api/resource_collection.rb +6 -0
  18. data/lib/oanda_api/streaming/client.rb +1 -0
  19. data/lib/oanda_api/version.rb +1 -1
  20. data/oanda_api.gemspec +2 -2
  21. data/spec/fixtures/vcr_cassettes/accounts_get.yml +13 -79
  22. data/spec/fixtures/vcr_cassettes/accounts_id_get.yml +23 -125
  23. data/spec/fixtures/vcr_cassettes/calendar_events_period_get.yml +54 -0
  24. data/spec/fixtures/vcr_cassettes/calendar_instrument_and_period_get.yml +61 -0
  25. data/spec/fixtures/vcr_cassettes/calendar_period_get.yml +54 -0
  26. data/spec/fixtures/vcr_cassettes/candles_options_get.yml +9 -45
  27. data/spec/fixtures/vcr_cassettes/client_helper_account.yml +45 -0
  28. data/spec/fixtures/vcr_cassettes/client_helper_accounts.yml +45 -0
  29. data/spec/fixtures/vcr_cassettes/instrument_EUR_USD.yml +42 -0
  30. data/spec/fixtures/vcr_cassettes/instrument_USD_JPY.yml +42 -0
  31. data/spec/fixtures/vcr_cassettes/instruments_get.yml +37 -303
  32. data/spec/fixtures/vcr_cassettes/instruments_options_get.yml +6 -43
  33. data/spec/fixtures/vcr_cassettes/order_id_close.yml +448 -0
  34. data/spec/fixtures/vcr_cassettes/order_id_get.yml +84 -0
  35. data/spec/fixtures/vcr_cassettes/order_options_create.yml +42 -0
  36. data/spec/fixtures/vcr_cassettes/order_options_update.yml +82 -0
  37. data/spec/fixtures/vcr_cassettes/orders_get.yml +205 -0
  38. data/spec/fixtures/vcr_cassettes/orders_options_get.yml +120 -0
  39. data/spec/fixtures/vcr_cassettes/positions_get.yml +82 -0
  40. data/spec/fixtures/vcr_cassettes/positions_instrument_close.yml +154 -0
  41. data/spec/fixtures/vcr_cassettes/{account_id_order_options_create.yml → positions_instrument_get.yml} +24 -18
  42. data/spec/fixtures/vcr_cassettes/prices_options_get.yml +11 -48
  43. data/spec/fixtures/vcr_cassettes/spread_history_get.yml +53 -0
  44. data/spec/fixtures/vcr_cassettes/spreads_get.yml +53 -0
  45. data/spec/fixtures/vcr_cassettes/trade_id_close.yml +277 -0
  46. data/spec/fixtures/vcr_cassettes/trade_id_get.yml +82 -0
  47. data/spec/fixtures/vcr_cassettes/trade_options_modify.yml +80 -0
  48. data/spec/fixtures/vcr_cassettes/trades_filter_get.yml +90 -0
  49. data/spec/fixtures/vcr_cassettes/trades_get.yml +171 -0
  50. data/spec/fixtures/vcr_cassettes/transaction_id_get.yml +248 -0
  51. data/spec/fixtures/vcr_cassettes/transactions_options_get.yml +202 -0
  52. data/spec/fixtures/vcr_cassettes/with_throttling_and_max_requests_per_second.yml +25 -19
  53. data/spec/fixtures/vcr_cassettes/with_throttling_with_multiple_threads.yml +51 -39
  54. data/spec/fixtures/vcr_cassettes/without_throttling.yml +81 -61
  55. data/spec/oanda_api/client/client_spec.rb +23 -10
  56. data/spec/oanda_api/client/namespace_proxy_spec.rb +1 -1
  57. data/spec/oanda_api/client/resource_descriptor_spec.rb +45 -14
  58. data/spec/oanda_api/configuration_spec.rb +13 -0
  59. data/spec/oanda_api/examples/accounts_spec.rb +0 -7
  60. data/spec/oanda_api/examples/calendar_spec.rb +27 -0
  61. data/spec/oanda_api/examples/orders_spec.rb +12 -12
  62. data/spec/oanda_api/examples/positions_spec.rb +3 -3
  63. data/spec/oanda_api/examples/rates_spec.rb +4 -2
  64. data/spec/oanda_api/examples/spread_history_spec.rb +32 -0
  65. data/spec/oanda_api/examples/trades_spec.rb +5 -5
  66. data/spec/oanda_api/examples/transactions_spec.rb +2 -2
  67. data/spec/oanda_api/resource_base_spec.rb +48 -8
  68. data/spec/oanda_api/streaming/client_spec.rb +30 -2
  69. data/spec/spec_helper.rb +1 -1
  70. data/spec/support/client_helper.rb +45 -11
  71. data/spec/support/vcr.rb +1 -0
  72. metadata +63 -49
  73. data/spec/fixtures/vcr_cassettes/account_id_order_id_close.yml +0 -264
  74. data/spec/fixtures/vcr_cassettes/account_id_order_id_get.yml +0 -114
  75. data/spec/fixtures/vcr_cassettes/account_id_order_options_update.yml +0 -112
  76. data/spec/fixtures/vcr_cassettes/account_id_orders_get.yml +0 -118
  77. data/spec/fixtures/vcr_cassettes/account_id_orders_options_get.yml +0 -123
  78. data/spec/fixtures/vcr_cassettes/account_id_positions_get.yml +0 -112
  79. data/spec/fixtures/vcr_cassettes/account_id_positions_instrument_close.yml +0 -214
  80. data/spec/fixtures/vcr_cassettes/account_id_positions_instrument_get.yml +0 -110
  81. data/spec/fixtures/vcr_cassettes/account_id_trade_id_close.yml +0 -252
  82. data/spec/fixtures/vcr_cassettes/account_id_trade_id_get.yml +0 -112
  83. data/spec/fixtures/vcr_cassettes/account_id_trade_options_modify.yml +0 -110
  84. data/spec/fixtures/vcr_cassettes/account_id_trades_filter_get.yml +0 -118
  85. data/spec/fixtures/vcr_cassettes/account_id_trades_get.yml +0 -118
  86. data/spec/fixtures/vcr_cassettes/account_id_transaction_id_get.yml +0 -283
  87. data/spec/fixtures/vcr_cassettes/account_id_transactions_options_get.yml +0 -205
  88. data/spec/fixtures/vcr_cassettes/accounts_create.yml +0 -75
  89. data/spec/fixtures/vcr_cassettes/sandbox_client.yml +0 -116
  90. data/spec/fixtures/vcr_cassettes/sandbox_client_account.yml +0 -111
  91. data/spec/fixtures/vcr_cassettes/sandbox_instrument_EUR_USD.yml +0 -77
  92. data/spec/oanda_api/client/username_client_spec.rb +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6bde10bb61208fec6faf667058293783ffdf6e2c
4
- data.tar.gz: 928603f30cf2a1170b8d5ef8091d8ce4fa6222da
3
+ metadata.gz: 917e6e85db408d8170f0ca102acdeb9cb4317d32
4
+ data.tar.gz: eb4b600f105084b22ae46d7575ed087f5333f1b4
5
5
  SHA512:
6
- metadata.gz: dc10bcbe935f95419b769296860c3069d1b77f62e35a9727b53d8c01c595509ebec739d3ff1fe11800b031441317ca9449fd750742437b23d7222289c033661d
7
- data.tar.gz: c4351ef875a10f099bc2da0bcc7a80ca9d47fbc7f0aa5888c420e10210ae762130933dac3f446624d33219ffe49062ddf9bd2b6eddd17629b4bc4ff9d1147861
6
+ metadata.gz: 0c71a4f00c50f36066e7ed8c1d36333e4b171a0bc57f5fe07484ede19207bfc497a8c15f8623120aac2464e2bcdef075207aee6750592884dc18c7de6693e814
7
+ data.tar.gz: e539247dc8ab06155d0d87844e81e85650a52b7e8be08de01491429a0171000de410e23b16bc1f9d1acbca8549bd69916122776ed012ac556abf6082c1a01ba5
@@ -1,5 +1,68 @@
1
1
  # Change Log
2
2
 
3
+ ## 0.9.5
4
+ * 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
+
6
+ * 2016-03-16 Added support for the Oanda [Forex Labs Spread History](http://developer.oanda.com/rest-live/forex-labs/#spreads) API:
7
+
8
+ ```ruby
9
+ require 'oanda_api'
10
+ # If you want to use sugar like: 1.day, 1.hour, 1.week, etc.
11
+ require 'active_support/core_ext/numeric/time'
12
+
13
+ client = OandaAPI::Client::TokenClient.new(:practice, ENV.fetch("OANDA_PRACTICE_TOKEN"))
14
+ spreads = client.spreads(instrument: "EUR_USD", period: 1.day).get
15
+
16
+ spreads.class # OandaAPI::Resource::Labs::SpreadHistory
17
+ spreads.averages.size # => 94
18
+ spreads.maximums.size # => 76
19
+ spreads.averages.size # => 50
20
+
21
+ spreads.averages.first.spread # => 1.81711
22
+ spreads.averages.first.timestamp # => 1458081900
23
+ spreads.averages.first.time # => 2016-03-15 23:00:00 UTC
24
+
25
+ spreads.maximums.first.spread # => 2.1
26
+ spreads.maximums.first.timestamp # => 1458082800
27
+ spreads.maximums.first.time # => 2016-03-15 23:00:00 UTC
28
+
29
+ spreads.minimums.first.spread # => 1.6
30
+ spreads.minimums.first.timestamp # => 1458081900
31
+ spreads.minimums.first.time # => 2016-03-15 23:00:00 UTC
32
+ ```
33
+
34
+ * 2016-03-16 Fixed `OandaAPI::Streaming::Client#emit_heartbeats=true`. Now heartbeats actually will be emitted if true. Previously this setting was ignored and heartbeats were never emitted. Thanks [dogwood008](https://github.com/dogwood008)!
35
+
36
+ * 2016-03-15 Now TLS verify_mode is explicitly set to OpenSSL::SSL::VERIFY_PEER instead of relying on underlying library defaults.
37
+
38
+ * 2016-03-14 Added support for the Oanda [Forex Labs Economic Calendar](http://developer.oanda.com/rest-live/forex-labs/#calendar) API:
39
+
40
+ Thanks [unageanu](https://github.com/unageanu)!
41
+
42
+ ```ruby
43
+ require 'oanda_api'
44
+ # If you want to use sugar like: 1.day, 1.hour, 1.week, etc.
45
+ require 'active_support/core_ext/numeric/time'
46
+
47
+ client = OandaAPI::Client::TokenClient.new(:practice, ENV.fetch("OANDA_PRACTICE_TOKEN"))
48
+
49
+ client.calendar_events(period: 1.day).get.each do |event|
50
+ event.class # => OandaAPI::Resource::CalendarEvent
51
+ event.title # => "Industrial Production"
52
+ event.currency # => "EUR"
53
+ event.region # => "europe"
54
+ event.forecast # => "-0.3"
55
+ event.previous # => "-0.3"
56
+ event.actual # => "3.3"
57
+ event.impact # => "2"
58
+ event.unit # => "% m/m"
59
+ event.timestamp # => 1457420400
60
+ event.time # => 2016-03-08 07:00:00 UTC
61
+ end
62
+ ```
63
+
64
+ * 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
+
3
66
  ## 0.9.4
4
67
 
5
68
  * Added multi-threaded support for request throttling. Now if you've configured the API to use request throttling:
@@ -19,19 +82,18 @@ and if you access a single instance of the API from multiple threads, then the r
19
82
  config.connection_pool_size = 5
20
83
  end
21
84
  ```
22
- Thanks [Eric](https://github.com/lifeBCE).
85
+ Thanks [LifeBCE](https://github.com/lifeBCE)!
23
86
 
24
87
  ## 0.9.3
25
88
 
26
- * Fixed support for retrieving [full account history](http://developer.oanda.com/rest-live/transaction-history/#getFullAccountHistory). Thanks [bewon](https://github.com/bewon).
27
- * Fixed issue [#6](https://github.com/nukeproof/oanda_api/issues/6) to make streaming JSON parsers available correctly under *nix. Thanks [Eric](https://github.com/lifeBCE).
89
+ * Fixed support for retrieving [full account history](http://developer.oanda.com/rest-live/transaction-history/#getFullAccountHistory). Thanks [bewon](https://github.com/bewon)!
90
+ * Fixed issue [#6](https://github.com/nukeproof/oanda_api/issues/6) to make streaming JSON parsers available correctly under *nix. Thanks [LifeBCE](https://github.com/lifeBCE)!
28
91
 
29
92
  ## 0.9.2
30
93
 
31
94
  * Specify version of HTTParty as 0.13.3 until HTTParty issue [#398](https://github.com/jnunemaker/httparty/issues/398) is resolved.
32
95
  * Now support any whitespace as delimiting multiple JSON objects in streaming API with `OandaAPI::Streaming::Adapters::Generic`.
33
96
 
34
-
35
97
  ## 0.9.1
36
98
 
37
99
  * Fixed JSON serialization for nested ResourceBase instances.
@@ -42,7 +104,6 @@ Thanks [Eric](https://github.com/lifeBCE).
42
104
  ###What's New?
43
105
  As with version 0.9.0, `OandaAPI::Streaming::Client` will use the JSON gem parser if it is the only JSON parser installed. However, the JSON gem does not support parsing streams of objects very robustly (i.e. it expects complete documents, or the stream to delimit multiple objects consistently). If you are using the streaming API, and install either the [yajl-ruby](https://github.com/brianmario/yajl-ruby) gem (for MRI and Rubinius ruby) or the [gson](https://github.com/avsej/gson.rb) gem (for jruby), then `OandaAPI::Streaming::Client` will use either of those streaming JSON gems for a gain in reliability.
44
106
 
45
-
46
107
  ## 0.9.0
47
108
 
48
109
  * Add support for live [Streaming](http://developer.oanda.com/rest-live/streaming/).
@@ -50,4 +111,4 @@ As with version 0.9.0, `OandaAPI::Streaming::Client` will use the JSON gem parse
50
111
  * Fixed Yardoc formatting.
51
112
 
52
113
  ###What's New?
53
- OandaAPI now supports Oanda's streaming API for consuming realtime ticks and account transactions. See the example in the README and have a look at the specs for `OandaAPI::Streaming::Client`.
114
+ OandaAPI now supports Oanda's streaming API for consuming realtime ticks and account transactions. See the example in the README and have a look at the specs for `OandaAPI::Streaming::Client`.
data/README.md CHANGED
@@ -122,6 +122,31 @@ transaction.time # => 2014-12-19 03:29:48 UTC
122
122
  transaction.type # => "MARKET_ORDER_CREATE"
123
123
  ```
124
124
 
125
+ ### Getting Economic Calendar Information
126
+
127
+ ```ruby
128
+ require 'oanda_api'
129
+
130
+ # If you want to use sugar like: 1.day, 1.hour, 1.week, etc.
131
+ require 'active_support/core_ext/numeric/time'
132
+
133
+ client = OandaAPI::Client::TokenClient.new(:practice, ENV.fetch("OANDA_PRACTICE_TOKEN"))
134
+
135
+ client.calendar(period: 1.day).get.each do |event|
136
+ event.class # => OandaAPI::Resource::CalendarEvent
137
+ event.title # => "Industrial Production"
138
+ event.currency # => "EUR"
139
+ event.region # => "europe"
140
+ event.forecast # => "-0.3"
141
+ event.previous # => "-0.3"
142
+ event.actual # => "3.3"
143
+ event.impact # => "2"
144
+ event.unit # => "% m/m"
145
+ event.timestamp # => 1457420400
146
+ event.time # => 2016-03-08 07:00:00 UTC
147
+ end
148
+ ```
149
+
125
150
  ##Streaming
126
151
  OandaAPI also supports the [Oanda realtime streaming API](http://developer.oanda.com/rest-live/streaming/).
127
152
 
@@ -151,7 +176,6 @@ for detailed documentation and API usage notes.
151
176
  |:---------------------------|:---------------------|
152
177
  | client.accounts.get | GET /v1/accounts |
153
178
  | client.account(123).get | GET /v1/accounts/123 |
154
- | client.account.create | POST /v1/accounts |
155
179
  | client.instruments(account_id: 123).get | GET /v1/instruments?accountId=123 |
156
180
  | client.prices(instruments: ["EUR_USD","USD_JPY"]).get | GET /v1/prices/?instruments=EUR_USD%2CUSD_JPY |
157
181
  | client.account(123).orders.get | GET /v1/accounts/123/orders |
@@ -169,6 +193,9 @@ for detailed documentation and API usage notes.
169
193
  | client.account(123).transactions.get | GET /v1/accounts/123/transactions |
170
194
  | client.account(123).transaction(123).get | GET /v1/accounts/123/transactions/123 |
171
195
  | client.account(123).alltransactions.get | GET /v1/accounts/123/alltransactions |
196
+ | client.calendar(instrument: "AUD_USD", period: 86400).get | GET /labs/v1/calendar?instrument=AUD_USD&period=86400|
197
+ | client.spreads(instrument: "AUD_USD", period: 86400).get | GET /labs/v1/spreads?instrument=AUD_USD&period=86400|
198
+
172
199
 
173
200
 
174
201
  Installation
@@ -200,7 +227,7 @@ See the RubyDoc [documentation](http://www.rubydoc.info/gems/oanda_api) for Oand
200
227
  ```ruby
201
228
  OandaAPI.configure do |config|
202
229
  config.use_compression = true
203
- config.use_request_rate_throttling = true
230
+ config.use_request_throttling = true
204
231
  config.max_requests_per_second = 10
205
232
  end
206
233
  ```
@@ -212,7 +239,7 @@ OandaAPI works with Ruby 2.0 and higher.
212
239
 
213
240
  Tested on:
214
241
 
215
- * MRI 2.1, 2.2
242
+ * MRI 2.1, 2.2, 2.3
216
243
  * JRuby 1.7, 9.0.0.0.pre
217
244
  * Rubinius 2.4, 2.5
218
245
 
@@ -233,6 +260,7 @@ When you're ready to code:
233
260
  4. Add new documentation where appropriate using [YARD](http://yardoc.org/) formatting.
234
261
  5. Create a new pull request and submit it to me.
235
262
 
263
+
236
264
  License
237
265
  -------
238
266
 
@@ -4,6 +4,7 @@ require 'persistent_httparty'
4
4
  require 'http/exceptions'
5
5
  require 'time'
6
6
 
7
+ require_relative 'oanda_api/utils/utils'
7
8
  require_relative 'oanda_api/configuration'
8
9
  require_relative 'oanda_api/client/client'
9
10
  require_relative 'oanda_api/client/namespace_proxy'
@@ -26,5 +27,6 @@ require_relative 'oanda_api/resource/price'
26
27
  require_relative 'oanda_api/resource/trade'
27
28
  require_relative 'oanda_api/resource/transaction'
28
29
  require_relative 'oanda_api/resource/transaction_history'
29
- require_relative 'oanda_api/utils/utils'
30
+ require_relative 'oanda_api/resource/labs/calendar_event'
31
+ require_relative 'oanda_api/resource/labs/spread_history'
30
32
  require_relative 'oanda_api/version'
@@ -23,11 +23,12 @@ module OandaAPI
23
23
 
24
24
  # Resource URI templates
25
25
  BASE_URI = {
26
- live: "https://api-fxtrade.oanda.com/[API_VERSION]",
27
- practice: "https://api-fxpractice.oanda.com/[API_VERSION]",
28
- sandbox: "http://api-sandbox.oanda.com/[API_VERSION]"
26
+ live: "https://api-fxtrade.oanda.com/",
27
+ practice: "https://api-fxpractice.oanda.com/",
28
+ sandbox: "http://api-sandbox.oanda.com/"
29
29
  }
30
30
 
31
+
31
32
  # @private
32
33
  # Camelizes keys and transforms array values into comma-delimited strings.
33
34
  #
@@ -50,7 +51,7 @@ module OandaAPI
50
51
  # @param [Hash] options Specifies overrides to default settings.
51
52
  # Overrides for the persistent connection adapter are specified
52
53
  # by including an :connection_adapter_options: {} hash.
53
- # @return [OandaAPI::Client]
54
+ # @return [OandaAPI::Client]
54
55
  def initialize(options={})
55
56
  super()
56
57
  load_persistent_connection_adapter options[:connection_adapter_options] || {}
@@ -58,12 +59,13 @@ module OandaAPI
58
59
 
59
60
  # Returns an absolute URI for a resource request.
60
61
  #
61
- # @param [String] path the path portion of the URI.
62
+ # @param [OandaAPI::Client::ResourceDescriptor] resource_descriptor metadata
63
+ # describing the requested resource.
62
64
  #
63
65
  # @return [String] a URI.
64
- def api_uri(path)
65
- uri = "#{BASE_URI[domain]}#{path}"
66
- uri.sub "[API_VERSION]", OandaAPI.configuration.rest_api_version
66
+ def api_uri(resource_descriptor)
67
+ api_version = resource_descriptor.labs? ? OandaAPI.configuration.labs_api_version : OandaAPI.configuration.rest_api_version
68
+ "#{BASE_URI[domain]}#{api_version}#{resource_descriptor.path}"
67
69
  end
68
70
 
69
71
  # Binds a persistent connection adapter. See documentation for the
@@ -78,6 +80,7 @@ module OandaAPI
78
80
  keep_alive: 30,
79
81
  warn_timeout: 2,
80
82
  pool_size: OandaAPI.configuration.connection_pool_size,
83
+ verify_mode: OpenSSL::SSL::VERIFY_PEER
81
84
  }.merge options
82
85
 
83
86
  Client.persistent_connection_adapter adapter_config
@@ -102,19 +105,21 @@ module OandaAPI
102
105
  #
103
106
  # @raise [OandaAPI::RequestError] if the API return code is not 2xx.
104
107
  def execute_request(method, path, conditions = {})
108
+ method = Client.map_method_to_http_verb method
109
+ resource_descriptor = ResourceDescriptor.new path, method
110
+
105
111
  response = Http::Exceptions.wrap_and_check do
106
- method = Client.map_method_to_http_verb(method)
107
112
  params_key = [:post, :patch, :put].include?(method) ? :body : :query
108
113
  Client.throttle_request_rate
109
114
  Client.send method,
110
- api_uri(path),
115
+ api_uri(resource_descriptor),
111
116
  params_key => Utils.stringify_keys(conditions.merge(default_params)),
112
117
  :headers => OandaAPI.configuration.headers.merge(headers),
113
118
  :open_timeout => OandaAPI.configuration.open_timeout,
114
119
  :read_timeout => OandaAPI.configuration.read_timeout
115
120
  end
116
121
 
117
- handle_response response, ResourceDescriptor.new(path, method)
122
+ handle_response response, resource_descriptor
118
123
  rescue Http::Exceptions::HttpException => e
119
124
  raise OandaAPI::RequestError, e.message
120
125
  end
@@ -158,7 +163,7 @@ module OandaAPI
158
163
  delta = now - (last_request_at || now)
159
164
  _throttle(delta, now) if delta < OandaAPI.configuration.min_request_interval &&
160
165
  OandaAPI.configuration.use_request_throttling?
161
- last_request_at = Time.now
166
+ self.last_request_at = Time.now
162
167
  end
163
168
 
164
169
  # @private
@@ -35,7 +35,7 @@ module OandaAPI
35
35
 
36
36
  @client = client
37
37
  @conditions = {}
38
- @namespace_segments = [Utils.pluralize(namespace_segment)]
38
+ @namespace_segments = [ResourceBase.pluralize(namespace_segment)]
39
39
  extract_key_and_conditions conditions
40
40
  end
41
41
 
@@ -107,7 +107,7 @@ module OandaAPI
107
107
  @client.execute_request sym, namespace, conditions, &block
108
108
  else
109
109
  ns = self.clone
110
- ns.namespace_segments << Utils.pluralize(sym)
110
+ ns.namespace_segments << ResourceBase.pluralize(sym)
111
111
  ns.extract_key_and_conditions args.first
112
112
  ns
113
113
  end
@@ -13,15 +13,21 @@ module OandaAPI
13
13
  # @!attribute [r] resource_klass
14
14
  # @return [Symbol] class of the resource.
15
15
  class ResourceDescriptor
16
+
16
17
  attr_reader :collection_name, :path, :resource_klass
17
18
 
18
19
  # Mapper for not "typical" resources.
19
20
  # Key is a resource from the API path.
20
- # Value is a hash that can contain "resource_name" from the code and/or
21
- # "is_collection" (if true: will force treating response as a collection of resources,
22
- # if false: will force treating response as a single resource).
21
+ # Value is a hash that can contain: 1) "resource_name" which is the OandaAPI ruby resource name and/or
22
+ # 2) "is_collection" (if true: response treated as a collection,
23
+ # false: response treated as a singular resource) and/or
24
+ # 3) "api_resource_name" the actual API resource name
23
25
  RESOURCES_MAPPER = {
24
- alltransactions: { resource_name: "transaction_history", is_collection: false }
26
+ alltransactions: { resource_name: "transaction_history", is_collection: false},
27
+ calendar: { resource_name: "calendar_event", is_collection: true},
28
+ calendar_events: { resource_name: "calendar_event", is_collection: true, api_resource_name: "calendar"},
29
+ spreads: { resource_name: "spread_history", is_collection: false, api_resource_name: "spreads"},
30
+ spread_historys: { resource_name: "spread_history", is_collection: false, api_resource_name: "spreads"}
25
31
  }
26
32
 
27
33
  # Analyzes the resource request and determines the type of resource
@@ -32,7 +38,7 @@ module OandaAPI
32
38
  # @param [Symbol] method an http verb (see {OandaAPI::Client.map_method_to_http_verb}).
33
39
  def initialize(path, method)
34
40
  @path = path
35
- path.match(/\/(?<resource_name>[a-z]*)\/?(?<resource_id>\w*?)$/) do |names|
41
+ path.match(/\/(?<resource_name>[a-z_]*)\/?(?<resource_id>\w*?)$/) do |names|
36
42
  initialize_from_resource_name(names[:resource_name], method, names[:resource_id])
37
43
  end
38
44
  end
@@ -43,15 +49,22 @@ module OandaAPI
43
49
  @is_collection
44
50
  end
45
51
 
52
+ # True if the resource represented by the path is one found in the "Labs"
53
+ # resources in the API.
54
+ # See {http://developer.oanda.com/rest-live/forex-labs/ Forex Labs} for
55
+ # details on Labs resources.
56
+ def labs?
57
+ OandaAPI::ResourceBase.labs_resource? resource_klass
58
+ end
59
+
46
60
  private
47
61
 
48
62
  # The resource type
49
63
  # @param [String] resource_name
50
64
  # @return [void]
51
65
  def resource_klass=(resource_name)
52
- klass_symbol = OandaAPI::Utils.classify(resource_name).to_sym
53
- fail ArgumentError, "Invalid resource" unless OandaAPI::Resource.constants.include?(klass_symbol)
54
- @resource_klass = OandaAPI::Resource.const_get klass_symbol
66
+ @resource_klass = OandaAPI::ResourceBase.class_from_symbol resource_name.to_sym
67
+ fail ArgumentError, "Invalid resource: #{resource_name}" unless @resource_klass
55
68
  end
56
69
 
57
70
  # Will set instance attributes based on resource_name, method and resource_id.
@@ -65,7 +78,10 @@ module OandaAPI
65
78
  { resource_name: Utils.singularize(resource_name) })
66
79
  self.resource_klass = mapped_resource.fetch :resource_name
67
80
  @is_collection = mapped_resource.fetch :is_collection, method == :get && resource_id.empty?
68
- @collection_name = Utils.pluralize(mapped_resource.fetch(:resource_name)).to_sym if is_collection?
81
+ @collection_name = ResourceBase.pluralize(mapped_resource.fetch(:resource_name)).to_sym if is_collection?
82
+
83
+ # If resource is using an alias name, replace it with its real API resource name.
84
+ @path.sub!(/\w*$/, mapped_resource[:api_resource_name]) if mapped_resource[:api_resource_name]
69
85
  end
70
86
  end
71
87
  end
@@ -1,5 +1,10 @@
1
1
  module OandaAPI
2
2
  module Client
3
+ # :nocov:
4
+ #
5
+ # *DEPRECATED:* The Sandbox API endpoint is no longer supported by Oanda.
6
+ # @deprecated Please use {OandaAPI::Client::TokenClient} with a practice account instead.
7
+ #
3
8
  # Makes requests to the API.
4
9
  # Instances access the Oanda _sandbox_ environment.
5
10
  # Most client requests require a valid Oanda sandbox account username.
@@ -36,6 +41,7 @@ module OandaAPI
36
41
 
37
42
  # @param [String] username used for authentication.
38
43
  def initialize(username, options={})
44
+ warn Kernel.caller.first + " [DEPRECATION] `OandaAPI::Client::UsernameClient` is deprecated. Please use `OandaAPI::Client::TokenClient` instead."
39
45
  super options
40
46
  @domain = :sandbox
41
47
  @username = username
@@ -49,5 +55,6 @@ module OandaAPI
49
55
  { "username" => @username }
50
56
  end
51
57
  end
58
+ # :nocov:
52
59
  end
53
60
  end
@@ -4,6 +4,7 @@ module OandaAPI
4
4
  # Configures client API settings.
5
5
  class Configuration
6
6
  DATETIME_FORMAT = :rfc3339
7
+ LABS_API_VERSION = "labs/v1"
7
8
  MAX_REQUESTS_PER_SECOND = 15
8
9
  OPEN_TIMEOUT = 10
9
10
  READ_TIMEOUT = 10
@@ -40,6 +41,19 @@ module OandaAPI
40
41
  @datetime_format = value
41
42
  end
42
43
 
44
+ # The Oanda Labs API version used by the client.
45
+ # @return [String]
46
+ def labs_api_version
47
+ @labs_api_version ||= LABS_API_VERSION
48
+ end
49
+
50
+ # See {#labs_api_version}.
51
+ # @param [String] value
52
+ # @return [void]
53
+ def labs_api_version=(value)
54
+ @labs_api_version = value
55
+ end
56
+
43
57
  # The maximum number of requests per second allowed to be made through the
44
58
  # API. Only enforced if {#use_request_throttling?} is `true`.
45
59
  #
@@ -13,10 +13,8 @@ module OandaAPI
13
13
  :margin_used,
14
14
  :open_orders,
15
15
  :open_trades,
16
- :password,
17
16
  :realized_pl,
18
- :unrealized_pl,
19
- :username
17
+ :unrealized_pl
20
18
 
21
19
  alias_method :id, :account_id
22
20
  alias_method :id=, :account_id=
@@ -32,6 +30,27 @@ module OandaAPI
32
30
  @open_trades = []
33
31
  super
34
32
  end
33
+
34
+ # :nocov:
35
+ def password=(v)
36
+ deprecated :password
37
+ end
38
+
39
+ def password
40
+ deprecated :password
41
+ end
42
+
43
+ def username=(v)
44
+ deprecated :username
45
+ end
46
+
47
+ def username
48
+ deprecated :username
49
+ end
50
+ # :nocov:
51
+ def deprecated(method)
52
+ warn Kernel.caller.first + " [ DEPRECATED ] #{method} has been removed by Oanda"
53
+ end
35
54
  end
36
55
  end
37
56
  end