schwab_rb 0.3.9 → 0.3.11

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 286e74e6bfe86be042b8863bbbc302e62eaca061d7640ae08bc5dd7f4d73528a
4
- data.tar.gz: a75283f71dd0a09aedb78362b82242c6344c0003b66c38d68d9bcce3f4c26a21
3
+ metadata.gz: 53cef23634d68e9c9650190e7ad67d58e6c4b3dda00cb7ec2a5e43cc9495bf1f
4
+ data.tar.gz: 9e60a403d25f003c38cc657db9683e74b8deae7324757a88337da4b36761a5e7
5
5
  SHA512:
6
- metadata.gz: 41f2a377bc7a7ba4896e0628f3573e6bb06d1c34d1a5f4822dab5d4ed69d32cfb9346f10e880576ea0e09462bdccfbbe7315ce6f9889a6092535083d693d8571
7
- data.tar.gz: c982d20399c1bdf9bccb19c45fdf7a0d6c5fe121c4c3a59512f171a0bd2b4a603ace02108c1c4d9749bd499dd5cd56d2746e9a0c16259eec4ef37bf1b27feef4
6
+ metadata.gz: f6e2e35615e1b5fca5f6a8dce012c660da6ecf0f88f752aee02594188af66136cae36aa263aa6578c5af18242c9154f51a12f46f4fc396f897265b26cdab9e3b
7
+ data.tar.gz: 4c369dfaa8fcec91d819849680c7bb7409b051da5a3b0dacdb8c15b9d516e042b751450d2863fd86fbac4b5a776d2f4205c86dfe223b672345372015b6890321
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Script to fetch price history data and save as fixture
5
+ # Usage: ruby examples/fetch_price_history.rb [SYMBOL]
6
+
7
+ require_relative "../lib/schwab_rb"
8
+ require "dotenv"
9
+ require "json"
10
+ require "fileutils"
11
+ require "pry"
12
+
13
+ Dotenv.load
14
+
15
+ def create_client
16
+ token_path = ENV["TOKEN_PATH"] || "schwab_token.json"
17
+ SchwabRb::Auth.init_client_easy(
18
+ ENV.fetch("SCHWAB_API_KEY", nil),
19
+ ENV.fetch("SCHWAB_APP_SECRET", nil),
20
+ ENV.fetch("APP_CALLBACK_URL", nil),
21
+ token_path
22
+ )
23
+ end
24
+
25
+ def fetch_price_history(symbol = "$SPX",
26
+ start_date = Date.new(Date.today.year, Date.today.month, 1),
27
+ end_date = Date.today
28
+ )
29
+ client = create_client
30
+ puts "Fetching price history for #{symbol}..."
31
+
32
+ puts " - Fetching minute price history..."
33
+ price_hist = client.get_price_history(
34
+ symbol,
35
+ period_type: SchwabRb::PriceHistory::PeriodTypes::DAY,
36
+ period: SchwabRb::PriceHistory::Periods::ONE_DAY,
37
+ frequency_type: SchwabRb::PriceHistory::FrequencyTypes::MINUTE,
38
+ frequency: SchwabRb::PriceHistory::Frequencies::EVERY_MINUTE,
39
+ start_datetime: start_date,
40
+ end_datetime: end_date,
41
+ need_extended_hours_data: true,
42
+ need_previous_close: false,
43
+ return_data_objects: true
44
+ )
45
+
46
+ puts "Price history data collection complete!"
47
+ puts "Symbol: #{symbol}"
48
+ rescue StandardError => e
49
+ puts "Error fetching price history: #{e.message}"
50
+ puts e.backtrace.first(3)
51
+ end
52
+
53
+ if __FILE__ == $PROGRAM_NAME
54
+ symbol = ARGV[0] || "$SPX"
55
+ start_date = ARGV[1] ? Date.parse(ARGV[1]) : Date.new(2025, 8, 1)
56
+ end_date = ARGV[2] ? Date.parse(ARGV[2]) : Date.today
57
+
58
+ fetch_price_history(symbol, start_date, end_date)
59
+ end
@@ -892,7 +892,7 @@ module SchwabRb
892
892
  def format_date_as_millis(var_name, dt)
893
893
  assert_type(var_name, dt, [Date, DateTime])
894
894
  dt = DateTime.new(dt.year, dt.month, dt.day) unless dt.is_a?(DateTime)
