snaptrade 3.0.44 → 3.0.46

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +54 -2
  3. data/lib/snaptrade/api/account_information_api.rb +4 -4
  4. data/lib/snaptrade/api/experimental_endpoints_api.rb +145 -0
  5. data/lib/snaptrade/models/account_order.rb +438 -0
  6. data/lib/snaptrade/models/account_order_group.rb +241 -0
  7. data/lib/snaptrade/models/account_order_leg.rb +302 -0
  8. data/lib/snaptrade/models/account_order_record_v2.rb +35 -1
  9. data/lib/snaptrade/models/account_order_time_in_force.rb +44 -0
  10. data/lib/snaptrade/models/all_account_orders_response.rb +239 -0
  11. data/lib/snaptrade/models/all_account_orders_response_data_freshness.rb +223 -0
  12. data/lib/snaptrade/models/limit_order_type.rb +237 -0
  13. data/lib/snaptrade/models/limit_order_type_kind.rb +36 -0
  14. data/lib/snaptrade/models/market_order_type.rb +222 -0
  15. data/lib/snaptrade/models/market_order_type_kind.rb +36 -0
  16. data/lib/snaptrade/models/order_type_configuration.rb +63 -0
  17. data/lib/snaptrade/models/other_order_type.rb +257 -0
  18. data/lib/snaptrade/models/other_order_type_kind.rb +36 -0
  19. data/lib/snaptrade/models/stop_limit_order_type.rb +252 -0
  20. data/lib/snaptrade/models/stop_limit_order_type_kind.rb +36 -0
  21. data/lib/snaptrade/models/stop_order_type.rb +237 -0
  22. data/lib/snaptrade/models/stop_order_type_kind.rb +36 -0
  23. data/lib/snaptrade/models/trailing_stop_limit_order_type.rb +262 -0
  24. data/lib/snaptrade/models/trailing_stop_limit_order_type_kind.rb +36 -0
  25. data/lib/snaptrade/models/trailing_stop_order_type.rb +247 -0
  26. data/lib/snaptrade/models/trailing_stop_order_type_kind.rb +36 -0
  27. data/lib/snaptrade/version.rb +1 -1
  28. data/lib/snaptrade.rb +21 -0
  29. data/spec/api/account_information_api_spec.rb +1 -1
  30. data/spec/api/experimental_endpoints_api_spec.rb +16 -0
  31. data/spec/models/account_order_group_spec.rb +35 -0
  32. data/spec/models/account_order_leg_spec.rb +71 -0
  33. data/spec/models/account_order_record_v2_spec.rb +4 -0
  34. data/spec/models/account_order_spec.rb +125 -0
  35. data/spec/models/account_order_time_in_force_spec.rb +23 -0
  36. data/spec/models/all_account_orders_response_data_freshness_spec.rb +29 -0
  37. data/spec/models/all_account_orders_response_spec.rb +35 -0
  38. data/spec/models/limit_order_type_kind_spec.rb +23 -0
  39. data/spec/models/limit_order_type_spec.rb +35 -0
  40. data/spec/models/market_order_type_kind_spec.rb +23 -0
  41. data/spec/models/market_order_type_spec.rb +29 -0
  42. data/spec/models/order_type_configuration_spec.rb +38 -0
  43. data/spec/models/other_order_type_kind_spec.rb +23 -0
  44. data/spec/models/other_order_type_spec.rb +47 -0
  45. data/spec/models/stop_limit_order_type_kind_spec.rb +23 -0
  46. data/spec/models/stop_limit_order_type_spec.rb +41 -0
  47. data/spec/models/stop_order_type_kind_spec.rb +23 -0
  48. data/spec/models/stop_order_type_spec.rb +35 -0
  49. data/spec/models/trailing_stop_limit_order_type_kind_spec.rb +23 -0
  50. data/spec/models/trailing_stop_limit_order_type_spec.rb +47 -0
  51. data/spec/models/trailing_stop_order_type_kind_spec.rb +23 -0
  52. data/spec/models/trailing_stop_order_type_spec.rb +41 -0
  53. metadata +316 -253
