snaptrade 2.0.19 → 2.0.20
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +8 -8
- data/lib/snaptrade/api/trading_api.rb +8 -8
- data/lib/snaptrade/models/account_order_record.rb +2 -2
- data/lib/snaptrade/models/{action.rb → action_strict.rb} +3 -3
- data/lib/snaptrade/models/manual_trade.rb +1 -1
- data/lib/snaptrade/models/manual_trade_form.rb +2 -2
- data/lib/snaptrade/models/manual_trade_form_notional_value.rb +214 -0
- data/lib/snaptrade/models/notional_value.rb +103 -0
- data/lib/snaptrade/models/session_event_type.rb +11 -3
- data/lib/snaptrade/version.rb +1 -1
- data/lib/snaptrade.rb +3 -1
- data/spec/models/action_strict_spec.rb +23 -0
- data/spec/models/manual_trade_form_notional_value_spec.rb +23 -0
- data/spec/models/notional_value_spec.rb +26 -0
- metadata +11 -5
- data/spec/models/action_spec.rb +0 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 40178dd356fa3c53ef0a09c17cfeccc3ac900992803129689f3df8d605c0aae5
|
|
4
|
+
data.tar.gz: 9a1f4f13933f789bb1cf6d69b86195353ad9557c56f5db8ca18b34301aa6a024
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52650a4f991bed16a72ead70654b6f58a8b1d774ce567b45363362f446e60b17696b98d217d366c67d056febf28bb6f9db0a0f503f2f088e9423b5ab33fb65fd
|
|
7
|
+
data.tar.gz: 9e40c527f3b8b9c7c5e7b0d442544ac89d348583aed99a81ea8dc71c3050278e1ed00db14a79293ffc16a34dae3d5854dd617d440e122ac394008bd7a0bc43ba
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
Connect brokerage accounts to your app for live positions and trading
|
|
8
8
|
|
|
9
|
-
[](https://rubygems.org/gems/snaptrade/versions/2.0.20)
|
|
10
10
|
[](https://snaptrade.com/)
|
|
11
11
|
|
|
12
12
|
</div>
|
|
@@ -69,7 +69,7 @@ Connect brokerage accounts to your app for live positions and trading
|
|
|
69
69
|
Add to Gemfile:
|
|
70
70
|
|
|
71
71
|
```ruby
|
|
72
|
-
gem 'snaptrade', '~> 2.0.
|
|
72
|
+
gem 'snaptrade', '~> 2.0.20'
|
|
73
73
|
```
|
|
74
74
|
|
|
75
75
|
## Getting Started<a id="getting-started"></a>
|
|
@@ -1356,7 +1356,7 @@ result = snaptrade.trading.get_order_impact(
|
|
|
1356
1356
|
time_in_force: "FOK",
|
|
1357
1357
|
units: 3.14,
|
|
1358
1358
|
universal_symbol_id: "2bcd7cc3-e922-4976-bce1-9858296801c3",
|
|
1359
|
-
notional_value:
|
|
1359
|
+
notional_value: None,
|
|
1360
1360
|
)
|
|
1361
1361
|
p result
|
|
1362
1362
|
```
|
|
@@ -1366,7 +1366,7 @@ p result
|
|
|
1366
1366
|
##### user_id: `String`<a id="user_id-string"></a>
|
|
1367
1367
|
##### user_secret: `String`<a id="user_secret-string"></a>
|
|
1368
1368
|
##### account_id: `String`<a id="account_id-string"></a>
|
|
1369
|
-
##### action: [`
|
|
1369
|
+
##### action: [`ActionStrict`](./lib/snaptrade/models/action_strict.rb)<a id="action-actionstrictlibsnaptrademodelsaction_strictrb"></a>
|
|
1370
1370
|
Trade Action
|
|
1371
1371
|
|
|
1372
1372
|
##### order_type: [`OrderTypeStrict`](./lib/snaptrade/models/order_type_strict.rb)<a id="order_type-ordertypestrictlibsnaptrademodelsorder_type_strictrb"></a>
|
|
@@ -1384,7 +1384,7 @@ Canceled
|
|
|
1384
1384
|
|
|
1385
1385
|
##### units: [`Float`](./lib/snaptrade/models/float.rb)<a id="units-floatlibsnaptrademodelsfloatrb"></a>
|
|
1386
1386
|
##### universal_symbol_id: `String`<a id="universal_symbol_id-string"></a>
|
|
1387
|
-
##### notional_value: [`
|
|
1387
|
+
##### notional_value: [`ManualTradeFormNotionalValue`](./lib/snaptrade/models/manual_trade_form_notional_value.rb)<a id="notional_value-manualtradeformnotionalvaluelibsnaptrademodelsmanual_trade_form_notional_valuerb"></a>
|
|
1388
1388
|
#### 🔄 Return<a id="🔄-return"></a>
|
|
1389
1389
|
|
|
1390
1390
|
[ManualTradeAndImpact](./lib/snaptrade/models/manual_trade_and_impact.rb)
|
|
@@ -1459,7 +1459,7 @@ result = snaptrade.trading.place_force_order(
|
|
|
1459
1459
|
time_in_force: "FOK",
|
|
1460
1460
|
units: 3.14,
|
|
1461
1461
|
universal_symbol_id: "2bcd7cc3-e922-4976-bce1-9858296801c3",
|
|
1462
|
-
notional_value:
|
|
1462
|
+
notional_value: None,
|
|
1463
1463
|
)
|
|
1464
1464
|
p result
|
|
1465
1465
|
```
|
|
@@ -1469,7 +1469,7 @@ p result
|
|
|
1469
1469
|
##### user_id: `String`<a id="user_id-string"></a>
|
|
1470
1470
|
##### user_secret: `String`<a id="user_secret-string"></a>
|
|
1471
1471
|
##### account_id: `String`<a id="account_id-string"></a>
|
|
1472
|
-
##### action: [`
|
|
1472
|
+
##### action: [`ActionStrict`](./lib/snaptrade/models/action_strict.rb)<a id="action-actionstrictlibsnaptrademodelsaction_strictrb"></a>
|
|
1473
1473
|
Trade Action
|
|
1474
1474
|
|
|
1475
1475
|
##### order_type: [`OrderTypeStrict`](./lib/snaptrade/models/order_type_strict.rb)<a id="order_type-ordertypestrictlibsnaptrademodelsorder_type_strictrb"></a>
|
|
@@ -1487,7 +1487,7 @@ Canceled
|
|
|
1487
1487
|
|
|
1488
1488
|
##### units: [`Float`](./lib/snaptrade/models/float.rb)<a id="units-floatlibsnaptrademodelsfloatrb"></a>
|
|
1489
1489
|
##### universal_symbol_id: `String`<a id="universal_symbol_id-string"></a>
|
|
1490
|
-
##### notional_value: [`
|
|
1490
|
+
##### notional_value: [`ManualTradeFormNotionalValue`](./lib/snaptrade/models/manual_trade_form_notional_value.rb)<a id="notional_value-manualtradeformnotionalvaluelibsnaptrademodelsmanual_trade_form_notional_valuerb"></a>
|
|
1491
1491
|
#### 🔄 Return<a id="🔄-return"></a>
|
|
1492
1492
|
|
|
1493
1493
|
[AccountOrderRecord](./lib/snaptrade/models/account_order_record.rb)
|
|
@@ -150,14 +150,14 @@ module SnapTrade
|
|
|
150
150
|
# @param user_id [String]
|
|
151
151
|
# @param user_secret [String]
|
|
152
152
|
# @param account_id [String]
|
|
153
|
-
# @param action [
|
|
153
|
+
# @param action [ActionStrict] Trade Action
|
|
154
154
|
# @param order_type [OrderTypeStrict] Order Type
|
|
155
155
|
# @param price [Float] Trade Price if limit or stop limit order
|
|
156
156
|
# @param stop [Float] Stop Price. If stop loss or stop limit order, the price to trigger the stop
|
|
157
157
|
# @param time_in_force [TimeInForceStrict] Trade time in force examples: * FOK - Fill Or Kill * Day - Day * GTC - Good Til Canceled
|
|
158
158
|
# @param units [Float]
|
|
159
159
|
# @param universal_symbol_id [String]
|
|
160
|
-
# @param notional_value [
|
|
160
|
+
# @param notional_value [ManualTradeFormNotionalValue]
|
|
161
161
|
# @param body [ManualTradeForm]
|
|
162
162
|
# @param [Hash] extra additional parameters to pass along through :header_params, :query_params, or parameter name
|
|
163
163
|
def get_order_impact(user_id:, user_secret:, account_id: SENTINEL, action: SENTINEL, order_type: SENTINEL, price: SENTINEL, stop: SENTINEL, time_in_force: SENTINEL, units: SENTINEL, universal_symbol_id: SENTINEL, notional_value: SENTINEL, extra: {})
|
|
@@ -183,14 +183,14 @@ module SnapTrade
|
|
|
183
183
|
# @param user_id [String]
|
|
184
184
|
# @param user_secret [String]
|
|
185
185
|
# @param account_id [String]
|
|
186
|
-
# @param action [
|
|
186
|
+
# @param action [ActionStrict] Trade Action
|
|
187
187
|
# @param order_type [OrderTypeStrict] Order Type
|
|
188
188
|
# @param price [Float] Trade Price if limit or stop limit order
|
|
189
189
|
# @param stop [Float] Stop Price. If stop loss or stop limit order, the price to trigger the stop
|
|
190
190
|
# @param time_in_force [TimeInForceStrict] Trade time in force examples: * FOK - Fill Or Kill * Day - Day * GTC - Good Til Canceled
|
|
191
191
|
# @param units [Float]
|
|
192
192
|
# @param universal_symbol_id [String]
|
|
193
|
-
# @param notional_value [
|
|
193
|
+
# @param notional_value [ManualTradeFormNotionalValue]
|
|
194
194
|
# @param body [ManualTradeForm]
|
|
195
195
|
# @param [Hash] extra additional parameters to pass along through :header_params, :query_params, or parameter name
|
|
196
196
|
def get_order_impact_with_http_info(user_id:, user_secret:, account_id: SENTINEL, action: SENTINEL, order_type: SENTINEL, price: SENTINEL, stop: SENTINEL, time_in_force: SENTINEL, units: SENTINEL, universal_symbol_id: SENTINEL, notional_value: SENTINEL, extra: {})
|
|
@@ -417,14 +417,14 @@ module SnapTrade
|
|
|
417
417
|
# @param user_id [String]
|
|
418
418
|
# @param user_secret [String]
|
|
419
419
|
# @param account_id [String]
|
|
420
|
-
# @param action [
|
|
420
|
+
# @param action [ActionStrict] Trade Action
|
|
421
421
|
# @param order_type [OrderTypeStrict] Order Type
|
|
422
422
|
# @param price [Float] Trade Price if limit or stop limit order
|
|
423
423
|
# @param stop [Float] Stop Price. If stop loss or stop limit order, the price to trigger the stop
|
|
424
424
|
# @param time_in_force [TimeInForceStrict] Trade time in force examples: * FOK - Fill Or Kill * Day - Day * GTC - Good Til Canceled
|
|
425
425
|
# @param units [Float]
|
|
426
426
|
# @param universal_symbol_id [String]
|
|
427
|
-
# @param notional_value [
|
|
427
|
+
# @param notional_value [ManualTradeFormNotionalValue]
|
|
428
428
|
# @param body [ManualTradeForm]
|
|
429
429
|
# @param [Hash] extra additional parameters to pass along through :header_params, :query_params, or parameter name
|
|
430
430
|
def place_force_order(user_id:, user_secret:, account_id: SENTINEL, action: SENTINEL, order_type: SENTINEL, price: SENTINEL, stop: SENTINEL, time_in_force: SENTINEL, units: SENTINEL, universal_symbol_id: SENTINEL, notional_value: SENTINEL, extra: {})
|
|
@@ -450,14 +450,14 @@ module SnapTrade
|
|
|
450
450
|
# @param user_id [String]
|
|
451
451
|
# @param user_secret [String]
|
|
452
452
|
# @param account_id [String]
|
|
453
|
-
# @param action [
|
|
453
|
+
# @param action [ActionStrict] Trade Action
|
|
454
454
|
# @param order_type [OrderTypeStrict] Order Type
|
|
455
455
|
# @param price [Float] Trade Price if limit or stop limit order
|
|
456
456
|
# @param stop [Float] Stop Price. If stop loss or stop limit order, the price to trigger the stop
|
|
457
457
|
# @param time_in_force [TimeInForceStrict] Trade time in force examples: * FOK - Fill Or Kill * Day - Day * GTC - Good Til Canceled
|
|
458
458
|
# @param units [Float]
|
|
459
459
|
# @param universal_symbol_id [String]
|
|
460
|
-
# @param notional_value [
|
|
460
|
+
# @param notional_value [ManualTradeFormNotionalValue]
|
|
461
461
|
# @param body [ManualTradeForm]
|
|
462
462
|
# @param [Hash] extra additional parameters to pass along through :header_params, :query_params, or parameter name
|
|
463
463
|
def place_force_order_with_http_info(user_id:, user_secret:, account_id: SENTINEL, action: SENTINEL, order_type: SENTINEL, price: SENTINEL, stop: SENTINEL, time_in_force: SENTINEL, units: SENTINEL, universal_symbol_id: SENTINEL, notional_value: SENTINEL, extra: {})
|
|
@@ -24,7 +24,7 @@ module SnapTrade
|
|
|
24
24
|
|
|
25
25
|
attr_accessor :option_symbol
|
|
26
26
|
|
|
27
|
-
# Trade Action
|
|
27
|
+
# Trade Action potential values include (but are not limited to) - BUY - SELL - BUY_COVER - SELL_SHORT - BUY_OPEN - BUY_CLOSE - SELL_OPEN - SELL_CLOSE
|
|
28
28
|
attr_accessor :action
|
|
29
29
|
|
|
30
30
|
attr_accessor :total_quantity
|
|
@@ -101,7 +101,7 @@ module SnapTrade
|
|
|
101
101
|
:'symbol' => :'String',
|
|
102
102
|
:'universal_symbol' => :'UniversalSymbol',
|
|
103
103
|
:'option_symbol' => :'OptionsSymbol',
|
|
104
|
-
:'action' => :'
|
|
104
|
+
:'action' => :'String',
|
|
105
105
|
:'total_quantity' => :'Float',
|
|
106
106
|
:'open_quantity' => :'Float',
|
|
107
107
|
:'canceled_quantity' => :'Float',
|
|
@@ -11,7 +11,7 @@ require 'date'
|
|
|
11
11
|
require 'time'
|
|
12
12
|
|
|
13
13
|
module SnapTrade
|
|
14
|
-
class
|
|
14
|
+
class ActionStrict
|
|
15
15
|
BUY = "BUY".freeze
|
|
16
16
|
SELL = "SELL".freeze
|
|
17
17
|
|
|
@@ -30,8 +30,8 @@ module SnapTrade
|
|
|
30
30
|
# @param [String] The enum value in the form of the string
|
|
31
31
|
# @return [String] The enum value
|
|
32
32
|
def build_from_hash(value)
|
|
33
|
-
return value if
|
|
34
|
-
raise "Invalid ENUM value #{value} for class #
|
|
33
|
+
return value if ActionStrict.all_vars.include?(value)
|
|
34
|
+
raise "Invalid ENUM value #{value} for class #ActionStrict"
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -60,14 +60,14 @@ module SnapTrade
|
|
|
60
60
|
def self.openapi_types
|
|
61
61
|
{
|
|
62
62
|
:'account_id' => :'String',
|
|
63
|
-
:'action' => :'
|
|
63
|
+
:'action' => :'ActionStrict',
|
|
64
64
|
:'order_type' => :'OrderTypeStrict',
|
|
65
65
|
:'price' => :'Float',
|
|
66
66
|
:'stop' => :'Float',
|
|
67
67
|
:'time_in_force' => :'TimeInForceStrict',
|
|
68
68
|
:'units' => :'Float',
|
|
69
69
|
:'universal_symbol_id' => :'String',
|
|
70
|
-
:'notional_value' => :'
|
|
70
|
+
:'notional_value' => :'ManualTradeFormNotionalValue'
|
|
71
71
|
}
|
|
72
72
|
end
|
|
73
73
|
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#SnapTrade
|
|
3
|
+
|
|
4
|
+
#Connect brokerage accounts to your app for live positions and trading
|
|
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 ManualTradeFormNotionalValue
|
|
15
|
+
# Attribute mapping from ruby-style variable name to JSON key.
|
|
16
|
+
def self.attribute_map
|
|
17
|
+
{
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Returns all the JSON keys this model knows about
|
|
22
|
+
def self.acceptable_attributes
|
|
23
|
+
attribute_map.values
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Attribute type mapping.
|
|
27
|
+
def self.openapi_types
|
|
28
|
+
{
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# List of attributes with nullable: true
|
|
33
|
+
def self.openapi_nullable
|
|
34
|
+
Set.new([
|
|
35
|
+
])
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# List of class defined in allOf (OpenAPI v3)
|
|
39
|
+
def self.openapi_all_of
|
|
40
|
+
[
|
|
41
|
+
:'NotionalValue'
|
|
42
|
+
]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Initializes the object
|
|
46
|
+
# @param [Hash] attributes Model attributes in the form of hash
|
|
47
|
+
def initialize(attributes = {})
|
|
48
|
+
if (!attributes.is_a?(Hash))
|
|
49
|
+
fail ArgumentError, "The input argument (attributes) must be a hash in `SnapTrade::ManualTradeFormNotionalValue` initialize method"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# check to see if the attribute exists and convert string to symbol for hash key
|
|
53
|
+
attributes = attributes.each_with_object({}) { |(k, v), h|
|
|
54
|
+
if (!self.class.attribute_map.key?(k.to_sym))
|
|
55
|
+
fail ArgumentError, "`#{k}` is not a valid attribute in `SnapTrade::ManualTradeFormNotionalValue`. Please check the name to make sure it's valid. List of attributes: " + self.class.attribute_map.keys.inspect
|
|
56
|
+
end
|
|
57
|
+
h[k.to_sym] = v
|
|
58
|
+
}
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Show invalid properties with the reasons. Usually used together with valid?
|
|
62
|
+
# @return Array for valid properties with the reasons
|
|
63
|
+
def list_invalid_properties
|
|
64
|
+
invalid_properties = Array.new
|
|
65
|
+
invalid_properties
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Check to see if the all the properties in the model are valid
|
|
69
|
+
# @return true if the model is valid
|
|
70
|
+
def valid?
|
|
71
|
+
true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Checks equality by comparing each attribute.
|
|
75
|
+
# @param [Object] Object to be compared
|
|
76
|
+
def ==(o)
|
|
77
|
+
return true if self.equal?(o)
|
|
78
|
+
self.class == o.class
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @see the `==` method
|
|
82
|
+
# @param [Object] Object to be compared
|
|
83
|
+
def eql?(o)
|
|
84
|
+
self == o
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Calculates hash code according to all attributes.
|
|
88
|
+
# @return [Integer] Hash code
|
|
89
|
+
def hash
|
|
90
|
+
[].hash
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Builds the object from hash
|
|
94
|
+
# @param [Hash] attributes Model attributes in the form of hash
|
|
95
|
+
# @return [Object] Returns the model itself
|
|
96
|
+
def self.build_from_hash(attributes)
|
|
97
|
+
new.build_from_hash(attributes)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Builds the object from hash
|
|
101
|
+
# @param [Hash] attributes Model attributes in the form of hash
|
|
102
|
+
# @return [Object] Returns the model itself
|
|
103
|
+
def build_from_hash(attributes)
|
|
104
|
+
return nil unless attributes.is_a?(Hash)
|
|
105
|
+
attributes = attributes.transform_keys(&:to_sym)
|
|
106
|
+
self.class.openapi_types.each_pair do |key, type|
|
|
107
|
+
if attributes[self.class.attribute_map[key]].nil? && self.class.openapi_nullable.include?(key)
|
|
108
|
+
self.send("#{key}=", nil)
|
|
109
|
+
elsif type =~ /\AArray<(.*)>/i
|
|
110
|
+
# check to ensure the input is an array given that the attribute
|
|
111
|
+
# is documented as an array but the input is not
|
|
112
|
+
if attributes[self.class.attribute_map[key]].is_a?(Array)
|
|
113
|
+
self.send("#{key}=", attributes[self.class.attribute_map[key]].map { |v| _deserialize($1, v) })
|
|
114
|
+
end
|
|
115
|
+
elsif !attributes[self.class.attribute_map[key]].nil?
|
|
116
|
+
self.send("#{key}=", _deserialize(type, attributes[self.class.attribute_map[key]]))
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
self
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Deserializes the data based on type
|
|
124
|
+
# @param string type Data type
|
|
125
|
+
# @param string value Value to be deserialized
|
|
126
|
+
# @return [Object] Deserialized data
|
|
127
|
+
def _deserialize(type, value)
|
|
128
|
+
case type.to_sym
|
|
129
|
+
when :Time
|
|
130
|
+
Time.parse(value)
|
|
131
|
+
when :Date
|
|
132
|
+
Date.parse(value)
|
|
133
|
+
when :String
|
|
134
|
+
value.to_s
|
|
135
|
+
when :Integer
|
|
136
|
+
value.to_i
|
|
137
|
+
when :Float
|
|
138
|
+
value.to_f
|
|
139
|
+
when :Boolean
|
|
140
|
+
if value.to_s =~ /\A(true|t|yes|y|1)\z/i
|
|
141
|
+
true
|
|
142
|
+
else
|
|
143
|
+
false
|
|
144
|
+
end
|
|
145
|
+
when :Object
|
|
146
|
+
# generic object (usually a Hash), return directly
|
|
147
|
+
value
|
|
148
|
+
when /\AArray<(?<inner_type>.+)>\z/
|
|
149
|
+
inner_type = Regexp.last_match[:inner_type]
|
|
150
|
+
value.map { |v| _deserialize(inner_type, v) }
|
|
151
|
+
when /\AHash<(?<k_type>.+?), (?<v_type>.+)>\z/
|
|
152
|
+
k_type = Regexp.last_match[:k_type]
|
|
153
|
+
v_type = Regexp.last_match[:v_type]
|
|
154
|
+
{}.tap do |hash|
|
|
155
|
+
value.each do |k, v|
|
|
156
|
+
hash[_deserialize(k_type, k)] = _deserialize(v_type, v)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
else # model
|
|
160
|
+
# models (e.g. Pet) or oneOf
|
|
161
|
+
klass = SnapTrade.const_get(type)
|
|
162
|
+
klass.respond_to?(:openapi_one_of) ? klass.build(value) : klass.build_from_hash(value)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Returns the string representation of the object
|
|
167
|
+
# @return [String] String presentation of the object
|
|
168
|
+
def to_s
|
|
169
|
+
to_hash.to_s
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# to_body is an alias to to_hash (backward compatibility)
|
|
173
|
+
# @return [Hash] Returns the object in the form of hash
|
|
174
|
+
def to_body
|
|
175
|
+
to_hash
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# Returns the object in the form of hash
|
|
179
|
+
# @return [Hash] Returns the object in the form of hash
|
|
180
|
+
def to_hash
|
|
181
|
+
hash = {}
|
|
182
|
+
self.class.attribute_map.each_pair do |attr, param|
|
|
183
|
+
value = self.send(attr)
|
|
184
|
+
if value.nil?
|
|
185
|
+
is_nullable = self.class.openapi_nullable.include?(attr)
|
|
186
|
+
next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
hash[param] = _to_hash(value)
|
|
190
|
+
end
|
|
191
|
+
hash
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Outputs non-array value in the form of hash
|
|
195
|
+
# For object, use to_hash. Otherwise, just return the value
|
|
196
|
+
# @param [Object] value Any valid value
|
|
197
|
+
# @return [Hash] Returns the value in the form of hash
|
|
198
|
+
def _to_hash(value)
|
|
199
|
+
if value.is_a?(Array)
|
|
200
|
+
value.compact.map { |v| _to_hash(v) }
|
|
201
|
+
elsif value.is_a?(Hash)
|
|
202
|
+
{}.tap do |hash|
|
|
203
|
+
value.each { |k, v| hash[k] = _to_hash(v) }
|
|
204
|
+
end
|
|
205
|
+
elsif value.respond_to? :to_hash
|
|
206
|
+
value.to_hash
|
|
207
|
+
else
|
|
208
|
+
value
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#SnapTrade
|
|
3
|
+
|
|
4
|
+
#Connect brokerage accounts to your app for live positions and trading
|
|
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
|
+
# Dollar amount to trade. Cannot work with units. Can only work for market order types and day for time in force. **Only available for Alpaca, Alpaca Paper, and Robinhood.**
|
|
15
|
+
module NotionalValue
|
|
16
|
+
class << self
|
|
17
|
+
# List of class defined in oneOf (OpenAPI v3)
|
|
18
|
+
def openapi_one_of
|
|
19
|
+
[
|
|
20
|
+
:'Float',
|
|
21
|
+
:'String'
|
|
22
|
+
]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Builds the object
|
|
26
|
+
# @param [Mixed] Data to be matched against the list of oneOf items
|
|
27
|
+
# @return [Object] Returns the model or the data itself
|
|
28
|
+
def build(data)
|
|
29
|
+
# Go through the list of oneOf items and attempt to identify the appropriate one.
|
|
30
|
+
# Note:
|
|
31
|
+
# - We do not attempt to check whether exactly one item matches.
|
|
32
|
+
# - No advanced validation of types in some cases (e.g. "x: { type: string }" will happily match { x: 123 })
|
|
33
|
+
# due to the way the deserialization is made in the base_object template (it just casts without verifying).
|
|
34
|
+
# - TODO: scalar values are de facto behaving as if they were nullable.
|
|
35
|
+
# - TODO: logging when debugging is set.
|
|
36
|
+
openapi_one_of.each do |klass|
|
|
37
|
+
begin
|
|
38
|
+
next if klass == :AnyType # "nullable: true"
|
|
39
|
+
typed_data = find_and_cast_into_type(klass, data)
|
|
40
|
+
return typed_data if typed_data
|
|
41
|
+
rescue # rescue all errors so we keep iterating even if the current item lookup raises
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
openapi_one_of.include?(:AnyType) ? data : nil
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
SchemaMismatchError = Class.new(StandardError)
|
|
51
|
+
|
|
52
|
+
# Note: 'File' is missing here because in the regular case we get the data _after_ a call to JSON.parse.
|
|
53
|
+
def find_and_cast_into_type(klass, data)
|
|
54
|
+
return if data.nil?
|
|
55
|
+
|
|
56
|
+
case klass.to_s
|
|
57
|
+
when 'Boolean'
|
|
58
|
+
return data if data.instance_of?(TrueClass) || data.instance_of?(FalseClass)
|
|
59
|
+
when 'Float'
|
|
60
|
+
return data if data.instance_of?(Float)
|
|
61
|
+
when 'Integer'
|
|
62
|
+
return data if data.instance_of?(Integer)
|
|
63
|
+
when 'Time'
|
|
64
|
+
return Time.parse(data)
|
|
65
|
+
when 'Date'
|
|
66
|
+
return Date.parse(data)
|
|
67
|
+
when 'String'
|
|
68
|
+
return data if data.instance_of?(String)
|
|
69
|
+
when 'Object' # "type: object"
|
|
70
|
+
return data if data.instance_of?(Hash)
|
|
71
|
+
when /\AArray<(?<sub_type>.+)>\z/ # "type: array"
|
|
72
|
+
if data.instance_of?(Array)
|
|
73
|
+
sub_type = Regexp.last_match[:sub_type]
|
|
74
|
+
return data.map { |item| find_and_cast_into_type(sub_type, item) }
|
|
75
|
+
end
|
|
76
|
+
when /\AHash<String, (?<sub_type>.+)>\z/ # "type: object" with "additionalProperties: { ... }"
|
|
77
|
+
if data.instance_of?(Hash) && data.keys.all? { |k| k.instance_of?(Symbol) || k.instance_of?(String) }
|
|
78
|
+
sub_type = Regexp.last_match[:sub_type]
|
|
79
|
+
return data.each_with_object({}) { |(k, v), hsh| hsh[k] = find_and_cast_into_type(sub_type, v) }
|
|
80
|
+
end
|
|
81
|
+
else # model
|
|
82
|
+
const = SnapTrade.const_get(klass)
|
|
83
|
+
if const
|
|
84
|
+
if const.respond_to?(:openapi_one_of) # nested oneOf model
|
|
85
|
+
model = const.build(data)
|
|
86
|
+
return model if model
|
|
87
|
+
else
|
|
88
|
+
# raise if data contains keys that are not known to the model
|
|
89
|
+
raise unless (data.keys - const.acceptable_attributes).empty?
|
|
90
|
+
model = const.build_from_hash(data)
|
|
91
|
+
return model if model && model.valid?
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
raise # if no match by now, raise
|
|
97
|
+
rescue
|
|
98
|
+
raise SchemaMismatchError, "#{data} doesn't match the #{klass} type"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
@@ -12,16 +12,24 @@ require 'time'
|
|
|
12
12
|
|
|
13
13
|
module SnapTrade
|
|
14
14
|
class SessionEventType
|
|
15
|
-
|
|
15
|
+
OAUTH_REDIRECT = "OAUTH_REDIRECT".freeze
|
|
16
16
|
DISCLAIMER_ACCEPTED = "DISCLAIMER_ACCEPTED".freeze
|
|
17
17
|
BROKERAGE_CONNECTION_INITIATED = "BROKERAGE_CONNECTION_INITIATED".freeze
|
|
18
|
+
BROKERAGE_RECONNECT_INITIATED = "BROKERAGE_RECONNECT_INITIATED".freeze
|
|
18
19
|
BROKERAGE_AUTHENTICATION = "BROKERAGE_AUTHENTICATION".freeze
|
|
19
|
-
|
|
20
|
+
OAUTH_BROKERAGE_AUTHENTICATION = "OAUTH_BROKERAGE_AUTHENTICATION".freeze
|
|
21
|
+
MFA_REQUESTED = "MFA_REQUESTED".freeze
|
|
22
|
+
MFA_SUBMITTED = "MFA_SUBMITTED".freeze
|
|
23
|
+
MFA_CHOICE_REQUESTED = "MFA_CHOICE_REQUESTED".freeze
|
|
24
|
+
MFA_CHOICE_SUBMITTED = "MFA_CHOICE_SUBMITTED".freeze
|
|
20
25
|
CONNECTION_SUCCESSFUL = "CONNECTION_SUCCESSFUL".freeze
|
|
26
|
+
CONNECTION_FAILED = "CONNECTION_FAILED".freeze
|
|
21
27
|
PARTNER_REDIRECT = "PARTNER_REDIRECT".freeze
|
|
28
|
+
CONNECTION_ABORTED = "CONNECTION_ABORTED".freeze
|
|
29
|
+
SESSION_STARTED = "SESSION_STARTED".freeze
|
|
22
30
|
|
|
23
31
|
def self.all_vars
|
|
24
|
-
@all_vars ||= [
|
|
32
|
+
@all_vars ||= [OAUTH_REDIRECT, DISCLAIMER_ACCEPTED, BROKERAGE_CONNECTION_INITIATED, BROKERAGE_RECONNECT_INITIATED, BROKERAGE_AUTHENTICATION, OAUTH_BROKERAGE_AUTHENTICATION, MFA_REQUESTED, MFA_SUBMITTED, MFA_CHOICE_REQUESTED, MFA_CHOICE_SUBMITTED, CONNECTION_SUCCESSFUL, CONNECTION_FAILED, PARTNER_REDIRECT, CONNECTION_ABORTED, SESSION_STARTED].freeze
|
|
25
33
|
end
|
|
26
34
|
|
|
27
35
|
# Builds the enum from string
|
data/lib/snaptrade/version.rb
CHANGED
data/lib/snaptrade.rb
CHANGED
|
@@ -25,7 +25,7 @@ require 'snaptrade/models/account_order_record'
|
|
|
25
25
|
require 'snaptrade/models/account_order_record_status'
|
|
26
26
|
require 'snaptrade/models/account_simple'
|
|
27
27
|
require 'snaptrade/models/account_sync_status'
|
|
28
|
-
require 'snaptrade/models/
|
|
28
|
+
require 'snaptrade/models/action_strict'
|
|
29
29
|
require 'snaptrade/models/amount'
|
|
30
30
|
require 'snaptrade/models/auth_type'
|
|
31
31
|
require 'snaptrade/models/authentication_login_snap_trade_user200_response'
|
|
@@ -61,6 +61,7 @@ require 'snaptrade/models/manual_trade'
|
|
|
61
61
|
require 'snaptrade/models/manual_trade_and_impact'
|
|
62
62
|
require 'snaptrade/models/manual_trade_balance'
|
|
63
63
|
require 'snaptrade/models/manual_trade_form'
|
|
64
|
+
require 'snaptrade/models/manual_trade_form_notional_value'
|
|
64
65
|
require 'snaptrade/models/manual_trade_symbol'
|
|
65
66
|
require 'snaptrade/models/model400_failed_request_response'
|
|
66
67
|
require 'snaptrade/models/model401_failed_request_response'
|
|
@@ -78,6 +79,7 @@ require 'snaptrade/models/model_type'
|
|
|
78
79
|
require 'snaptrade/models/monthly_dividends'
|
|
79
80
|
require 'snaptrade/models/net_contributions'
|
|
80
81
|
require 'snaptrade/models/net_dividend'
|
|
82
|
+
require 'snaptrade/models/notional_value'
|
|
81
83
|
require 'snaptrade/models/option_chain_inner'
|
|
82
84
|
require 'snaptrade/models/option_chain_inner_chain_per_root_inner'
|
|
83
85
|
require 'snaptrade/models/option_chain_inner_chain_per_root_inner_chain_per_strike_price_inner'
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#SnapTrade
|
|
3
|
+
|
|
4
|
+
#Connect brokerage accounts to your app for live positions and trading
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
Contact: api@snaptrade.com
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
require 'spec_helper'
|
|
11
|
+
require 'json'
|
|
12
|
+
require 'date'
|
|
13
|
+
|
|
14
|
+
# Unit tests for SnapTrade::ActionStrict
|
|
15
|
+
describe SnapTrade::ActionStrict do
|
|
16
|
+
let(:instance) { SnapTrade::ActionStrict.new }
|
|
17
|
+
|
|
18
|
+
describe 'test an instance of ActionStrict' do
|
|
19
|
+
it 'should create an instance of ActionStrict' do
|
|
20
|
+
expect(instance).to be_instance_of(SnapTrade::ActionStrict)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#SnapTrade
|
|
3
|
+
|
|
4
|
+
#Connect brokerage accounts to your app for live positions and trading
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
Contact: api@snaptrade.com
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
require 'spec_helper'
|
|
11
|
+
require 'json'
|
|
12
|
+
require 'date'
|
|
13
|
+
|
|
14
|
+
# Unit tests for SnapTrade::ManualTradeFormNotionalValue
|
|
15
|
+
describe SnapTrade::ManualTradeFormNotionalValue do
|
|
16
|
+
let(:instance) { SnapTrade::ManualTradeFormNotionalValue.new }
|
|
17
|
+
|
|
18
|
+
describe 'test an instance of ManualTradeFormNotionalValue' do
|
|
19
|
+
it 'should create an instance of ManualTradeFormNotionalValue' do
|
|
20
|
+
expect(instance).to be_instance_of(SnapTrade::ManualTradeFormNotionalValue)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
#SnapTrade
|
|
3
|
+
|
|
4
|
+
#Connect brokerage accounts to your app for live positions and trading
|
|
5
|
+
|
|
6
|
+
The version of the OpenAPI document: 1.0.0
|
|
7
|
+
Contact: api@snaptrade.com
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
require 'spec_helper'
|
|
11
|
+
require 'json'
|
|
12
|
+
require 'date'
|
|
13
|
+
|
|
14
|
+
# Unit tests for SnapTrade::NotionalValue
|
|
15
|
+
describe SnapTrade::NotionalValue do
|
|
16
|
+
describe '.openapi_one_of' do
|
|
17
|
+
it 'lists the items referenced in the oneOf array' do
|
|
18
|
+
expect(described_class.openapi_one_of).to_not be_empty
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe '.build' do
|
|
23
|
+
it 'returns the correct model' do
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: snaptrade
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.20
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- SnapTrade
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2024-05-
|
|
11
|
+
date: 2024-05-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: faraday
|
|
@@ -104,7 +104,7 @@ files:
|
|
|
104
104
|
- lib/snaptrade/models/account_order_record_status.rb
|
|
105
105
|
- lib/snaptrade/models/account_simple.rb
|
|
106
106
|
- lib/snaptrade/models/account_sync_status.rb
|
|
107
|
-
- lib/snaptrade/models/
|
|
107
|
+
- lib/snaptrade/models/action_strict.rb
|
|
108
108
|
- lib/snaptrade/models/amount.rb
|
|
109
109
|
- lib/snaptrade/models/auth_type.rb
|
|
110
110
|
- lib/snaptrade/models/authentication_login_snap_trade_user200_response.rb
|
|
@@ -140,6 +140,7 @@ files:
|
|
|
140
140
|
- lib/snaptrade/models/manual_trade_and_impact.rb
|
|
141
141
|
- lib/snaptrade/models/manual_trade_balance.rb
|
|
142
142
|
- lib/snaptrade/models/manual_trade_form.rb
|
|
143
|
+
- lib/snaptrade/models/manual_trade_form_notional_value.rb
|
|
143
144
|
- lib/snaptrade/models/manual_trade_symbol.rb
|
|
144
145
|
- lib/snaptrade/models/model400_failed_request_response.rb
|
|
145
146
|
- lib/snaptrade/models/model401_failed_request_response.rb
|
|
@@ -157,6 +158,7 @@ files:
|
|
|
157
158
|
- lib/snaptrade/models/monthly_dividends.rb
|
|
158
159
|
- lib/snaptrade/models/net_contributions.rb
|
|
159
160
|
- lib/snaptrade/models/net_dividend.rb
|
|
161
|
+
- lib/snaptrade/models/notional_value.rb
|
|
160
162
|
- lib/snaptrade/models/option_chain_inner.rb
|
|
161
163
|
- lib/snaptrade/models/option_chain_inner_chain_per_root_inner.rb
|
|
162
164
|
- lib/snaptrade/models/option_chain_inner_chain_per_root_inner_chain_per_strike_price_inner.rb
|
|
@@ -248,7 +250,7 @@ files:
|
|
|
248
250
|
- spec/models/account_simple_spec.rb
|
|
249
251
|
- spec/models/account_spec.rb
|
|
250
252
|
- spec/models/account_sync_status_spec.rb
|
|
251
|
-
- spec/models/
|
|
253
|
+
- spec/models/action_strict_spec.rb
|
|
252
254
|
- spec/models/amount_spec.rb
|
|
253
255
|
- spec/models/auth_type_spec.rb
|
|
254
256
|
- spec/models/authentication_login_snap_trade_user200_response_spec.rb
|
|
@@ -282,6 +284,7 @@ files:
|
|
|
282
284
|
- spec/models/login_redirect_uri_spec.rb
|
|
283
285
|
- spec/models/manual_trade_and_impact_spec.rb
|
|
284
286
|
- spec/models/manual_trade_balance_spec.rb
|
|
287
|
+
- spec/models/manual_trade_form_notional_value_spec.rb
|
|
285
288
|
- spec/models/manual_trade_form_spec.rb
|
|
286
289
|
- spec/models/manual_trade_spec.rb
|
|
287
290
|
- spec/models/manual_trade_symbol_spec.rb
|
|
@@ -301,6 +304,7 @@ files:
|
|
|
301
304
|
- spec/models/monthly_dividends_spec.rb
|
|
302
305
|
- spec/models/net_contributions_spec.rb
|
|
303
306
|
- spec/models/net_dividend_spec.rb
|
|
307
|
+
- spec/models/notional_value_spec.rb
|
|
304
308
|
- spec/models/option_chain_inner_chain_per_root_inner_chain_per_strike_price_inner_spec.rb
|
|
305
309
|
- spec/models/option_chain_inner_chain_per_root_inner_spec.rb
|
|
306
310
|
- spec/models/option_chain_inner_spec.rb
|
|
@@ -424,6 +428,7 @@ test_files:
|
|
|
424
428
|
- spec/models/model400_failed_request_response_spec.rb
|
|
425
429
|
- spec/models/strategy_quotes_greek_spec.rb
|
|
426
430
|
- spec/models/account_spec.rb
|
|
431
|
+
- spec/models/action_strict_spec.rb
|
|
427
432
|
- spec/models/net_contributions_spec.rb
|
|
428
433
|
- spec/models/delete_user_response_spec.rb
|
|
429
434
|
- spec/models/net_dividend_spec.rb
|
|
@@ -443,6 +448,7 @@ test_files:
|
|
|
443
448
|
- spec/models/brokerage_authorization_type_read_only_type_spec.rb
|
|
444
449
|
- spec/models/manual_trade_symbol_spec.rb
|
|
445
450
|
- spec/models/position_spec.rb
|
|
451
|
+
- spec/models/notional_value_spec.rb
|
|
446
452
|
- spec/models/trade_action_spec.rb
|
|
447
453
|
- spec/models/authentication_login_snap_trade_user200_response_spec.rb
|
|
448
454
|
- spec/models/model_portfolio_details_spec.rb
|
|
@@ -501,11 +507,11 @@ test_files:
|
|
|
501
507
|
- spec/models/options_symbol_spec.rb
|
|
502
508
|
- spec/models/options_place_option_strategy_request_spec.rb
|
|
503
509
|
- spec/models/account_balance_spec.rb
|
|
504
|
-
- spec/models/action_spec.rb
|
|
505
510
|
- spec/models/options_get_option_strategy_request_spec.rb
|
|
506
511
|
- spec/models/currency_spec.rb
|
|
507
512
|
- spec/models/option_type_spec.rb
|
|
508
513
|
- spec/models/security_type_spec.rb
|
|
514
|
+
- spec/models/manual_trade_form_notional_value_spec.rb
|
|
509
515
|
- spec/models/login_redirect_uri_spec.rb
|
|
510
516
|
- spec/models/calculated_trade_spec.rb
|
|
511
517
|
- spec/models/target_asset_spec.rb
|
data/spec/models/action_spec.rb
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
=begin
|
|
2
|
-
#SnapTrade
|
|
3
|
-
|
|
4
|
-
#Connect brokerage accounts to your app for live positions and trading
|
|
5
|
-
|
|
6
|
-
The version of the OpenAPI document: 1.0.0
|
|
7
|
-
Contact: api@snaptrade.com
|
|
8
|
-
=end
|
|
9
|
-
|
|
10
|
-
require 'spec_helper'
|
|
11
|
-
require 'json'
|
|
12
|
-
require 'date'
|
|
13
|
-
|
|
14
|
-
# Unit tests for SnapTrade::Action
|
|
15
|
-
describe SnapTrade::Action do
|
|
16
|
-
let(:instance) { SnapTrade::Action.new }
|
|
17
|
-
|
|
18
|
-
describe 'test an instance of Action' do
|
|
19
|
-
it 'should create an instance of Action' do
|
|
20
|
-
expect(instance).to be_instance_of(SnapTrade::Action)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|