895
- (dt.to_time.to_f * 1000).to_i
895
+ (dt.to_time.to_i * 1000).to_i
896
896
  end
897
897
 
898
898
  def normalize_start_and_end_datetimes(start_datetime, end_datetime)
@@ -12,16 +12,18 @@ module SchwabRb
12
12
  end
13
13
 
14
14
  def initialize(data)
15
- @symbol = data["symbol"]
16
- @empty = data["empty"]
17
- @candles = data["candles"]&.map { |candle_data| Candle.new(candle_data) } || []
15
+ # Convert string keys to symbols if needed
16
+ data = data.transform_keys(&:to_sym) if data.respond_to?(:transform_keys)
17
+ @symbol = data[:symbol]
18
+ @empty = data[:empty]
19
+ @candles = data[:candles]&.map { |candle_data| Candle.new(candle_data) } || []
18
20
  end
19
21
 
20
22
  def to_h
21
23
  {
22
- "symbol" => @symbol,
23
- "empty" => @empty,
24
- "candles" => @candles.map(&:to_h)
24
+ symbol: @symbol,
25
+ empty: @empty,
26
+ candles: @candles.map(&:to_h)
25
27
  }
26
28
  end
27
29
 
@@ -45,10 +47,10 @@ module SchwabRb
45
47
 
46
48
  def candles_for_date_range(start_date, end_date)
47
49
  start_timestamp = start_date.to_time.to_i * 1000
48
- end_timestamp = end_date.to_time.to_i * 1000
50
+ end_timestamp = (end_date.to_time + 24 * 60 * 60 - 1).to_i * 1000
49
51
 
50
52
  @candles.select do |candle|
51
- candle.datetime >= start_timestamp && candle.datetime <= end_timestamp
53
+ candle.datetime_ms >= start_timestamp && candle.datetime_ms <= end_timestamp
52
54
  end
53
55
  end
54
56
 
@@ -102,34 +104,36 @@ module SchwabRb
102
104
  include Enumerable
103
105
 
104
106
  class Candle
105
- attr_reader :open, :high, :low, :close, :volume, :datetime
107
+ attr_reader :open, :high, :low, :close, :volume, :datetime_ms
106
108
 
107
109
  def initialize(data)
108
- @open = data["open"]
109
- @high = data["high"]
110
- @low = data["low"]
111
- @close = data["close"]
112
- @volume = data["volume"]
113
- @datetime = data["datetime"]
110
+ # Convert string keys to symbols if needed
111
+ data = data.transform_keys(&:to_sym) if data.respond_to?(:transform_keys)
112
+ @open = data[:open]
113
+ @high = data[:high]
114
+ @low = data[:low]
115
+ @close = data[:close]
116
+ @volume = data[:volume]
117
+ @datetime_ms = data[:datetime]
114
118
  end
115
119
 
116
120
  def to_h
117
121
  {
118
- "open" => @open,
119
- "high" => @high,
120
- "low" => @low,
121
- "close" => @close,
122
- "volume" => @volume,
123
- "datetime" => @datetime
122
+ open: @open,
123
+ high: @high,
124
+ low: @low,
125
+ close: @close,
126
+ volume: @volume,
127
+ datetime: @datetime_ms
124
128
  }
125
129
  end
126
130
 
127
- def date_time
128
- Time.at(@datetime / 1000.0) if @datetime
131
+ def datetime
132
+ Time.at(@datetime_ms / 1000.0) if @datetime_ms
129
133
  end
130
134
 
131
135
  def date
132
- date_time&.to_date
136
+ datetime&.to_date
133
137
  end
134
138
 
135
139
  def price_change
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SchwabRb
4
- VERSION = "0.3.9"
4
+ VERSION = "0.3.11"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: schwab_rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.3.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joseph Platta
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-08-29 00:00:00.000000000 Z
10
+ date: 2025-09-08 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: async
@@ -205,6 +205,7 @@ files:
205
205
  - doc/notes/data_objects_analysis.md
206
206
  - doc/notes/data_objects_refactoring_plan.md
207
207
  - examples/fetch_account_numbers.rb
208
+ - examples/fetch_price_history.rb
208
209
  - examples/fetch_user_preferences.rb
209
210
  - lib/schwab_rb.rb
210
211
  - lib/schwab_rb/account.rb