@@ -0,0 +1,302 @@
1
+ =begin
2
+ #SnapTrade
3
+
4
+ #Connect brokerage accounts to your app for live positions and trading. ## Rate limiting Two limits apply to requests signed with your `clientId`. The stricter one wins, and exceeding either returns `429 Too Many Requests`. - **Customer-level** — 250 requests/minute by default, scoped to your `clientId` and applied across all endpoints. Reported in `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. - **Account-level** — 10 requests/minute per account, scoped to (`clientId`, `accountId`). All covered operations for one account draw on the same bucket — reading balances and reading positions share it — and enforcement does not depend on the HTTP method, so updating an account consumes the same bucket as reading it. Only enforced for Personal users, and only for integrations it has been rolled out to — it is not yet in force for every Personal integration. It also does not apply on every operation that documents a 429 below. Where it applies it is reported in `X-RateLimit-Account-Limit`, `X-RateLimit-Account-Remaining` and `X-RateLimit-Account-Reset`. Do not read the absence of those headers as proof the limit is off — some configurations omit the rate limit headers while still enforcing the limit, so header absence tells you nothing about your allowance. On a 429, `X-RateLimit-Remaining: 0` means you hit the customer-level limit and `X-RateLimit-Account-Remaining: 0` means the account-level one. Wait for the corresponding `*-Reset` value (seconds) before retrying, or fall back to exponential backoff with jitter. Not every 429 is explained by those headers. A separate per-authenticated-user limit, reported in no `X-RateLimit-*` header, covers OAuth-authenticated requests and signed requests in configurations where the customer-level limit is not in effect — on the operations that use the default throttles. A few operations override those and are governed by the customer-level limit alone. The two do not stack: a signed request governed by the customer-level limit above is not additionally subject to the per-user one. If a 429 arrives with no header at zero — or with no `X-RateLimit-*` headers at all — honour `Retry-After` and back off. Treat the remaining counts as a hint, not a guarantee that the next request will succeed. Because the customer-level limit applies everywhere, any signed request can return 429. **OAuth-authenticated requests are an exception.** They are not subject to the customer-level limit and do not receive `X-RateLimit-Limit`, `X-RateLimit-Remaining` or `X-RateLimit-Reset` — do not wait on those headers or design around a customer-level allowance on this path. The account-level limit still applies to them on the account-data endpoints above, reported in the `X-RateLimit-Account-*` headers. On operations using the default throttles the per-user limit above applies to them as well, so an OAuth request can be rejected while the account headers still show capacity; on the few operations that override those throttles, OAuth callers have no per-user ceiling at all. Drive retries from `Retry-After` and exponential backoff with jitter rather than from the headers. See https://docs.snaptrade.com/docs/ratelimiting.
5
+
6
+ The version of the OpenAPI document: 1.0.0
7
+ Contact: api@snaptrade.com
8
+ =end
9
+
10
+ require 'date'
11
+ require 'time'
12
+
13
+ module SnapTrade
14
+ # One leg of an order.
15
+ class AccountOrderLeg
16
+ # Brokerage identifier for this leg, when the brokerage assigns one.
17
+ attr_accessor :leg_id
18
+
19
+ attr_accessor :instrument
20
+
21
+ # The action describes the intent or side of a trade. - BUY - SELL - BUY_COVER - SELL_SHORT - BUY_TO_OPEN - BUY_TO_CLOSE - SELL_TO_OPEN - SELL_TO_CLOSE
22
+ attr_accessor :action
23
+
24
+ # Total number of shares or contracts for this leg. Can be a decimal for fractional orders.
25
+ attr_accessor :total_quantity
26
+
27
+ # Number of shares or contracts filled for this leg.
28
+ attr_accessor :filled_quantity
29
+
30
+ # Number of shares or contracts canceled for this leg.
31
+ attr_accessor :canceled_quantity
32
+
33
+ # Average execution price for this leg, when available.
34
+ attr_accessor :execution_price
35
+
36
+ attr_accessor :status
37
+
38
+ # Attribute mapping from ruby-style variable name to JSON key.
39
+ def self.attribute_map
40
+ {
41
+ :'leg_id' => :'leg_id',
42
+ :'instrument' => :'instrument',
43
+ :'action' => :'action',
44
+ :'total_quantity' => :'total_quantity',
45
+ :'filled_quantity' => :'filled_quantity',
46
+ :'canceled_quantity' => :'canceled_quantity',
47
+ :'execution_price' => :'execution_price',
48
+ :'status' => :'status'
49
+ }
50
+ end
51
+
52
+ # Returns all the JSON keys this model knows about
53
+ def self.acceptable_attributes
54
+ attribute_map.values
55
+ end
56
+
57
+ # Attribute type mapping.
58
+ def self.openapi_types
59
+ {
60
+ :'leg_id' => :'String',
61
+ :'instrument' => :'Instrument',
62
+ :'action' => :'String',
63
+ :'total_quantity' => :'Float',
64
+ :'filled_quantity' => :'Float',
65
+ :'canceled_quantity' => :'Float',
66
+ :'execution_price' => :'Float',
67
+ :'status' => :'AccountOrderRecordStatusV2'
68
+ }
69
+ end
70
+
71
+ # List of attributes with nullable: true
72
+ def self.openapi_nullable
73
+ Set.new([
74
+ :'leg_id',
75
+ :'total_quantity',
76
+ :'filled_quantity',
77
+ :'canceled_quantity',
78
+ :'execution_price',
79
+ :'status'
80
+ ])
81
+ end
82
+
83
+ # Initializes the object
84
+ # @param [Hash] attributes Model attributes in the form of hash
85
+ def initialize(attributes = {})
86
+ if (!attributes.is_a?(Hash))
87
+ fail ArgumentError, "The input argument (attributes) must be a hash in `SnapTrade::AccountOrderLeg` initialize method"
88
+ end
89
+
90
+ # check to see if the attribute exists and convert string to symbol for hash key
91
+ attributes = attributes.each_with_object({}) { |(k, v), h|
92
+ if (!self.class.attribute_map.key?(k.to_sym))
93
+ fail ArgumentError, "`#{k}` is not a valid attribute in `SnapTrade::AccountOrderLeg`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
94
+ end
95
+ h[k.to_sym] = v
96
+ }
97
+
98
+ if attributes.key?(:'leg_id')
99
+ self.leg_id = attributes[:'leg_id']
100
+ end
101
+
102
+ if attributes.key?(:'instrument')
103
+ self.instrument = attributes[:'instrument']
104
+ end
105
+
106
+ if attributes.key?(:'action')
107
+ self.action = attributes[:'action']
108
+ end
109
+
110
+ if attributes.key?(:'total_quantity')
111
+ self.total_quantity = attributes[:'total_quantity']
112
+ end
113
+
114
+ if attributes.key?(:'filled_quantity')
115
+ self.filled_quantity = attributes[:'filled_quantity']
116
+ end
117
+
118
+ if attributes.key?(:'canceled_quantity')
119
+ self.canceled_quantity = attributes[:'canceled_quantity']
120
+ end
121
+
122
+ if attributes.key?(:'execution_price')
123
+ self.execution_price = attributes[:'execution_price']
124
+ end
125
+
126
+ if attributes.key?(:'status')
127
+ self.status = attributes[:'status']
128
+ end
129
+ end
130
+
131
+ # Show invalid properties with the reasons. Usually used together with valid?
132
+ # @return Array for valid properties with the reasons
133
+ def list_invalid_properties
134
+ invalid_properties = Array.new
135
+ if @instrument.nil?
136
+ invalid_properties.push('invalid value for "instrument", instrument cannot be nil.')
137
+ end
138
+
139
+ if @action.nil?
140
+ invalid_properties.push('invalid value for "action", action cannot be nil.')
141
+ end
142
+
143
+ invalid_properties
144
+ end
145
+
146
+ # Check to see if the all the properties in the model are valid
147
+ # @return true if the model is valid
148
+ def valid?
149
+ return false if @instrument.nil?
150
+ return false if @action.nil?
151
+ true
152
+ end
153
+
154
+ # Checks equality by comparing each attribute.
155
+ # @param [Object] Object to be compared
156
+ def ==(o)
157
+ return true if self.equal?(o)
158
+ self.class == o.class &&
159
+ leg_id == o.leg_id &&
160
+ instrument == o.instrument &&
161
+ action == o.action &&
162
+ total_quantity == o.total_quantity &&
163
+ filled_quantity == o.filled_quantity &&
164
+ canceled_quantity == o.canceled_quantity &&
165
+ execution_price == o.execution_price &&
166
+ status == o.status
167
+ end
168
+
169
+ # @see the `==` method
170
+ # @param [Object] Object to be compared
171
+ def eql?(o)
172
+ self == o
173
+ end
174
+
175
+ # Calculates hash code according to all attributes.
176
+ # @return [Integer] Hash code
177
+ def hash
178
+ [leg_id, instrument, action, total_quantity, filled_quantity, canceled_quantity, execution_price, status].hash
179
+ end
180
+
181
+ # Builds the object from hash
182
+ # @param [Hash] attributes Model attributes in the form of hash
183
+ # @return [Object] Returns the model itself
184
+ def self.build_from_hash(attributes)
185
+ new.build_from_hash(attributes)
186
+ end
187
+
188
+ # Builds the object from hash
189
+ # @param [Hash] attributes Model attributes in the form of hash
190
+ # @return [Object] Returns the model itself
191
+ def build_from_hash(attributes)
192
+ return nil unless attributes.is_a?(Hash)
193
+ attributes = attributes.transform_keys(&:to_sym)
194
+ self.class.openapi_types.each_pair do |key, type|
195
+ if attributes[self.class.attribute_map[key]].nil? && self.class.openapi_nullable.include?(key)
196
+ self.send("#{key}=", nil)
197
+ elsif type =~ /\AArray<(.*)>/i
198
+ # check to ensure the input is an array given that the attribute
199
+ # is documented as an array but the input is not
200
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
201
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
202
+ end
203
+ elsif !attributes[self.class.attribute_map[key]].nil?
204
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
205
+ end
206
+ end
207
+
208
+ self
209
+ end
210
+
211
+ # Deserializes the data based on type
212
+ # @param string type Data type
213
+ # @param string value Value to be deserialized
214
+ # @return [Object] Deserialized data
215
+ def _deserialize(type, value)
216
+ case type.to_sym
217
+ when :Time
218
+ Time.parse(value)
219
+ when :Date
220
+ Date.parse(value)
221
+ when :String
222
+ value.to_s
223
+ when :Integer
224
+ value.to_i
225
+ when :Float
226
+ value.to_f
227
+ when :Boolean
228
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
229
+ true
230
+ else
231
+ false
232
+ end
233
+ when :Object
234
+ # generic object (usually a Hash), return directly
235
+ value
236
+ when /\AArray<(?<inner_type>.+)>\z/
237
+ inner_type = Regexp.last_match[:inner_type]
238
+ value.map { |v| _deserialize(inner_type, v) }
239
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
240
+ k_type = Regexp.last_match[:k_type]
241
+ v_type = Regexp.last_match[:v_type]
242
+ {}.tap do |hash|
243
+ value.each do |k, v|
244
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
245
+ end
246
+ end
247
+ else # model
248
+ # models (e.g. Pet) or oneOf
249
+ klass = SnapTrade.const_get(type)
250
+ klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
251
+ end
252
+ end
253
+
254
+ # Returns the string representation of the object
255
+ # @return [String] String presentation of the object
256
+ def to_s
257
+ to_hash.to_s
258
+ end
259
+
260
+ # to_body is an alias to to_hash (backward compatibility)
261
+ # @return [Hash] Returns the object in the form of hash
262
+ def to_body
263
+ to_hash
264
+ end
265
+
266
+ # Returns the object in the form of hash
267
+ # @return [Hash] Returns the object in the form of hash
268
+ def to_hash
269
+ hash = {}
270
+ self.class.attribute_map.each_pair do |attr, param|
271
+ value = self.send(attr)
272
+ if value.nil?
273
+ is_nullable = self.class.openapi_nullable.include?(attr)
274
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
275
+ end
276
+
277
+ hash[param] = _to_hash(value)
278
+ end
279
+ hash
280
+ end
281
+
282
+ # Outputs non-array value in the form of hash
283
+ # For object, use to_hash. Otherwise, just return the value
284
+ # @param [Object] value Any valid value
285
+ # @return [Hash] Returns the value in the form of hash
286
+ def _to_hash(value)
287
+ if value.is_a?(Array)
288
+ value.compact.map { |v| _to_hash(v) }
289
+ elsif value.is_a?(Hash)
290
+ {}.tap do |hash|
291
+ value.each { |k, v| hash[k] = _to_hash(v) }
292
+ end
293
+ elsif value.respond_to? :to_hash
294
+ value.to_hash
295
+ else
296
+ value
297
+ end
298
+ end
299
+
300
+ end
301
+
302
+ end
@@ -57,6 +57,28 @@ module SnapTrade
57
57
  # List of legs that make up the order.
