schwab_rb 0.3.12 → 0.4.0
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/CHANGELOG.md +22 -0
- data/doc/ACCOUNT_MANAGEMENT.md +297 -0
- data/doc/PLACE_ORDER_SAMPLES.md +301 -0
- data/doc/QUICK_START.md +239 -0
- data/examples/place_oco_order.rb +75 -0
- data/lib/schwab_rb/account_hash_manager.rb +119 -0
- data/lib/schwab_rb/clients/base_client.rb +231 -115
- data/lib/schwab_rb/configuration.rb +7 -1
- data/lib/schwab_rb/orders/iron_condor_order.rb +14 -26
- data/lib/schwab_rb/orders/oco_order.rb +69 -0
- data/lib/schwab_rb/orders/order.rb +45 -2
- data/lib/schwab_rb/orders/order_factory.rb +21 -10
- data/lib/schwab_rb/orders/single_order.rb +16 -7
- data/lib/schwab_rb/orders/vertical_order.rb +23 -26
- data/lib/schwab_rb/version.rb +1 -1
- data/lib/schwab_rb.rb +2 -0
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9855a77823d8f9039e402281cec2efba85bd1bdba9b7ff7404a8ad136a276631
|
4
|
+
data.tar.gz: fd0c1e0cc43e9c52c82e8f45fee14c919ea307b40c82195d8272ce921ca5defd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1cd4e54dc2eace5a02ce328762f3ffaa4f23356684716d8d4987268c63d463b4cacbd51c8f278ec42cee8a73005bacd11a150db8e78beba3e34ae84c35e9e86e
|
7
|
+
data.tar.gz: 0b3f8920a5fd5c6256e5a3d69da6a65d54a781e8773b0a1a8981f88418444d2ee1243060f73b5c57dc4f63f61eea14aa420fcae57a70c98d5a0c0ed02929c7dd
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,27 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.4.0] - 2025-10-19
|
4
|
+
|
5
|
+
### Added
|
6
|
+
- Account Management System: New `AccountHashManager` class for managing accounts via friendly names instead of encrypted account hashes
|
7
|
+
- One-Cancels-Other (OCO) Orders: Support for OCO order types with comprehensive examples
|
8
|
+
- Stop Limit Orders: Added support for stop limit order types
|
9
|
+
- Order type and duration as configurable parameters across all order types
|
10
|
+
- Quick Start Guide (doc/QUICK_START.md) for new users
|
11
|
+
- Account Management documentation (doc/ACCOUNT_MANAGEMENT.md) with detailed usage examples
|
12
|
+
- Place Order Samples documentation (doc/PLACE_ORDER_SAMPLES.md) with examples for all order types
|
13
|
+
- Example script for placing OCO orders (examples/place_oco_order.rb)
|
14
|
+
- Configuration options for account management paths
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
- Enhanced `BaseClient` with account name resolution - client methods can now accept account names or hashes
|
18
|
+
- Refactored order classes (IronCondorOrder, VerticalOrder, SingleOrder) to support order_type and duration parameters
|
19
|
+
- Improved `OrderFactory` to handle OCO and stop limit orders
|
20
|
+
- Updated bin/console with account hash manager initialization
|
21
|
+
|
22
|
+
### Fixed
|
23
|
+
- Fixed parameter order in client method calls
|
24
|
+
|
3
25
|
## [0.2.0] - 2025-07-20
|
4
26
|
|
5
27
|
### Added
|
@@ -0,0 +1,297 @@
|
|
1
|
+
# Account Management Guide
|
2
|
+
|
3
|
+
The schwab_rb gem provides a secure and convenient way to manage multiple Schwab accounts using friendly account names instead of exposing account numbers or hashes in your code.
|
4
|
+
|
5
|
+
## Table of Contents
|
6
|
+
|
7
|
+
- [Overview](#overview)
|
8
|
+
- [Quick Start](#quick-start)
|
9
|
+
- [Configuration](#configuration)
|
10
|
+
- [Account Names Setup](#account-names-setup)
|
11
|
+
- [Using Account Names](#using-account-names)
|
12
|
+
- [Security Best Practices](#security-best-practices)
|
13
|
+
- [Troubleshooting](#troubleshooting)
|
14
|
+
- [API Reference](#api-reference)
|
15
|
+
|
16
|
+
## Overview
|
17
|
+
|
18
|
+
Schwab's API requires account hashes for most operations, which:
|
19
|
+
- Change periodically (accounts get "rehashed")
|
20
|
+
- Are inconvenient to look up and copy
|
21
|
+
- Expose sensitive account numbers in code
|
22
|
+
|
23
|
+
schwab_rb provides an account name mapping system that:
|
24
|
+
- **Increases Security**: Account numbers never appear in your code
|
25
|
+
- **Improves Usability**: Reference accounts by friendly names like "my_trading_account"
|
26
|
+
- **Auto-Updates**: Account hashes refresh automatically
|
27
|
+
- **Handles Staleness**: Retries failed requests with fresh hashes
|
28
|
+
|
29
|
+
## Quick Start
|
30
|
+
|
31
|
+
### 1. Create Account Names File
|
32
|
+
|
33
|
+
Create `~/.schwab_rb/account_names.json` with your account mappings:
|
34
|
+
|
35
|
+
```json
|
36
|
+
{
|
37
|
+
"my_trading_account": "12345678",
|
38
|
+
"my_ira": "87654321",
|
39
|
+
"my_roth_ira": "11223344"
|
40
|
+
}
|
41
|
+
```
|
42
|
+
|
43
|
+
### 2. Initialize Client and Fetch Hashes
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
require "schwab_rb"
|
47
|
+
|
48
|
+
# Initialize client
|
49
|
+
client = SchwabRb::Auth.init_client_easy(
|
50
|
+
ENV['SCHWAB_API_KEY'],
|
51
|
+
ENV['SCHWAB_APP_SECRET'],
|
52
|
+
ENV['SCHWAB_APP_CALLBACK_URL'],
|
53
|
+
ENV['SCHWAB_TOKEN_PATH']
|
54
|
+
)
|
55
|
+
|
56
|
+
# Fetch account numbers and populate hashes
|
57
|
+
client.get_account_numbers
|
58
|
+
```
|
59
|
+
|
60
|
+
This automatically creates `~/.schwab_rb/account_hashes.json` with the name-to-hash mappings.
|
61
|
+
|
62
|
+
### 3. Use Account Names in API Calls
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
# Get account by name
|
66
|
+
account = client.get_account(account_name: "my_trading_account")
|
67
|
+
|
68
|
+
# Place order using account name
|
69
|
+
order = client.place_order(order_spec, account_name: "my_ira")
|
70
|
+
|
71
|
+
# Get transactions
|
72
|
+
transactions = client.get_transactions(account_name: "my_roth_ira")
|
73
|
+
```
|
74
|
+
|
75
|
+
## Configuration
|
76
|
+
|
77
|
+
### Default Paths
|
78
|
+
|
79
|
+
By default, schwab_rb uses:
|
80
|
+
- `schwab_home`: `~/.schwab_rb`
|
81
|
+
- `account_hashes_path`: `~/.schwab_rb/account_hashes.json`
|
82
|
+
- `account_names_path`: `~/.schwab_rb/account_names.json`
|
83
|
+
|
84
|
+
### Custom Paths
|
85
|
+
|
86
|
+
#### Via Environment Variables
|
87
|
+
|
88
|
+
```bash
|
89
|
+
export SCHWAB_HOME="/custom/path"
|
90
|
+
export SCHWAB_ACCOUNT_HASHES_PATH="/custom/path/hashes.json"
|
91
|
+
export SCHWAB_ACCOUNT_NAMES_PATH="/custom/path/names.json"
|
92
|
+
```
|
93
|
+
|
94
|
+
#### Via Ruby Configuration
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
SchwabRb.configure do |config|
|
98
|
+
config.schwab_home = "/custom/path"
|
99
|
+
config.account_hashes_path = "/custom/path/hashes.json"
|
100
|
+
config.account_names_path = "/custom/path/names.json"
|
101
|
+
end
|
102
|
+
```
|
103
|
+
|
104
|
+
## Account Names Setup
|
105
|
+
|
106
|
+
### File Format
|
107
|
+
|
108
|
+
`account_names.json` is a simple JSON object mapping friendly names to 8-digit account numbers:
|
109
|
+
|
110
|
+
```json
|
111
|
+
{
|
112
|
+
"descriptive_name": "account_number"
|
113
|
+
}
|
114
|
+
```
|
115
|
+
|
116
|
+
## Using Account Names
|
117
|
+
|
118
|
+
### Methods Supporting Account Names
|
119
|
+
|
120
|
+
All account-specific methods support both `account_hash` and `account_name`:
|
121
|
+
|
122
|
+
- `get_account(account_name:)` or `get_account(account_hash)`
|
123
|
+
- `get_order(order_id, account_name:)`
|
124
|
+
- `cancel_order(order_id, account_name:)`
|
125
|
+
- `get_account_orders(account_name:)`
|
126
|
+
- `place_order(order_spec, account_name:)`
|
127
|
+
- `replace_order(order_id, order_spec, account_name:)`
|
128
|
+
- `preview_order(order_spec, account_name:)`
|
129
|
+
- `get_transactions(account_name:)`
|
130
|
+
- `get_transaction(activity_id, account_name:)`
|
131
|
+
|
132
|
+
### Calling Patterns
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
# Using account name (keyword argument) - RECOMMENDED
|
136
|
+
client.get_account(account_name: "my_trading_account")
|
137
|
+
|
138
|
+
# Using account hash (positional argument) - still works
|
139
|
+
client.get_account("ABC123HASH")
|
140
|
+
|
141
|
+
# Using account hash (keyword argument)
|
142
|
+
client.get_account(account_hash: "ABC123HASH")
|
143
|
+
|
144
|
+
# Priority: account_name always takes precedence
|
145
|
+
client.get_account("HASH1", account_name: "my_ira") # Uses "my_ira"
|
146
|
+
```
|
147
|
+
|
148
|
+
### List Available Accounts
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
# Get list of configured account names
|
152
|
+
names = client.available_account_names
|
153
|
+
# => ["my_trading_account", "my_ira", "my_roth_ira"]
|
154
|
+
|
155
|
+
puts "Available accounts:"
|
156
|
+
names.each { |name| puts " - #{name}" }
|
157
|
+
```
|
158
|
+
|
159
|
+
## Security
|
160
|
+
|
161
|
+
### 1. Protect Your Files
|
162
|
+
|
163
|
+
The account files contain sensitive information:
|
164
|
+
|
165
|
+
```bash
|
166
|
+
# Set restrictive permissions
|
167
|
+
chmod 600 ~/.schwab_rb/account_names.json
|
168
|
+
chmod 600 ~/.schwab_rb/account_hashes.json
|
169
|
+
|
170
|
+
# Verify permissions
|
171
|
+
ls -l ~/.schwab_rb/
|
172
|
+
```
|
173
|
+
|
174
|
+
### 2. Don't Commit to Version Control
|
175
|
+
|
176
|
+
Add to `.gitignore`:
|
177
|
+
|
178
|
+
```
|
179
|
+
.schwab_rb/
|
180
|
+
**/account_names.json
|
181
|
+
**/account_hashes.json
|
182
|
+
```
|
183
|
+
|
184
|
+
### 3. Environment-Specific Configs
|
185
|
+
|
186
|
+
Use different configs per environment:
|
187
|
+
|
188
|
+
```ruby
|
189
|
+
# In development
|
190
|
+
SchwabRb.configure do |config|
|
191
|
+
config.schwab_home = "~/.schwab_rb/development"
|
192
|
+
end
|
193
|
+
|
194
|
+
# In production
|
195
|
+
SchwabRb.configure do |config|
|
196
|
+
config.schwab_home = ENV['SCHWAB_CONFIG_PATH']
|
197
|
+
end
|
198
|
+
```
|
199
|
+
|
200
|
+
## Troubleshooting
|
201
|
+
|
202
|
+
### Account Name Not Found
|
203
|
+
|
204
|
+
**Error**: `Account name 'my_account' not found in account hashes.`
|
205
|
+
|
206
|
+
**Solutions**:
|
207
|
+
1. Run `client.get_account_numbers` to populate hashes
|
208
|
+
2. Check spelling in `account_names.json`
|
209
|
+
3. Verify account number is correct
|
210
|
+
|
211
|
+
### Account Numbers File Missing
|
212
|
+
|
213
|
+
**Error**: `Account names file not found at ~/.schwab_rb/account_names.json`
|
214
|
+
|
215
|
+
**Solutions**:
|
216
|
+
1. Create the file with your account mappings (see [Quick Start](#quick-start))
|
217
|
+
2. Set custom path via config if file is elsewhere
|
218
|
+
|
219
|
+
### Account Not in API Response
|
220
|
+
|
221
|
+
**Warning**: `Account 'old_account' (98765432) not found in API response.`
|
222
|
+
|
223
|
+
This warning means an account in your `account_names.json` wasn't returned by the API.
|
224
|
+
|
225
|
+
**Possible Causes**:
|
226
|
+
- Account was closed
|
227
|
+
- Wrong account number in `account_names.json`
|
228
|
+
- Account not accessible with current API credentials
|
229
|
+
|
230
|
+
**Actions**:
|
231
|
+
1. Verify account status on Schwab website
|
232
|
+
2. Check account number in `account_names.json`
|
233
|
+
3. Remove closed accounts from config
|
234
|
+
|
235
|
+
### Stale Account Hashes
|
236
|
+
|
237
|
+
The gem automatically handles stale hashes:
|
238
|
+
1. Request fails with stale hash
|
239
|
+
2. Calls `get_account_numbers` to refresh
|
240
|
+
3. Retries request with new hash
|
241
|
+
4. If still fails, raises original error
|
242
|
+
|
243
|
+
## API Reference
|
244
|
+
|
245
|
+
### Client Methods
|
246
|
+
|
247
|
+
#### `available_account_names`
|
248
|
+
|
249
|
+
Returns list of configured account names.
|
250
|
+
|
251
|
+
```ruby
|
252
|
+
client.available_account_names
|
253
|
+
# => ["my_trading_account", "my_ira"]
|
254
|
+
```
|
255
|
+
|
256
|
+
**Returns**: `Array<String>` - List of account names from `account_names.json`
|
257
|
+
**Returns**: `[]` - Empty array if file doesn't exist
|
258
|
+
|
259
|
+
#### Account-Specific Methods
|
260
|
+
|
261
|
+
All methods accept either `account_name:` or `account_hash`:
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
# Get account
|
265
|
+
client.get_account(account_name: "my_trading_account")
|
266
|
+
client.get_account("ABC123HASH")
|
267
|
+
|
268
|
+
# Get orders
|
269
|
+
client.get_account_orders(account_name: "my_ira", max_results: 10)
|
270
|
+
|
271
|
+
# Place order
|
272
|
+
client.place_order(order_spec, account_name: "my_trading_account")
|
273
|
+
```
|
274
|
+
|
275
|
+
### AccountHashManager
|
276
|
+
|
277
|
+
Direct access to the account hash manager:
|
278
|
+
|
279
|
+
```ruby
|
280
|
+
manager = SchwabRb::AccountHashManager.new
|
281
|
+
|
282
|
+
# Get available names
|
283
|
+
manager.available_account_names
|
284
|
+
# => ["my_trading_account", "my_ira"]
|
285
|
+
|
286
|
+
# Get hash by name
|
287
|
+
manager.get_hash_by_name("my_trading_account")
|
288
|
+
# => "ABC123HASH"
|
289
|
+
|
290
|
+
# Get all hashes
|
291
|
+
manager.get_all_hashes
|
292
|
+
# => {"my_trading_account" => "ABC123HASH", "my_ira" => "XYZ789HASH"}
|
293
|
+
```
|
294
|
+
|
295
|
+
---
|
296
|
+
|
297
|
+
For more information, see the [main README](../README.md) or visit [github.com/jwplatta/schwab_rb](https://github.com/jwplatta/schwab_rb).
|
@@ -0,0 +1,301 @@
|
|
1
|
+
# Place Order Samples
|
2
|
+
|
3
|
+
Below, you will find examples specific to orders for use in the Schwab Trader API POST and PUT Order endpoints. Order entry will only be available for the assetType 'EQUIT' and 'OPTION as of this time.
|
4
|
+
|
5
|
+
Trader API applications (Individual and Commercial) are limited in the number of PUT/POST/DELETE order requests per minute per account based on the properties of the application specified during registration or follow-up process. Throttle limits for orders can be set from zero (0) to 120 requests per minute per account. Get order requests are unthrottled. Contact TraderAPI@schwab.com for further information.
|
6
|
+
|
7
|
+
Options and their Symbology:
|
8
|
+
Options symbols are broken down as:
|
9
|
+
Underlying Symbol (6 characters including spaces) | Expiration (6 characters) | Call/Put (1 character) | Strike Price (5+3=8 characters)
|
10
|
+
|
11
|
+
```
|
12
|
+
Option Symbol: XYZ 210115C00050000
|
13
|
+
Stock Symbol: XYZ
|
14
|
+
Expiration: 2021/01/15
|
15
|
+
Type: Call
|
16
|
+
Strike Price: $50.00
|
17
|
+
|
18
|
+
Option Symbol: XYZ 210115C00055000
|
19
|
+
Stock Symbol: XYZ
|
20
|
+
Expiration: 2021/01/15
|
21
|
+
Type: Call
|
22
|
+
Strike Price: $55.00
|
23
|
+
|
24
|
+
Option Symbol: XYZ 210115C00062500
|
25
|
+
Stock Symbol: XYZ
|
26
|
+
Expiration: 2021/01/15
|
27
|
+
Type: Call
|
28
|
+
Strike Price: $62.50
|
29
|
+
```
|
30
|
+
|
31
|
+
Instruction for EQUITY and OPTION
|
32
|
+
|
33
|
+
Instruction EQUITY (Stocks and ETFs) Option
|
34
|
+
BUY ACCEPTED REJECT
|
35
|
+
SELL ACCEPTED REJECT
|
36
|
+
BUY_TO_OPEN REJECT ACCEPTED
|
37
|
+
BUY_TO_COVER ACCEPTED REJECT
|
38
|
+
BUY_TO_CLOSE REJECT ACCEPTED
|
39
|
+
SELL_TO_OPEN REJECT ACCEPTED
|
40
|
+
SELL_SHORT ACCEPTED REJECT
|
41
|
+
SELL_TO_CLOSE REJECT ACCEPTED
|
42
|
+
Buy Market: Stock
|
43
|
+
Buy 15 shares of XYZ at the Market good for the Day.
|
44
|
+
|
45
|
+
```json
|
46
|
+
{
|
47
|
+
"orderType": "MARKET",
|
48
|
+
"session": "NORMAL",
|
49
|
+
"duration": "DAY",
|
50
|
+
"orderStrategyType": "SINGLE",
|
51
|
+
"orderLegCollection": [
|
52
|
+
{
|
53
|
+
"instruction": "BUY",
|
54
|
+
"quantity": 15,
|
55
|
+
"instrument": {
|
56
|
+
"symbol": "XYZ",
|
57
|
+
"assetType": "EQUITY"
|
58
|
+
}
|
59
|
+
}
|
60
|
+
]
|
61
|
+
}
|
62
|
+
```
|
63
|
+
|
64
|
+
## Buy Limit: Single Option
|
65
|
+
|
66
|
+
Buy to open 10 contracts of the XYZ March 15, 2024 $50 CALL at a Limit of $6.45 good for the Day.
|
67
|
+
|
68
|
+
```json
|
69
|
+
{
|
70
|
+
"complexOrderStrategyType": "NONE",
|
71
|
+
"orderType": "LIMIT",
|
72
|
+
"session": "NORMAL",
|
73
|
+
"price": "6.45",
|
74
|
+
"duration": "DAY",
|
75
|
+
"orderStrategyType": "SINGLE",
|
76
|
+
"orderLegCollection": [
|
77
|
+
{
|
78
|
+
"instruction": "BUY_TO_OPEN",
|
79
|
+
"quantity": 10,
|
80
|
+
"instrument": {
|
81
|
+
"symbol": "XYZ 240315C00500000",
|
82
|
+
"assetType": "OPTION"
|
83
|
+
}
|
84
|
+
}
|
85
|
+
]
|
86
|
+
}
|
87
|
+
```
|
88
|
+
|
89
|
+
## Buy Limit: Vertical Call Spread
|
90
|
+
Buy to open 2 contracts of the XYZ March 15, 2024 $45 Put and Sell to open 2 contract of the XYZ March 15, 2024 $43 Put at a LIMIT price of $0.10 good for the Day.
|
91
|
+
|
92
|
+
```json
|
93
|
+
{
|
94
|
+
"orderType": "NET_DEBIT",
|
95
|
+
"session": "NORMAL",
|
96
|
+
"price": "0.10",
|
97
|
+
"duration": "DAY",
|
98
|
+
"orderStrategyType": "SINGLE",
|
99
|
+
"orderLegCollection": [
|
100
|
+
{
|
101
|
+
"instruction": "BUY_TO_OPEN",
|
102
|
+
"quantity": 2,
|
103
|
+
"instrument": {
|
104
|
+
"symbol": "XYZ 240315P00045000",
|
105
|
+
"assetType": "OPTION"
|
106
|
+
}
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"instruction": "SELL_TO_OPEN",
|
110
|
+
"quantity": 2,
|
111
|
+
"instrument": {
|
112
|
+
"symbol": "XYZ 240315P00043000",
|
113
|
+
"assetType": "OPTION"
|
114
|
+
}
|
115
|
+
}
|
116
|
+
]
|
117
|
+
}
|
118
|
+
```
|
119
|
+
|
120
|
+
## Conditional Order: One Triggers Another
|
121
|
+
Buy 10 shares of XYZ at a Limit price of $34.97 good for the Day. If filled, immediately submit an order to Sell 10 shares of XYZ with a Limit price of $42.03 good for the Day. Also known as 1st Trigger Sequence.
|
122
|
+
|
123
|
+
```json
|
124
|
+
{
|
125
|
+
"orderType": "LIMIT",
|
126
|
+
"session": "NORMAL",
|
127
|
+
"price": "34.97",
|
128
|
+
"duration": "DAY",
|
129
|
+
"orderStrategyType": "TRIGGER",
|
130
|
+
"orderLegCollection": [
|
131
|
+
{
|
132
|
+
"instruction": "BUY",
|
133
|
+
"quantity": 10,
|
134
|
+
"instrument": {
|
135
|
+
"symbol": "XYZ",
|
136
|
+
"assetType": "EQUITY"
|
137
|
+
}
|
138
|
+
}
|
139
|
+
],
|
140
|
+
"childOrderStrategies": [
|
141
|
+
{
|
142
|
+
"orderType": "LIMIT",
|
143
|
+
"session": "NORMAL",
|
144
|
+
"price": "42.03",
|
145
|
+
"duration": "DAY",
|
146
|
+
"orderStrategyType": "SINGLE",
|
147
|
+
"orderLegCollection": [
|
148
|
+
{
|
149
|
+
"instruction": "SELL",
|
150
|
+
"quantity": 10,
|
151
|
+
"instrument": {
|
152
|
+
"symbol": "XYZ",
|
153
|
+
"assetType": "EQUITY"
|
154
|
+
}
|
155
|
+
}
|
156
|
+
]
|
157
|
+
}
|
158
|
+
]
|
159
|
+
}
|
160
|
+
```
|
161
|
+
|
162
|
+
|
163
|
+
## Conditional Order: One Cancels Another
|
164
|
+
|
165
|
+
Sell 2 shares of XYZ at a Limit price of $45.97 and Sell 2 shares of XYZ with a Stop Limit order where the stop price is $37.03 and limit is $37.00. Both orders are sent at the same time. If one order fills, the other order is immediately cancelled. Both orders are good for the Day. Also known as an OCO order.
|
166
|
+
|
167
|
+
```json
|
168
|
+
{
|
169
|
+
"orderStrategyType": "OCO",
|
170
|
+
"childOrderStrategies": [
|
171
|
+
{
|
172
|
+
"orderType": "LIMIT",
|
173
|
+
"session": "NORMAL",
|
174
|
+
"price": "45.97",
|
175
|
+
"duration": "DAY",
|
176
|
+
"orderStrategyType": "SINGLE",
|
177
|
+
"orderLegCollection": [
|
178
|
+
{
|
179
|
+
"instruction": "SELL",
|
180
|
+
"quantity": 2,
|
181
|
+
"instrument": {
|
182
|
+
"symbol": "XYZ",
|
183
|
+
"assetType": "EQUITY"
|
184
|
+
}
|
185
|
+
}
|
186
|
+
]
|
187
|
+
},
|
188
|
+
{
|
189
|
+
"orderType": "STOP_LIMIT",
|
190
|
+
"session": "NORMAL",
|
191
|
+
"price": "37.00",
|
192
|
+
"stopPrice": "37.03",
|
193
|
+
"duration": "DAY",
|
194
|
+
"orderStrategyType": "SINGLE",
|
195
|
+
"orderLegCollection": [
|
196
|
+
{
|
197
|
+
"instruction": "SELL",
|
198
|
+
"quantity": 2,
|
199
|
+
"instrument": {
|
200
|
+
"symbol": "XYZ",
|
201
|
+
"assetType": "EQUITY"
|
202
|
+
}
|
203
|
+
}
|
204
|
+
]
|
205
|
+
}
|
206
|
+
]
|
207
|
+
}
|
208
|
+
```
|
209
|
+
|
210
|
+
|
211
|
+
## Conditional Order: One Triggers A One Cancels Another
|
212
|
+
|
213
|
+
Buy 5 shares of XYZ at a Limit price of $14.97 good for the Day. Once filled, 2 sell orders are immediately sent: Sell 5 shares of XYZ at a Limit price of $15.27 and Sell 5 shares of XYZ with a Stop order where the stop price is $11.27. If one of the sell orders fill, the other order is immediately cancelled. Both Sell orders are Good till Cancel. Also known as a 1st Trigger OCO order.
|
214
|
+
|
215
|
+
```json
|
216
|
+
{
|
217
|
+
"orderStrategyType": "TRIGGER",
|
218
|
+
"session": "NORMAL",
|
219
|
+
"duration": "DAY",
|
220
|
+
"orderType": "LIMIT",
|
221
|
+
"price": 14.97,
|
222
|
+
"orderLegCollection": [
|
223
|
+
{
|
224
|
+
"instruction": "BUY",
|
225
|
+
"quantity": 5,
|
226
|
+
"instrument": {
|
227
|
+
"assetType": "EQUITY",
|
228
|
+
"symbol": "XYZ"
|
229
|
+
}
|
230
|
+
}
|
231
|
+
],
|
232
|
+
"childOrderStrategies": [
|
233
|
+
{
|
234
|
+
"orderStrategyType": "OCO",
|
235
|
+
"childOrderStrategies": [
|
236
|
+
{
|
237
|
+
"orderStrategyType": "SINGLE",
|
238
|
+
"session": "NORMAL",
|
239
|
+
"duration": "GOOD_TILL_CANCEL",
|
240
|
+
"orderType": "LIMIT",
|
241
|
+
"price": 15.27,
|
242
|
+
"orderLegCollection": [
|
243
|
+
{
|
244
|
+
"instruction": "SELL",
|
245
|
+
"quantity": 5,
|
246
|
+
"instrument": {
|
247
|
+
"assetType": "EQUITY",
|
248
|
+
"symbol": "XYZ"
|
249
|
+
}
|
250
|
+
}
|
251
|
+
]
|
252
|
+
},
|
253
|
+
{
|
254
|
+
"orderStrategyType": "SINGLE",
|
255
|
+
"session": "NORMAL",
|
256
|
+
"duration": "GOOD_TILL_CANCEL",
|
257
|
+
"orderType": "STOP",
|
258
|
+
"stopPrice": 11.27,
|
259
|
+
"orderLegCollection": [
|
260
|
+
{
|
261
|
+
"instruction": "SELL",
|
262
|
+
"quantity": 5,
|
263
|
+
"instrument": {
|
264
|
+
"assetType": "EQUITY",
|
265
|
+
"symbol": "XYZ"
|
266
|
+
}
|
267
|
+
}
|
268
|
+
]
|
269
|
+
}
|
270
|
+
]
|
271
|
+
}
|
272
|
+
]
|
273
|
+
}
|
274
|
+
```
|
275
|
+
|
276
|
+
## Sell Trailing Stop: Stock
|
277
|
+
|
278
|
+
Sell 10 shares of XYZ with a Trailing Stop where the trail is a -$10 offset from the time the order is submitted. As the stock price goes up, the -$10 trailing offset will follow. If stock XYZ goes from $110 to $130, your trail will automatically be adjusted to $120. If XYZ falls to $120 or below, a Market order is submitted. This order is good for the Day.
|
279
|
+
|
280
|
+
```json
|
281
|
+
{
|
282
|
+
"complexOrderStrategyType": "NONE",
|
283
|
+
"orderType": "TRAILING_STOP",
|
284
|
+
"session": "NORMAL",
|
285
|
+
"stopPriceLinkBasis": "BID",
|
286
|
+
"stopPriceLinkType": "VALUE",
|
287
|
+
"stopPriceOffset": 10,
|
288
|
+
"duration": "DAY",
|
289
|
+
"orderStrategyType": "SINGLE",
|
290
|
+
"orderLegCollection": [
|
291
|
+
{
|
292
|
+
"instruction": "SELL",
|
293
|
+
"quantity": 10,
|
294
|
+
"instrument": {
|
295
|
+
"symbol": "XYZ",
|
296
|
+
"assetType": "EQUITY"
|
297
|
+
}
|
298
|
+
}
|
299
|
+
]
|
300
|
+
}
|
301
|
+
```
|