schwab_rb 0.8.2 → 0.9.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/.rubocop.yml +1 -0
- data/lib/schwab_rb/cli/app.rb +9 -186
- data/lib/schwab_rb/option_sample/downloader.rb +210 -0
- data/lib/schwab_rb/option_sample.rb +6 -0
- data/lib/schwab_rb/version.rb +1 -1
- data/lib/schwab_rb.rb +2 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4886933bb9c99f66735ff9503b0904ac55a605e653550d413713c8d33e412a79
|
|
4
|
+
data.tar.gz: d4f9476eeb6f97b00d890295e1edb6002c0780f4c34eb1b321d2355d55853e6a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7998b7bbbfac20de7e62b3dc2ccc6472be8a19b2956f2a2f93c1fbd441c0ff0e5713004f27cc96b6b27286aead9457a16aca4d92a62411ea1a662a6f67d9f49f
|
|
7
|
+
data.tar.gz: e911c3bf6958b4dc0858669e0f38795466a4abf6d202805f6f12fa19ec6a991b1819b8743c682b89e12908595cb856ca8a15bea4b1011a4d6549f9a4a40feb6b
|
data/.rubocop.yml
CHANGED
data/lib/schwab_rb/cli/app.rb
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "csv"
|
|
4
3
|
require "date"
|
|
5
4
|
require "json"
|
|
6
5
|
require "optparse"
|
|
7
6
|
require "pathname"
|
|
8
|
-
require "fileutils"
|
|
9
|
-
require "time"
|
|
10
7
|
|
|
11
8
|
module SchwabRb
|
|
12
9
|
module CLI
|
|
@@ -18,33 +15,6 @@ module SchwabRb
|
|
|
18
15
|
DEFAULT_HISTORY_DIR = "~/.schwab_rb/data/history"
|
|
19
16
|
DEFAULT_OPTIONS_DIR = "~/.schwab_rb/data/options"
|
|
20
17
|
SUPPORTED_FORMATS = %w[csv json].freeze
|
|
21
|
-
OPTION_SAMPLE_CSV_HEADERS = %w[
|
|
22
|
-
contract_type
|
|
23
|
-
symbol
|
|
24
|
-
description
|
|
25
|
-
strike
|
|
26
|
-
expiration_date
|
|
27
|
-
mark
|
|
28
|
-
bid
|
|
29
|
-
bid_size
|
|
30
|
-
ask
|
|
31
|
-
ask_size
|
|
32
|
-
last
|
|
33
|
-
last_size
|
|
34
|
-
open_interest
|
|
35
|
-
total_volume
|
|
36
|
-
delta
|
|
37
|
-
gamma
|
|
38
|
-
theta
|
|
39
|
-
vega
|
|
40
|
-
rho
|
|
41
|
-
volatility
|
|
42
|
-
theoretical_volatility
|
|
43
|
-
theoretical_option_value
|
|
44
|
-
intrinsic_value
|
|
45
|
-
extrinsic_value
|
|
46
|
-
underlying_price
|
|
47
|
-
].freeze
|
|
48
18
|
PERIOD_TYPES = {
|
|
49
19
|
"day" => SchwabRb::PriceHistory::PeriodTypes::DAY,
|
|
50
20
|
"month" => SchwabRb::PriceHistory::PeriodTypes::MONTH,
|
|
@@ -221,14 +191,13 @@ module SchwabRb
|
|
|
221
191
|
|
|
222
192
|
validate_option_sample_options!(options)
|
|
223
193
|
|
|
224
|
-
output_path = resolve_option_sample_response(options)
|
|
194
|
+
_, output_path = resolve_option_sample_response(options)
|
|
225
195
|
|
|
226
196
|
stdout.puts("Saved #{options[:symbol]} option sample to #{output_path}")
|
|
227
197
|
0
|
|
228
198
|
end
|
|
229
199
|
# rubocop:enable Metrics/AbcSize
|
|
230
200
|
|
|
231
|
-
# rubocop:disable Metrics/AbcSize
|
|
232
201
|
def resolve_price_history_response(options)
|
|
233
202
|
directory = SchwabRb::PathSupport.expand_path(options.fetch(:dir))
|
|
234
203
|
SchwabRb::PriceHistory::Downloader.resolve(
|
|
@@ -245,148 +214,20 @@ module SchwabRb
|
|
|
245
214
|
period: options[:period]
|
|
246
215
|
)
|
|
247
216
|
end
|
|
248
|
-
# rubocop:enable Metrics/AbcSize
|
|
249
217
|
|
|
250
218
|
def resolve_option_sample_response(options)
|
|
251
219
|
directory = SchwabRb::PathSupport.expand_path(options.fetch(:dir))
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
File.write(output_path, serialized_option_sample(response, options))
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def serialized_option_sample(response, options)
|
|
264
|
-
case options.fetch(:format)
|
|
265
|
-
when "json"
|
|
266
|
-
JSON.pretty_generate(response)
|
|
267
|
-
when "csv"
|
|
268
|
-
serialized_option_sample_csv(response, options)
|
|
269
|
-
else
|
|
270
|
-
raise Error, "Unsupported format `#{options[:format]}`."
|
|
271
|
-
end
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def serialized_option_sample_csv(response, options)
|
|
275
|
-
sample_timestamp = options.fetch(:timestamp).utc.iso8601
|
|
276
|
-
|
|
277
|
-
CSV.generate do |csv|
|
|
278
|
-
csv << OPTION_SAMPLE_CSV_HEADERS
|
|
279
|
-
option_sample_rows(response).each do |option|
|
|
280
|
-
csv << option_sample_csv_row(response, option, sample_timestamp)
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
# rubocop:disable Metrics/AbcSize
|
|
286
|
-
def option_sample_csv_row(response, option, _sample_timestamp)
|
|
287
|
-
[
|
|
288
|
-
option[:putCall],
|
|
289
|
-
option[:symbol],
|
|
290
|
-
option[:description],
|
|
291
|
-
option[:strikePrice],
|
|
292
|
-
normalize_option_date(option[:expirationDate]),
|
|
293
|
-
option[:mark],
|
|
294
|
-
option[:bid],
|
|
295
|
-
option[:bidSize],
|
|
296
|
-
option[:ask],
|
|
297
|
-
option[:askSize],
|
|
298
|
-
option[:last],
|
|
299
|
-
option[:lastSize],
|
|
300
|
-
option[:openInterest],
|
|
301
|
-
option[:totalVolume],
|
|
302
|
-
option[:delta],
|
|
303
|
-
option[:gamma],
|
|
304
|
-
option[:theta],
|
|
305
|
-
option[:vega],
|
|
306
|
-
option[:rho],
|
|
307
|
-
option[:volatility],
|
|
308
|
-
option[:theoreticalVolatility],
|
|
309
|
-
option[:theoreticalOptionValue],
|
|
310
|
-
option[:intrinsicValue],
|
|
311
|
-
option[:extrinsicValue],
|
|
312
|
-
response[:underlyingPrice]
|
|
313
|
-
]
|
|
314
|
-
end
|
|
315
|
-
# rubocop:enable Metrics/AbcSize
|
|
316
|
-
|
|
317
|
-
def fetch_option_sample(client, options)
|
|
318
|
-
expiration_date = options.fetch(:expiration_date)
|
|
319
|
-
|
|
320
|
-
response = client.get_option_chain(
|
|
321
|
-
SchwabRb::PriceHistory::Downloader.api_symbol(options.fetch(:symbol)),
|
|
322
|
-
contract_type: SchwabRb::Option::ContractTypes::ALL,
|
|
323
|
-
strike_range: SchwabRb::Option::StrikeRanges::ALL,
|
|
324
|
-
from_date: expiration_date,
|
|
325
|
-
to_date: expiration_date,
|
|
326
|
-
return_data_objects: false
|
|
327
|
-
)
|
|
328
|
-
|
|
329
|
-
filter_option_sample_response(response, options[:root])
|
|
330
|
-
end
|
|
331
|
-
|
|
332
|
-
def option_sample_rows(response)
|
|
333
|
-
rows = [response[:callExpDateMap], response[:putExpDateMap]].compact.flat_map do |date_map|
|
|
334
|
-
option_rows_from_date_map(date_map)
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
rows.sort_by do |option|
|
|
338
|
-
[
|
|
339
|
-
normalize_option_date(option[:expirationDate]).to_s,
|
|
340
|
-
option[:putCall].to_s,
|
|
341
|
-
option[:strikePrice].to_f
|
|
342
|
-
]
|
|
343
|
-
end
|
|
344
|
-
end
|
|
345
|
-
|
|
346
|
-
def option_rows_from_date_map(date_map)
|
|
347
|
-
date_map.values.flat_map do |strikes|
|
|
348
|
-
strikes.values.flatten.map { |option| option.transform_keys(&:to_sym) }
|
|
349
|
-
end
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
def filter_option_sample_response(response, option_root)
|
|
353
|
-
return response if blank?(option_root)
|
|
354
|
-
|
|
355
|
-
normalized_root = option_root.to_s.strip.upcase
|
|
356
|
-
filtered_call_map = filter_option_date_map_by_root(response[:callExpDateMap], normalized_root)
|
|
357
|
-
filtered_put_map = filter_option_date_map_by_root(response[:putExpDateMap], normalized_root)
|
|
358
|
-
|
|
359
|
-
response.merge(
|
|
360
|
-
callExpDateMap: filtered_call_map,
|
|
361
|
-
putExpDateMap: filtered_put_map
|
|
220
|
+
SchwabRb::OptionSample::Downloader.resolve(
|
|
221
|
+
client: build_non_interactive_client,
|
|
222
|
+
symbol: options.fetch(:symbol),
|
|
223
|
+
root: options[:root],
|
|
224
|
+
expiration_date: options.fetch(:expiration_date),
|
|
225
|
+
directory: directory,
|
|
226
|
+
format: options.fetch(:format),
|
|
227
|
+
timestamp: options.fetch(:timestamp)
|
|
362
228
|
)
|
|
363
229
|
end
|
|
364
230
|
|
|
365
|
-
def filter_option_date_map_by_root(date_map, option_root)
|
|
366
|
-
return {} unless date_map
|
|
367
|
-
|
|
368
|
-
date_map.each_with_object({}) do |(expiration_key, strikes), filtered_dates|
|
|
369
|
-
filtered_strikes = strikes.each_with_object({}) do |(strike, contracts), filtered_by_strike|
|
|
370
|
-
matching_contracts = contracts.select { |contract| contract[:optionRoot].to_s.upcase == option_root }
|
|
371
|
-
filtered_by_strike[strike] = matching_contracts if matching_contracts.any?
|
|
372
|
-
end
|
|
373
|
-
|
|
374
|
-
filtered_dates[expiration_key] = filtered_strikes if filtered_strikes.any?
|
|
375
|
-
end
|
|
376
|
-
end
|
|
377
|
-
|
|
378
|
-
def normalize_option_date(value)
|
|
379
|
-
return if value.nil?
|
|
380
|
-
|
|
381
|
-
Date.parse(value.to_s).iso8601
|
|
382
|
-
end
|
|
383
|
-
|
|
384
|
-
def normalize_option_timestamp(value)
|
|
385
|
-
return if value.nil?
|
|
386
|
-
|
|
387
|
-
Time.at(value / 1000.0).utc.iso8601
|
|
388
|
-
end
|
|
389
|
-
|
|
390
231
|
def build_non_interactive_client
|
|
391
232
|
credentials = load_credentials(require_callback_url: false)
|
|
392
233
|
token_path = resolved_token_path
|
|
@@ -494,24 +335,6 @@ module SchwabRb
|
|
|
494
335
|
)
|
|
495
336
|
end
|
|
496
337
|
|
|
497
|
-
def option_sample_output_path(directory, options, response)
|
|
498
|
-
File.join(
|
|
499
|
-
directory,
|
|
500
|
-
[
|
|
501
|
-
SchwabRb::PriceHistory::Downloader.sanitize_symbol(
|
|
502
|
-
options[:root] || option_sample_root(response, options.fetch(:symbol))
|
|
503
|
-
),
|
|
504
|
-
"exp#{options.fetch(:expiration_date).iso8601}",
|
|
505
|
-
options.fetch(:timestamp).strftime("%Y-%m-%d_%H-%M-%S")
|
|
506
|
-
].join("_") + ".#{options.fetch(:format)}"
|
|
507
|
-
)
|
|
508
|
-
end
|
|
509
|
-
|
|
510
|
-
def option_sample_root(response, fallback_symbol)
|
|
511
|
-
first_option = option_sample_rows(response).find { |option| !blank?(option[:optionRoot]) }
|
|
512
|
-
first_option ? first_option[:optionRoot] : fallback_symbol
|
|
513
|
-
end
|
|
514
|
-
|
|
515
338
|
def blank?(value)
|
|
516
339
|
value.nil? || value.to_s.strip.empty?
|
|
517
340
|
end
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "csv"
|
|
4
|
+
require "json"
|
|
5
|
+
require "time"
|
|
6
|
+
require "fileutils"
|
|
7
|
+
|
|
8
|
+
module SchwabRb
|
|
9
|
+
class OptionSample
|
|
10
|
+
# Public file-oriented downloader for one-expiration option chain samples.
|
|
11
|
+
module Downloader
|
|
12
|
+
SUPPORTED_FORMATS = %w[csv json].freeze
|
|
13
|
+
CSV_HEADERS = %w[
|
|
14
|
+
contract_type
|
|
15
|
+
symbol
|
|
16
|
+
description
|
|
17
|
+
strike
|
|
18
|
+
expiration_date
|
|
19
|
+
mark
|
|
20
|
+
bid
|
|
21
|
+
bid_size
|
|
22
|
+
ask
|
|
23
|
+
ask_size
|
|
24
|
+
last
|
|
25
|
+
last_size
|
|
26
|
+
open_interest
|
|
27
|
+
total_volume
|
|
28
|
+
delta
|
|
29
|
+
gamma
|
|
30
|
+
theta
|
|
31
|
+
vega
|
|
32
|
+
rho
|
|
33
|
+
volatility
|
|
34
|
+
theoretical_volatility
|
|
35
|
+
theoretical_option_value
|
|
36
|
+
intrinsic_value
|
|
37
|
+
extrinsic_value
|
|
38
|
+
underlying_price
|
|
39
|
+
].freeze
|
|
40
|
+
|
|
41
|
+
module_function
|
|
42
|
+
|
|
43
|
+
# rubocop:disable Metrics/ParameterLists
|
|
44
|
+
def resolve(client:, symbol:, expiration_date:, directory:, format:, timestamp:, root: nil)
|
|
45
|
+
response = fetch(
|
|
46
|
+
client: client,
|
|
47
|
+
symbol: symbol,
|
|
48
|
+
expiration_date: expiration_date,
|
|
49
|
+
root: root
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
FileUtils.mkdir_p(directory)
|
|
53
|
+
path = output_path(
|
|
54
|
+
directory: directory,
|
|
55
|
+
symbol: symbol,
|
|
56
|
+
expiration_date: expiration_date,
|
|
57
|
+
format: format,
|
|
58
|
+
timestamp: timestamp,
|
|
59
|
+
root: root,
|
|
60
|
+
response: response
|
|
61
|
+
)
|
|
62
|
+
File.write(path, serialize(response: response, format: format, timestamp: timestamp))
|
|
63
|
+
|
|
64
|
+
[response, path]
|
|
65
|
+
end
|
|
66
|
+
# rubocop:enable Metrics/ParameterLists
|
|
67
|
+
|
|
68
|
+
def fetch(client:, symbol:, expiration_date:, root: nil)
|
|
69
|
+
response = client.get_option_chain(
|
|
70
|
+
SchwabRb::PriceHistory::Downloader.api_symbol(symbol),
|
|
71
|
+
contract_type: SchwabRb::Option::ContractTypes::ALL,
|
|
72
|
+
strike_range: SchwabRb::Option::StrikeRanges::ALL,
|
|
73
|
+
from_date: expiration_date,
|
|
74
|
+
to_date: expiration_date,
|
|
75
|
+
return_data_objects: false
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
filter_response_by_root(response, root)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def filter_response_by_root(response, option_root)
|
|
82
|
+
return response if blank?(option_root)
|
|
83
|
+
|
|
84
|
+
normalized_root = option_root.to_s.strip.upcase
|
|
85
|
+
|
|
86
|
+
response.merge(
|
|
87
|
+
callExpDateMap: filter_date_map_by_root(response[:callExpDateMap], normalized_root),
|
|
88
|
+
putExpDateMap: filter_date_map_by_root(response[:putExpDateMap], normalized_root)
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def filter_date_map_by_root(date_map, option_root)
|
|
93
|
+
return {} unless date_map
|
|
94
|
+
|
|
95
|
+
date_map.each_with_object({}) do |(expiration_key, strikes), filtered_dates|
|
|
96
|
+
filtered_strikes = strikes.each_with_object({}) do |(strike, contracts), filtered_by_strike|
|
|
97
|
+
matching_contracts = contracts.select { |contract| contract[:optionRoot].to_s.upcase == option_root }
|
|
98
|
+
filtered_by_strike[strike] = matching_contracts if matching_contracts.any?
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
filtered_dates[expiration_key] = filtered_strikes if filtered_strikes.any?
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# rubocop:disable Metrics/ParameterLists
|
|
106
|
+
def output_path(directory:, symbol:, expiration_date:, format:, timestamp:, root: nil, response: nil)
|
|
107
|
+
selected_root = root || option_root(response, symbol)
|
|
108
|
+
|
|
109
|
+
File.join(
|
|
110
|
+
directory,
|
|
111
|
+
[
|
|
112
|
+
SchwabRb::PriceHistory::Downloader.sanitize_symbol(selected_root),
|
|
113
|
+
"exp#{expiration_date.iso8601}",
|
|
114
|
+
timestamp.strftime("%Y-%m-%d_%H-%M-%S")
|
|
115
|
+
].join("_") + ".#{format}"
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
# rubocop:enable Metrics/ParameterLists
|
|
119
|
+
|
|
120
|
+
def serialize(response:, format:, timestamp:)
|
|
121
|
+
case format
|
|
122
|
+
when "json"
|
|
123
|
+
JSON.pretty_generate(response)
|
|
124
|
+
when "csv"
|
|
125
|
+
serialize_csv(response: response, timestamp: timestamp)
|
|
126
|
+
else
|
|
127
|
+
raise ArgumentError, "Unsupported format `#{format}`."
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def serialize_csv(response:, timestamp:)
|
|
132
|
+
sample_timestamp = timestamp.utc.iso8601
|
|
133
|
+
|
|
134
|
+
CSV.generate do |csv|
|
|
135
|
+
csv << CSV_HEADERS
|
|
136
|
+
rows(response).each do |option|
|
|
137
|
+
csv << csv_row(response, option, sample_timestamp)
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# rubocop:disable Metrics/AbcSize
|
|
143
|
+
def csv_row(response, option, _sample_timestamp)
|
|
144
|
+
[
|
|
145
|
+
option[:putCall],
|
|
146
|
+
option[:symbol],
|
|
147
|
+
option[:description],
|
|
148
|
+
option[:strikePrice],
|
|
149
|
+
normalize_option_date(option[:expirationDate]),
|
|
150
|
+
option[:mark],
|
|
151
|
+
option[:bid],
|
|
152
|
+
option[:bidSize],
|
|
153
|
+
option[:ask],
|
|
154
|
+
option[:askSize],
|
|
155
|
+
option[:last],
|
|
156
|
+
option[:lastSize],
|
|
157
|
+
option[:openInterest],
|
|
158
|
+
option[:totalVolume],
|
|
159
|
+
option[:delta],
|
|
160
|
+
option[:gamma],
|
|
161
|
+
option[:theta],
|
|
162
|
+
option[:vega],
|
|
163
|
+
option[:rho],
|
|
164
|
+
option[:volatility],
|
|
165
|
+
option[:theoreticalVolatility],
|
|
166
|
+
option[:theoreticalOptionValue],
|
|
167
|
+
option[:intrinsicValue],
|
|
168
|
+
option[:extrinsicValue],
|
|
169
|
+
response[:underlyingPrice]
|
|
170
|
+
]
|
|
171
|
+
end
|
|
172
|
+
# rubocop:enable Metrics/AbcSize
|
|
173
|
+
|
|
174
|
+
def rows(response)
|
|
175
|
+
extracted_rows = [response[:callExpDateMap], response[:putExpDateMap]].compact.flat_map do |date_map|
|
|
176
|
+
rows_from_date_map(date_map)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
extracted_rows.sort_by do |option|
|
|
180
|
+
[
|
|
181
|
+
normalize_option_date(option[:expirationDate]).to_s,
|
|
182
|
+
option[:putCall].to_s,
|
|
183
|
+
option[:strikePrice].to_f
|
|
184
|
+
]
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def rows_from_date_map(date_map)
|
|
189
|
+
date_map.values.flat_map do |strikes|
|
|
190
|
+
strikes.values.flatten.map { |option| option.transform_keys(&:to_sym) }
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def option_root(response, fallback_symbol)
|
|
195
|
+
first_option = rows(response).find { |option| !blank?(option[:optionRoot]) }
|
|
196
|
+
first_option ? first_option[:optionRoot] : fallback_symbol
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def normalize_option_date(value)
|
|
200
|
+
return if value.nil?
|
|
201
|
+
|
|
202
|
+
Date.parse(value.to_s).iso8601
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def blank?(value)
|
|
206
|
+
value.nil? || value.to_s.strip.empty?
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
data/lib/schwab_rb/version.rb
CHANGED
data/lib/schwab_rb.rb
CHANGED
|
@@ -23,6 +23,8 @@ require_relative "schwab_rb/orders/instruments"
|
|
|
23
23
|
require_relative "schwab_rb/market_hours"
|
|
24
24
|
require_relative "schwab_rb/price_history"
|
|
25
25
|
require_relative "schwab_rb/price_history/downloader"
|
|
26
|
+
require_relative "schwab_rb/option_sample"
|
|
27
|
+
require_relative "schwab_rb/option_sample/downloader"
|
|
26
28
|
require_relative "schwab_rb/movers"
|
|
27
29
|
require_relative "schwab_rb/orders/builder"
|
|
28
30
|
require_relative "schwab_rb/orders/session"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: schwab_rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Joseph Platta
|
|
@@ -256,6 +256,8 @@ files:
|
|
|
256
256
|
- lib/schwab_rb/market_hours.rb
|
|
257
257
|
- lib/schwab_rb/movers.rb
|
|
258
258
|
- lib/schwab_rb/option.rb
|
|
259
|
+
- lib/schwab_rb/option_sample.rb
|
|
260
|
+
- lib/schwab_rb/option_sample/downloader.rb
|
|
259
261
|
- lib/schwab_rb/orders/builder.rb
|
|
260
262
|
- lib/schwab_rb/orders/destination.rb
|
|
261
263
|
- lib/schwab_rb/orders/duration.rb
|