oanda_api 0.8.1 → 0.8.3
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.
- data/.gitignore +38 -0
- data/.rspec_non_jruby +2 -0
- data/.yardopts +6 -0
- data/Gemfile +13 -0
- data/Guardfile +7 -0
- data/LICENSE +22 -0
- data/README.md +218 -0
- data/Rakefile +23 -0
- data/lib/oanda_api.rb +25 -0
- data/lib/oanda_api/client/client.rb +175 -0
- data/lib/oanda_api/client/namespace_proxy.rb +112 -0
- data/lib/oanda_api/client/resource_descriptor.rb +52 -0
- data/lib/oanda_api/client/token_client.rb +69 -0
- data/lib/oanda_api/client/username_client.rb +53 -0
- data/lib/oanda_api/configuration.rb +167 -0
- data/lib/oanda_api/errors.rb +4 -0
- data/lib/oanda_api/resource/account.rb +37 -0
- data/lib/oanda_api/resource/candle.rb +29 -0
- data/lib/oanda_api/resource/instrument.rb +21 -0
- data/lib/oanda_api/resource/order.rb +74 -0
- data/lib/oanda_api/resource/position.rb +18 -0
- data/lib/oanda_api/resource/price.rb +16 -0
- data/lib/oanda_api/resource/trade.rb +23 -0
- data/lib/oanda_api/resource/transaction.rb +67 -0
- data/lib/oanda_api/resource_base.rb +35 -0
- data/lib/oanda_api/resource_collection.rb +77 -0
- data/lib/oanda_api/utils/utils.rb +101 -0
- data/lib/oanda_api/version.rb +3 -0
- data/oanda_api.gemspec +32 -0
- data/spec/fixtures/vcr_cassettes/account_id_order_id_close.yml +264 -0
- data/spec/fixtures/vcr_cassettes/account_id_order_id_get.yml +114 -0
- data/spec/fixtures/vcr_cassettes/account_id_order_options_create.yml +74 -0
- data/spec/fixtures/vcr_cassettes/account_id_order_options_update.yml +112 -0
- data/spec/fixtures/vcr_cassettes/account_id_orders_get.yml +118 -0
- data/spec/fixtures/vcr_cassettes/account_id_orders_options_get.yml +123 -0
- data/spec/fixtures/vcr_cassettes/account_id_positions_get.yml +112 -0
- data/spec/fixtures/vcr_cassettes/account_id_positions_instrument_close.yml +214 -0
- data/spec/fixtures/vcr_cassettes/account_id_positions_instrument_get.yml +110 -0
- data/spec/fixtures/vcr_cassettes/account_id_trade_id_close.yml +252 -0
- data/spec/fixtures/vcr_cassettes/account_id_trade_id_get.yml +112 -0
- data/spec/fixtures/vcr_cassettes/account_id_trade_options_modify.yml +110 -0
- data/spec/fixtures/vcr_cassettes/account_id_trades_filter_get.yml +118 -0
- data/spec/fixtures/vcr_cassettes/account_id_trades_get.yml +118 -0
- data/spec/fixtures/vcr_cassettes/account_id_transaction_id_get.yml +283 -0
- data/spec/fixtures/vcr_cassettes/account_id_transactions_options_get.yml +205 -0
- data/spec/fixtures/vcr_cassettes/accounts_create.yml +75 -0
- data/spec/fixtures/vcr_cassettes/accounts_get.yml +111 -0
- data/spec/fixtures/vcr_cassettes/accounts_id_get.yml +187 -0
- data/spec/fixtures/vcr_cassettes/candles_options_get.yml +79 -0
- data/spec/fixtures/vcr_cassettes/instruments_get.yml +501 -0
- data/spec/fixtures/vcr_cassettes/instruments_options_get.yml +81 -0
- data/spec/fixtures/vcr_cassettes/prices_options_get.yml +81 -0
- data/spec/fixtures/vcr_cassettes/sandbox_client.yml +116 -0
- data/spec/fixtures/vcr_cassettes/sandbox_client_account.yml +111 -0
- data/spec/fixtures/vcr_cassettes/sandbox_instrument_EUR_USD.yml +77 -0
- data/spec/oanda_api/client/client_spec.rb +107 -0
- data/spec/oanda_api/client/namespace_proxy_spec.rb +16 -0
- data/spec/oanda_api/client/resource_descriptor_spec.rb +39 -0
- data/spec/oanda_api/client/token_client_spec.rb +60 -0
- data/spec/oanda_api/client/username_client_spec.rb +31 -0
- data/spec/oanda_api/configuration_spec.rb +138 -0
- data/spec/oanda_api/examples/accounts_spec.rb +28 -0
- data/spec/oanda_api/examples/orders_spec.rb +68 -0
- data/spec/oanda_api/examples/positions_spec.rb +38 -0
- data/spec/oanda_api/examples/rates_spec.rb +46 -0
- data/spec/oanda_api/examples/trades_spec.rb +58 -0
- data/spec/oanda_api/examples/transactions_spec.rb +24 -0
- data/spec/oanda_api/resource_collection_spec.rb +109 -0
- data/spec/oanda_api/utils/utils_spec.rb +109 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/client_helper.rb +60 -0
- data/spec/support/vcr.rb +7 -0
- metadata +124 -9
@@ -0,0 +1,112 @@
|
|
1
|
+
module OandaAPI
|
2
|
+
module Client
|
3
|
+
# A client proxy and method-chaining enabler.
|
4
|
+
#
|
5
|
+
# @example Example usage
|
6
|
+
# client = OandaAPI::Client::TokenClient.new :practice, token
|
7
|
+
# account = client.account(1234) # => OandaAPI::Client::NamespaceProxy
|
8
|
+
# account.get # => OandaAPI::Resource::Account
|
9
|
+
# account.orders.get # => OandaAPI::Resource::ResourceCollection
|
10
|
+
#
|
11
|
+
# @!attribute [rw] conditions
|
12
|
+
# @return [Hash] a collection of parameters that typically specifies
|
13
|
+
# conditions and filters for a resource request.
|
14
|
+
#
|
15
|
+
# @!attribute [rw] namespace_segments
|
16
|
+
# @return [Array<String>] an ordered list of namespaces, when joined,
|
17
|
+
# creates a path to a resource URI.
|
18
|
+
class NamespaceProxy
|
19
|
+
attr_accessor :conditions, :namespace_segments
|
20
|
+
|
21
|
+
# @param [OandaAPI::Client] client
|
22
|
+
#
|
23
|
+
# @param [String] namespace_segment a _segment_ in a resource's URI. An
|
24
|
+
# ordered list of segments, joined, creates a path to a resource URI.
|
25
|
+
#
|
26
|
+
# @param [Hash] conditions an optional list of parameters that typically
|
27
|
+
# specifies conditions and filters for a resource request. A a _"key"_
|
28
|
+
# or _"id"_ is a condition that identifies a particular resource. If a
|
29
|
+
# key condition is included, it is extracted and added as a namespace
|
30
|
+
# segment. See {#extract_key_and_conditions}.
|
31
|
+
def initialize(client, namespace_segment, conditions)
|
32
|
+
fail ArgumentError, "expecting an OandaAPI::Client instance" unless client && client.is_a?(OandaAPI::Client)
|
33
|
+
fail ArgumentError, "expecting a namespace value" if namespace_segment.to_s.empty?
|
34
|
+
|
35
|
+
@client = client
|
36
|
+
@conditions = {}
|
37
|
+
@namespace_segments = [Utils.pluralize(namespace_segment)]
|
38
|
+
extract_key_and_conditions conditions
|
39
|
+
end
|
40
|
+
|
41
|
+
# Returns a deep clone of +self+.
|
42
|
+
# @return [NamespaceProxy]
|
43
|
+
def clone
|
44
|
+
ns = self.dup
|
45
|
+
ns.conditions = conditions.dup
|
46
|
+
ns.namespace_segments = namespace_segments.dup
|
47
|
+
ns
|
48
|
+
end
|
49
|
+
|
50
|
+
# Returns the namespace (URI path to a resource).
|
51
|
+
# @return [String]
|
52
|
+
def namespace
|
53
|
+
"/" + @namespace_segments.join("/")
|
54
|
+
end
|
55
|
+
|
56
|
+
# Extracts a _key_ parameter from the arguments.
|
57
|
+
# If a key is found, it's appended to the list namespace segments. Non-key
|
58
|
+
# parameters are merged into the {#conditions} collection. A parameter is a
|
59
|
+
# key if it's named ":id", or if there is only a single scalar argument.
|
60
|
+
#
|
61
|
+
# @example "key" parameters
|
62
|
+
# client = OandaAPI::Client::TokenClient.new :practice, token
|
63
|
+
# account = client.account(1234) # 1234 is a _key_ (accountId)
|
64
|
+
# account.namespace # => /accounts/1234
|
65
|
+
#
|
66
|
+
# order = account.order(instrument: "USD_JPY",
|
67
|
+
# type: "market",
|
68
|
+
# units: 10_000,
|
69
|
+
# side: "buy").create # No key parameters here
|
70
|
+
#
|
71
|
+
# position = account.position("USD_JPY").get # USD_JPY is a key
|
72
|
+
#
|
73
|
+
# @param conditions either a hash of parameter values, single scalar value, or nil.
|
74
|
+
#
|
75
|
+
# @return [void]
|
76
|
+
def extract_key_and_conditions(conditions)
|
77
|
+
key =
|
78
|
+
case
|
79
|
+
when conditions && conditions.is_a?(Hash)
|
80
|
+
@conditions.merge! Utils.rubyize_keys(conditions)
|
81
|
+
@conditions.delete :id
|
82
|
+
when conditions
|
83
|
+
conditions
|
84
|
+
end
|
85
|
+
@namespace_segments << key if key
|
86
|
+
end
|
87
|
+
|
88
|
+
# Executes an API request and returns a resource object, or returns a
|
89
|
+
# clone of +self+ for method chaining.
|
90
|
+
#
|
91
|
+
# @return [OandaAPI::Client::NamespaceProxy] if the method is used
|
92
|
+
# for chaining.
|
93
|
+
#
|
94
|
+
# @return [OandaAPI::ResourceBase] if the method is one of the supported
|
95
|
+
# _terminating_ methods (+:create+, +:close+, +:delete+, +:get+, +:update+).
|
96
|
+
#
|
97
|
+
# @return [OandaAPI::ResourceCollection] if the method is +:get+ and the
|
98
|
+
# API returns a collection of resources.
|
99
|
+
def method_missing(sym, *args)
|
100
|
+
# Check for terminating method
|
101
|
+
if [:create, :close, :delete, :get, :update].include?(sym)
|
102
|
+
@client.execute_request sym, namespace, conditions
|
103
|
+
else
|
104
|
+
ns = self.clone
|
105
|
+
ns.namespace_segments << Utils.pluralize(sym)
|
106
|
+
ns.extract_key_and_conditions args.first
|
107
|
+
ns
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module OandaAPI
|
2
|
+
module Client
|
3
|
+
# @private
|
4
|
+
# Metadata about a resource request.
|
5
|
+
#
|
6
|
+
# @!attribute [r] collection_name
|
7
|
+
# @return [Symbol] method name that returns a collection of the resource
|
8
|
+
# from the API response.
|
9
|
+
#
|
10
|
+
# @!attribute [r] path
|
11
|
+
# @return [String] path of the resource URI.
|
12
|
+
#
|
13
|
+
# @!attribute [r] resource_klass
|
14
|
+
# @return [Symbol] class of the resource.
|
15
|
+
class ResourceDescriptor
|
16
|
+
attr_reader :collection_name, :path, :resource_klass
|
17
|
+
|
18
|
+
# Analyzes the resource request and determines the type of resource
|
19
|
+
# expected from the API.
|
20
|
+
#
|
21
|
+
# @param [String] path a path to a resource.
|
22
|
+
#
|
23
|
+
# @param [Symbol] method an http verb (see {OandaAPI::Client.map_method_to_http_verb}).
|
24
|
+
def initialize(path, method)
|
25
|
+
@path = path
|
26
|
+
path.match(/\/(?<resource_name>[a-z]*)\/?(?<resource_id>\w*?)$/) do |names|
|
27
|
+
resource_name, resource_id = [Utils.singularize(names[:resource_name]), names[:resource_id]]
|
28
|
+
self.resource_klass = resource_name
|
29
|
+
@is_collection = method == :get && resource_id.empty?
|
30
|
+
@collection_name = Utils.pluralize(resource_name).to_sym if is_collection?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# True if the request returns a collection.
|
35
|
+
# @return [Boolean]
|
36
|
+
def is_collection?
|
37
|
+
@is_collection
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
# The resource type
|
43
|
+
# @param [String] resource_name
|
44
|
+
# @return [void]
|
45
|
+
def resource_klass=(resource_name)
|
46
|
+
klass_symbol = resource_name.capitalize.to_sym
|
47
|
+
fail ArgumentError, "Invalid resource" unless OandaAPI::Resource.constants.include?(klass_symbol)
|
48
|
+
@resource_klass = OandaAPI::Resource.const_get klass_symbol
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module OandaAPI
|
2
|
+
module Client
|
3
|
+
# Makes requests to the API.
|
4
|
+
# Instances access Oanda's _practice_ or _live_ environments.
|
5
|
+
# Most API methods require an account API token to perform requests in the
|
6
|
+
# associated environment.
|
7
|
+
# See the Oanda Development Guide for information about
|
8
|
+
# {http://developer.oanda.com/rest-live/authentication/ obtaining a personal access token from Oanda}.
|
9
|
+
#
|
10
|
+
# @example Example usage
|
11
|
+
# token = ENV["oanda_practice_account_token"]
|
12
|
+
# client = OandaAPI::Client::TokenClient.new :practice, token
|
13
|
+
#
|
14
|
+
# # Get information for an account.
|
15
|
+
# # See http://developer.oanda.com/rest-live/accounts/
|
16
|
+
# account = client.accounts.get.first # => OandaAPI::Resource::Account
|
17
|
+
#
|
18
|
+
# # Get a list of open positions.
|
19
|
+
# # See http://developer.oanda.com/rest-live/positions/
|
20
|
+
# positions = client.account(account.id)
|
21
|
+
# .positions.get # => OandaAPI::ResourceCollection
|
22
|
+
#
|
23
|
+
#
|
24
|
+
# @!attribute [r] auth_token
|
25
|
+
# @return [String] Oanda personal access token.
|
26
|
+
#
|
27
|
+
# @!attribute [rw] domain
|
28
|
+
# @return [Symbol] identifies the Oanda subdomain (+:practice+ or +:live+)
|
29
|
+
# accessed by the client.
|
30
|
+
#
|
31
|
+
# @!attribute [rw] default_params
|
32
|
+
# @return [Hash] parameters that are included with every API
|
33
|
+
# request as either query or url_form encoded parameters.
|
34
|
+
#
|
35
|
+
# @!attribute [rw] headers
|
36
|
+
# @return [Hash] parameters that are included with every API request
|
37
|
+
# as HTTP headers.
|
38
|
+
class TokenClient
|
39
|
+
include Client
|
40
|
+
|
41
|
+
attr_reader :auth_token
|
42
|
+
attr_accessor :domain, :default_params, :headers
|
43
|
+
|
44
|
+
# @param [Symbol] domain see {#domain}
|
45
|
+
# @param [String] auth_token see {#auth_token}
|
46
|
+
def initialize(domain, auth_token)
|
47
|
+
super()
|
48
|
+
@auth_token = auth_token
|
49
|
+
@default_params = {}
|
50
|
+
self.domain = domain
|
51
|
+
@headers = auth
|
52
|
+
end
|
53
|
+
|
54
|
+
# Parameters used for authentication.
|
55
|
+
# @return [Hash]
|
56
|
+
def auth
|
57
|
+
{ "Authorization" => "Bearer #{auth_token}" }
|
58
|
+
end
|
59
|
+
|
60
|
+
# @private
|
61
|
+
# Sets the domain the client can access. (Testing convenience only).
|
62
|
+
# @return [void]
|
63
|
+
def domain=(value)
|
64
|
+
fail ArgumentError, "Invalid domain" unless OandaAPI::DOMAINS.include? value
|
65
|
+
@domain = value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module OandaAPI
|
2
|
+
module Client
|
3
|
+
# Makes requests to the API.
|
4
|
+
# Instances access the Oanda _sandbox_ environment.
|
5
|
+
# Most client requests require a valid Oanda sandbox account username.
|
6
|
+
# See the Oanda Development Guide for information about
|
7
|
+
# {http://developer.oanda.com/rest-live/accounts/#createTestAccount creating a test account}.
|
8
|
+
#
|
9
|
+
# @example Example usage (creates a new test account).
|
10
|
+
# client = OandaAPI::Client::UsernameClient.new "_" # Note: A new test account can be created without having an
|
11
|
+
# # existing account, which is why we create a client in this
|
12
|
+
# # example with a bogus username ("_").
|
13
|
+
# new_account = client.account.create # => OandaAPI::Resource::Account
|
14
|
+
# new_account.username # => "<username>"
|
15
|
+
#
|
16
|
+
#
|
17
|
+
# @!attribute [r] domain
|
18
|
+
# @return [Symbol] identifies the Oanda subdomain (+:sandbox+) which the
|
19
|
+
# client accesses.
|
20
|
+
#
|
21
|
+
# @!attribute [r] username
|
22
|
+
# @return [String] the username used for authentication.
|
23
|
+
#
|
24
|
+
# @!attribute [rw] default_params
|
25
|
+
# @return [Hash] parameters that are included with every API request as
|
26
|
+
# either query or url_form encoded parameters.
|
27
|
+
#
|
28
|
+
# @!attribute [rw] headers
|
29
|
+
# @return [Hash] parameters that are included with every API request as
|
30
|
+
# HTTP headers.
|
31
|
+
class UsernameClient
|
32
|
+
include Client
|
33
|
+
|
34
|
+
attr_reader :domain, :username
|
35
|
+
attr_accessor :default_params, :headers
|
36
|
+
|
37
|
+
# @param [String] username used for authentication.
|
38
|
+
def initialize(username)
|
39
|
+
super()
|
40
|
+
@domain = :sandbox
|
41
|
+
@username = username
|
42
|
+
@default_params = auth
|
43
|
+
@headers = {}
|
44
|
+
end
|
45
|
+
|
46
|
+
# Parameters used for authentication.
|
47
|
+
# @return [Hash]
|
48
|
+
def auth
|
49
|
+
{ "username" => @username }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module OandaAPI
|
2
|
+
DATETIME_FORMATS = [:rfc3339, :unix]
|
3
|
+
|
4
|
+
# Configures client API settings.
|
5
|
+
class Configuration
|
6
|
+
DATETIME_FORMAT = :rfc3339
|
7
|
+
MAX_REQUESTS_PER_SECOND = 15
|
8
|
+
OPEN_TIMEOUT = 10
|
9
|
+
READ_TIMEOUT = 10
|
10
|
+
REST_API_VERSION = "v1"
|
11
|
+
USE_COMPRESSION = false
|
12
|
+
USE_REQUEST_THROTTLING = false
|
13
|
+
|
14
|
+
# The format in which dates will be returned by the API (+:rfc3339+ or +:unix+).
|
15
|
+
# See the Oanda Development Guide for more details about {http://developer.oanda.com/rest-live/development-guide/#date_Time_Format DateTime formats}.
|
16
|
+
# @return [Symbol]
|
17
|
+
def datetime_format
|
18
|
+
@datetime_format ||= DATETIME_FORMAT
|
19
|
+
end
|
20
|
+
|
21
|
+
# See {#datetime_format}.
|
22
|
+
# @param [Symbol] value
|
23
|
+
# @return [void]
|
24
|
+
def datetime_format=(value)
|
25
|
+
fail ArgumentError, "Invalid datetime format" unless OandaAPI::DATETIME_FORMATS.include? value
|
26
|
+
@datetime_format = value
|
27
|
+
end
|
28
|
+
|
29
|
+
# The maximum number of requests per second allowed to be made through the
|
30
|
+
# API. Only enforced if {#use_request_throttling?} is +true+.
|
31
|
+
#
|
32
|
+
# @return [Numeric]
|
33
|
+
def max_requests_per_second
|
34
|
+
@max_requests_per_second ||= MAX_REQUESTS_PER_SECOND
|
35
|
+
end
|
36
|
+
|
37
|
+
# See {#max_requests_per_second}.
|
38
|
+
# @param [Numeric] value
|
39
|
+
# @return [void]
|
40
|
+
def max_requests_per_second=(value)
|
41
|
+
fail ArgumentError, "must be a number > 0" unless value.is_a?(Numeric) && value > 0
|
42
|
+
@min_request_interval = nil
|
43
|
+
@max_requests_per_second = value
|
44
|
+
end
|
45
|
+
|
46
|
+
# The minimum amount of time in seconds that must elapse between consecutive requests to the API.
|
47
|
+
# Determined by {#max_requests_per_second}. Only enforced if {#use_request_throttling?} is +true+.
|
48
|
+
# @return [Float]
|
49
|
+
def min_request_interval
|
50
|
+
@min_request_interval ||= (1.0 / max_requests_per_second)
|
51
|
+
end
|
52
|
+
|
53
|
+
# The number of seconds the client waits for a new HTTP connection to be established before
|
54
|
+
# raising a timeout exception.
|
55
|
+
# @return [Numeric]
|
56
|
+
def open_timeout
|
57
|
+
@open_timeout ||= OPEN_TIMEOUT
|
58
|
+
end
|
59
|
+
|
60
|
+
# See {#open_timeout}.
|
61
|
+
# @param [Numeric] value
|
62
|
+
# @return [void]
|
63
|
+
def open_timeout=(value)
|
64
|
+
fail ArgumentError, "must be an integer or float" unless value && (value.is_a?(Integer) || value.is_a?(Float))
|
65
|
+
@open_timeout = value
|
66
|
+
end
|
67
|
+
|
68
|
+
# The number of seconds the client waits for a response from the API before
|
69
|
+
# raising a timeout exception.
|
70
|
+
# @return [Numeric]
|
71
|
+
def read_timeout
|
72
|
+
@read_timeout ||= READ_TIMEOUT
|
73
|
+
end
|
74
|
+
|
75
|
+
# See {#read_timeout}.
|
76
|
+
# @param [Numeric] value
|
77
|
+
# @return [void]
|
78
|
+
def read_timeout=(value)
|
79
|
+
fail ArgumentError, "must be an integer or float" unless value && (value.is_a?(Integer) || value.is_a?(Float))
|
80
|
+
@read_timeout = value
|
81
|
+
end
|
82
|
+
|
83
|
+
# The Oanda REST API version used by the client.
|
84
|
+
# @return [String]
|
85
|
+
def rest_api_version
|
86
|
+
@rest_api_version ||= REST_API_VERSION
|
87
|
+
end
|
88
|
+
|
89
|
+
# See {#rest_api_version}.
|
90
|
+
# @param [String] value
|
91
|
+
# @return [void]
|
92
|
+
def rest_api_version=(value)
|
93
|
+
@rest_api_version = value
|
94
|
+
end
|
95
|
+
|
96
|
+
# Specifies whether the API uses compressed responses. See the Oanda Development Guide
|
97
|
+
# for more information about {http://developer.oanda.com/rest-live/best-practices/#compression compression}.
|
98
|
+
#
|
99
|
+
# @return [Boolean]
|
100
|
+
def use_compression
|
101
|
+
@use_compression = USE_COMPRESSION if @use_compression.nil?
|
102
|
+
@use_compression
|
103
|
+
end
|
104
|
+
|
105
|
+
alias_method :use_compression?, :use_compression
|
106
|
+
|
107
|
+
# See {#use_compression}.
|
108
|
+
# @param [Boolean] value
|
109
|
+
# @return [void]
|
110
|
+
def use_compression=(value)
|
111
|
+
@use_compression = !!value
|
112
|
+
end
|
113
|
+
|
114
|
+
# Throttles the rate of requests made to the API. See the Oanda Developers
|
115
|
+
# Guide for information about
|
116
|
+
# {http://developer.oanda.com/rest-live/best-practices/ connection limits}.
|
117
|
+
# If enabled, requests will not exceed {#max_requests_per_second}. If the
|
118
|
+
# rate of requests received by the client exceeds this limit, the client
|
119
|
+
# delays the rate-exceeding request for the minimum amount of time needed
|
120
|
+
# to satisfy the rate limit.
|
121
|
+
#
|
122
|
+
# @return [Boolean]
|
123
|
+
def use_request_throttling
|
124
|
+
@use_request_throttling = USE_REQUEST_THROTTLING if @use_request_throttling.nil?
|
125
|
+
@use_request_throttling
|
126
|
+
end
|
127
|
+
|
128
|
+
alias_method :use_request_throttling?, :use_request_throttling
|
129
|
+
|
130
|
+
# See {#use_request_throttling}.
|
131
|
+
# @param [Boolean] value
|
132
|
+
# @return [void]
|
133
|
+
def use_request_throttling=(value)
|
134
|
+
@use_request_throttling = !!value
|
135
|
+
end
|
136
|
+
|
137
|
+
# @private
|
138
|
+
# @return [Hash] headers that are set on every request as a result of
|
139
|
+
# configuration settings.
|
140
|
+
def headers
|
141
|
+
h = {}
|
142
|
+
h["X-Accept-Datetime-Format"] = datetime_format.to_s.upcase
|
143
|
+
h["Accept-Encoding"] = "deflate, gzip" if use_compression?
|
144
|
+
h
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Use to configure application-wide settings.
|
149
|
+
#
|
150
|
+
# @example Example Usage
|
151
|
+
# OandaAPI.configure |config|
|
152
|
+
# config.use_compression = true
|
153
|
+
# config.use_request_throttling = true
|
154
|
+
# end
|
155
|
+
#
|
156
|
+
# @yield [Configuration]
|
157
|
+
# @return [void]
|
158
|
+
def self.configure
|
159
|
+
yield configuration
|
160
|
+
end
|
161
|
+
|
162
|
+
# @private
|
163
|
+
# @return [Configuration]
|
164
|
+
def self.configuration
|
165
|
+
@configuration ||= Configuration.new
|
166
|
+
end
|
167
|
+
end
|