58
58
  attr_accessor :legs
59
59
 
60
+ class EnumAttributeValidator
61
+ attr_reader :datatype
62
+ attr_reader :allowable_values
63
+
64
+ def initialize(datatype, allowable_values)
65
+ @allowable_values = allowable_values.map do |value|
66
+ case datatype.to_s
67
+ when /Integer/i
68
+ value.to_i
69
+ when /Float/i
70
+ value.to_f
71
+ else
72
+ value
73
+ end
74
+ end
75
+ end
76
+
77
+ def valid?(value)
78
+ !value || allowable_values.include?(value)
79
+ end
80
+ end
81
+
60
82
  # Attribute mapping from ruby-style variable name to JSON key.
61
83
  def self.attribute_map
62
84
  {
@@ -95,7 +117,7 @@ module SnapTrade
95
117
  :'time_placed' => :'Time',
96
118
  :'time_executed' => :'Time',
97
119
  :'price_currency' => :'String',
98
- :'price_effect' => :'PriceEffect',
120
+ :'price_effect' => :'String',
99
121
  :'execution_price' => :'Float',
100
122
  :'limit_price' => :'Float',
101
123
  :'stop_price' => :'Float',
@@ -211,9 +233,21 @@ module SnapTrade
211
233
  # @return true if the model is valid
212
234
  def valid?
213
235
  return false if @price_effect.nil?
236
+ price_effect_validator = EnumAttributeValidator.new('String', ["CREDIT", "DEBIT", "EVEN", "UNKNOWN"])
237
+ return false unless price_effect_validator.valid?(@price_effect)
214
238
  true
215
239
  end
216
240
 
241
+ # Custom attribute writer method checking allowed values (enum).
242
+ # @param [Object] price_effect Object to be assigned
243
+ def price_effect=(price_effect)
244
+ validator = EnumAttributeValidator.new('String', ["CREDIT", "DEBIT", "EVEN", "UNKNOWN"])
245
+ unless validator.valid?(price_effect)
246
+ fail ArgumentError, "invalid value for \"price_effect\", must be one of #{validator.allowable_values}."
247
+ end
248
+ @price_effect = price_effect
249
+ end
250
+
217
251
  # Checks equality by comparing each attribute.
218
252
  # @param [Object] Object to be compared
219
253
  def ==(o)
@@ -0,0 +1,44 @@
1
+ =begin
2
+ #SnapTrade
3
+
4
+ #Connect brokerage accounts to your app for live positions and trading. ## Rate limiting Two limits apply to requests signed with your `clientId`. The stricter one wins, and exceeding either returns `429 Too Many Requests`. - **Customer-level** — 250 requests/minute by default, scoped to your `clientId` and applied across all endpoints. Reported in `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. - **Account-level** — 10 requests/minute per account, scoped to (`clientId`, `accountId`). All covered operations for one account draw on the same bucket — reading balances and reading positions share it — and enforcement does not depend on the HTTP method, so updating an account consumes the same bucket as reading it. Only enforced for Personal users, and only for integrations it has been rolled out to — it is not yet in force for every Personal integration. It also does not apply on every operation that documents a 429 below. Where it applies it is reported in `X-RateLimit-Account-Limit`, `X-RateLimit-Account-Remaining` and `X-RateLimit-Account-Reset`. Do not read the absence of those headers as proof the limit is off — some configurations omit the rate limit headers while still enforcing the limit, so header absence tells you nothing about your allowance. On a 429, `X-RateLimit-Remaining: 0` means you hit the customer-level limit and `X-RateLimit-Account-Remaining: 0` means the account-level one. Wait for the corresponding `*-Reset` value (seconds) before retrying, or fall back to exponential backoff with jitter. Not every 429 is explained by those headers. A separate per-authenticated-user limit, reported in no `X-RateLimit-*` header, covers OAuth-authenticated requests and signed requests in configurations where the customer-level limit is not in effect — on the operations that use the default throttles. A few operations override those and are governed by the customer-level limit alone. The two do not stack: a signed request governed by the customer-level limit above is not additionally subject to the per-user one. If a 429 arrives with no header at zero — or with no `X-RateLimit-*` headers at all — honour `Retry-After` and back off. Treat the remaining counts as a hint, not a guarantee that the next request will succeed. Because the customer-level limit applies everywhere, any signed request can return 429. **OAuth-authenticated requests are an exception.** They are not subject to the customer-level limit and do not receive `X-RateLimit-Limit`, `X-RateLimit-Remaining` or `X-RateLimit-Reset` — do not wait on those headers or design around a customer-level allowance on this path. The account-level limit still applies to them on the account-data endpoints above, reported in the `X-RateLimit-Account-*` headers. On operations using the default throttles the per-user limit above applies to them as well, so an OAuth request can be rejected while the account headers still show capacity; on the few operations that override those throttles, OAuth callers have no per-user ceiling at all. Drive retries from `Retry-After` and exponential backoff with jitter rather than from the headers. See https://docs.snaptrade.com/docs/ratelimiting.
5
+
6
+ The version of the OpenAPI document: 1.0.0
7
+ Contact: api@snaptrade.com
8
+ =end
9
+
10
+ require 'date'
11
+ require 'time'
12
+
13
+ module SnapTrade
14
+ class AccountOrderTimeInForce
15
+ DAY = "DAY".freeze
16
+ GTC = "GTC".freeze
17
+ FOK = "FOK".freeze
18
+ IOC = "IOC".freeze
19
+ GTD = "GTD".freeze
20
+ MOO = "MOO".freeze
21
+ EHP = "EHP".freeze
22
+ EHA = "EHA".freeze
23
+ OTHER = "OTHER".freeze
24
+
25
+ def self.all_vars
26
+ @all_vars ||= [DAY, GTC, FOK, IOC, GTD, MOO, EHP, EHA, OTHER].freeze
27
+ end
28
+
29
+ # Builds the enum from string
30
+ # @param [String] The enum value in the form of the string
31
+ # @return [String] The enum value
32
+ def self.build_from_hash(value)
33
+ new.build_from_hash(value)
34
+ end
35
+
36
+ # Builds the enum from string
37
+ # @param [String] The enum value in the form of the string
38
+ # @return [String] The enum value
39
+ def build_from_hash(value)
40
+ return value if AccountOrderTimeInForce.all_vars.include?(value)
41
+ raise "Invalid ENUM value #{value} for class #AccountOrderTimeInForce"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,239 @@
1
+ =begin
2
+ #SnapTrade
3
+
4
+ #Connect brokerage accounts to your app for live positions and trading. ## Rate limiting Two limits apply to requests signed with your `clientId`. The stricter one wins, and exceeding either returns `429 Too Many Requests`. - **Customer-level** — 250 requests/minute by default, scoped to your `clientId` and applied across all endpoints. Reported in `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. - **Account-level** — 10 requests/minute per account, scoped to (`clientId`, `accountId`). All covered operations for one account draw on the same bucket — reading balances and reading positions share it — and enforcement does not depend on the HTTP method, so updating an account consumes the same bucket as reading it. Only enforced for Personal users, and only for integrations it has been rolled out to — it is not yet in force for every Personal integration. It also does not apply on every operation that documents a 429 below. Where it applies it is reported in `X-RateLimit-Account-Limit`, `X-RateLimit-Account-Remaining` and `X-RateLimit-Account-Reset`. Do not read the absence of those headers as proof the limit is off — some configurations omit the rate limit headers while still enforcing the limit, so header absence tells you nothing about your allowance. On a 429, `X-RateLimit-Remaining: 0` means you hit the customer-level limit and `X-RateLimit-Account-Remaining: 0` means the account-level one. Wait for the corresponding `*-Reset` value (seconds) before retrying, or fall back to exponential backoff with jitter. Not every 429 is explained by those headers. A separate per-authenticated-user limit, reported in no `X-RateLimit-*` header, covers OAuth-authenticated requests and signed requests in configurations where the customer-level limit is not in effect — on the operations that use the default throttles. A few operations override those and are governed by the customer-level limit alone. The two do not stack: a signed request governed by the customer-level limit above is not additionally subject to the per-user one. If a 429 arrives with no header at zero — or with no `X-RateLimit-*` headers at all — honour `Retry-After` and back off. Treat the remaining counts as a hint, not a guarantee that the next request will succeed. Because the customer-level limit applies everywhere, any signed request can return 429. **OAuth-authenticated requests are an exception.** They are not subject to the customer-level limit and do not receive `X-RateLimit-Limit`, `X-RateLimit-Remaining` or `X-RateLimit-Reset` — do not wait on those headers or design around a customer-level allowance on this path. The account-level limit still applies to them on the account-data endpoints above, reported in the `X-RateLimit-Account-*` headers. On operations using the default throttles the per-user limit above applies to them as well, so an OAuth request can be rejected while the account headers still show capacity; on the few operations that override those throttles, OAuth callers have no per-user ceiling at all. Drive retries from `Retry-After` and exponential backoff with jitter rather than from the headers. See https://docs.snaptrade.com/docs/ratelimiting.
5
+
6
+ The version of the OpenAPI document: 1.0.0
7
+ Contact: api@snaptrade.com
8
+ =end
9
+
10
+ require 'date'
11
+ require 'time'
12
+
13
+ module SnapTrade
14
+ # Orders in the `kind`-discriminated format returned by `/accounts/{accountId}/orders/all`.
15
+ class AllAccountOrdersResponse
16
+ # Orders returned for the request.
17
+ attr_accessor :results
18
+
19
+ attr_accessor :data_freshness
20
+
21
+ # Attribute mapping from ruby-style variable name to JSON key.
22
+ def self.attribute_map
23
+ {
24
+ :'results' => :'results',
25
+ :'data_freshness' => :'data_freshness'
26
+ }
27
+ end
28
+
29
+ # Returns all the JSON keys this model knows about
30
+ def self.acceptable_attributes
31
+ attribute_map.values
32
+ end
33
+
34
+ # Attribute type mapping.
35
+ def self.openapi_types
36
+ {
37
+ :'results' => :'Array<AccountOrder>',
38
+ :'data_freshness' => :'AllAccountOrdersResponseDataFreshness'
39
+ }
40
+ end
41
+
42
+ # List of attributes with nullable: true
43
+ def self.openapi_nullable
44
+ Set.new([
45
+ ])
46
+ end
47
+
48
+ # Initializes the object
49
+ # @param [Hash] attributes Model attributes in the form of hash
50
+ def initialize(attributes = {})
51
+ if (!attributes.is_a?(Hash))
52
+ fail ArgumentError, "The input argument (attributes) must be a hash in `SnapTrade::AllAccountOrdersResponse` initialize method"
53
+ end
54
+
55
+ # check to see if the attribute exists and convert string to symbol for hash key
56
+ attributes = attributes.each_with_object({}) { |(k, v), h|
57
+ if (!self.class.attribute_map.key?(k.to_sym))
58
+ fail ArgumentError, "`#{k}` is not a valid attribute in `SnapTrade::AllAccountOrdersResponse`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
59
+ end
60
+ h[k.to_sym] = v
61
+ }
62
+
63
+ if attributes.key?(:'results')
64
+ if (value = attributes[:'results']).is_a?(Array)
65
+ self.results = value
66
+ end
67
+ end
68
+
69
+ if attributes.key?(:'data_freshness')
70
+ self.data_freshness = attributes[:'data_freshness']
71
+ end
72
+ end
73
+
74
+ # Show invalid properties with the reasons. Usually used together with valid?
75
+ # @return Array for valid properties with the reasons
76
+ def list_invalid_properties
77
+ invalid_properties = Array.new
78
+ if @results.nil?
79
+ invalid_properties.push('invalid value for "results", results cannot be nil.')
80
+ end
81
+
82
+ if @data_freshness.nil?
83
+ invalid_properties.push('invalid value for "data_freshness", data_freshness cannot be nil.')
84
+ end
85
+
86
+ invalid_properties
87
+ end
88
+
89
+ # Check to see if the all the properties in the model are valid
90
+ # @return true if the model is valid
91
+ def valid?
92
+ return false if @results.nil?
93
+ return false if @data_freshness.nil?
94
+ true
95
+ end
96
+
97
+ # Checks equality by comparing each attribute.
98
+ # @param [Object] Object to be compared
99
+ def ==(o)
100
+ return true if self.equal?(o)
101
+ self.class == o.class &&
102
+ results == o.results &&
103
+ data_freshness == o.data_freshness
104
+ end
105
+
106
+ # @see the `==` method
107
+ # @param [Object] Object to be compared
108
+ def eql?(o)
109
+ self == o
110
+ end
111
+
112
+ # Calculates hash code according to all attributes.
113
+ # @return [Integer] Hash code
114
+ def hash
115
+ [results, data_freshness].hash
116
+ end
117
+
118
+ # Builds the object from hash
119
+ # @param [Hash] attributes Model attributes in the form of hash
120
+ # @return [Object] Returns the model itself
121
+ def self.build_from_hash(attributes)
122
+ new.build_from_hash(attributes)
123
+ end
124
+
125
+ # Builds the object from hash
126
+ # @param [Hash] attributes Model attributes in the form of hash
127
+ # @return [Object] Returns the model itself
128
+ def build_from_hash(attributes)
129
+ return nil unless attributes.is_a?(Hash)
130
+ attributes = attributes.transform_keys(&:to_sym)
131
+ self.class.openapi_types.each_pair do |key, type|
132
+ if attributes[self.class.attribute_map[key]].nil? && self.class.openapi_nullable.include?(key)
133
+ self.send("#{key}=", nil)
134
+ elsif type =~ /\AArray<(.*)>/i
135
+ # check to ensure the input is an array given that the attribute
136
+ # is documented as an array but the input is not
137
+ if attributes[self.class.attribute_map[key]].is_a?(Array)
138
+ self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
139
+ end
140
+ elsif !attributes[self.class.attribute_map[key]].nil?
141
+ self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
142
+ end
143
+ end
144
+
145
+ self
146
+ end
147
+
148
+ # Deserializes the data based on type
149
+ # @param string type Data type
150
+ # @param string value Value to be deserialized
151
+ # @return [Object] Deserialized data
152
+ def _deserialize(type, value)
153
+ case type.to_sym
154
+ when :Time
155
+ Time.parse(value)
156
+ when :Date
157
+ Date.parse(value)
158
+ when :String
159
+ value.to_s
160
+ when :Integer
161
+ value.to_i
162
+ when :Float
163
+ value.to_f
164
+ when :Boolean
165
+ if value.to_s =~ /\A(true|t|yes|y|1)\z/i
166
+ true
167
+ else
168
+ false
169
+ end
170
+ when :Object
171
+ # generic object (usually a Hash), return directly
172
+ value
173
+ when /\AArray<(?<inner_type>.+)>\z/
174
+ inner_type = Regexp.last_match[:inner_type]
175
+ value.map { |v| _deserialize(inner_type, v) }
176
+ when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
177
+ k_type = Regexp.last_match[:k_type]
178
+ v_type = Regexp.last_match[:v_type]
179
+ {}.tap do |hash|
180
+ value.each do |k, v|
181
+ hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
182
+ end
183
+ end
184
+ else # model
185
+ # models (e.g. Pet) or oneOf
186
+ klass = SnapTrade.const_get(type)
187
+ klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
188
+ end
189
+ end
190
+
191
+ # Returns the string representation of the object
192
+ # @return [String] String presentation of the object
193
+ def to_s
194
+ to_hash.to_s
195
+ end
196
+
197
+ # to_body is an alias to to_hash (backward compatibility)
198
+ # @return [Hash] Returns the object in the form of hash
199
+ def to_body
200
+ to_hash
201
+ end
202
+
203
+ # Returns the object in the form of hash
204
+ # @return [Hash] Returns the object in the form of hash
205
+ def to_hash
206
+ hash = {}
207
+ self.class.attribute_map.each_pair do |attr, param|
208
+ value = self.send(attr)
209
+ if value.nil?
210
+ is_nullable = self.class.openapi_nullable.include?(attr)
211
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
212
+ end
213
+
214
+ hash[param] = _to_hash(value)
215
+ end
216
+ hash
217
+ end
218
+
219
+ # Outputs non-array value in the form of hash
220
+ # For object, use to_hash. Otherwise, just return the value
221
+ # @param [Object] value Any valid value
222
+ # @return [Hash] Returns the value in the form of hash
223
+ def _to_hash(value)
224
+ if value.is_a?(Array)
225
+ value.compact.map { |v| _to_hash(v) }
226
+ elsif value.is_a?(Hash)
227
+ {}.tap do |hash|
228
+ value.each { |k, v| hash[k] = _to_hash(v) }
229
+ end
230
+ elsif value.respond_to? :to_hash
231
+ value.to_hash
232
+ else
233
+ value
234
+ end
235
+ end
236
+
237
+ end
238
+
239
+ end