iron_warbler 2.0.7.41 → 2.0.7.42

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: 00d253e5183bd431fc4f47681007d9ce860d7ea71ec825247db81d3f56224d4f
4
- data.tar.gz: 8600938ea2f61303da8f2eae2a4775e13b177cb976211a1911a4f5d9d09b1aba
3
+ metadata.gz: 63cc89c7ffba2eebf079f6470e3d7346d7fae502a5789e3822210ddb747fc3e1
4
+ data.tar.gz: faf3977f0f75b27653d9112c6ee993627a8a465aacb904866d5e047253989aa8
5
5
  SHA512:
6
- metadata.gz: 3867a03b4d259f27256a09eda9047b688f3410301429ea9d8a321875e9d753db9028cadf93fb02f2ea1617e0370ad6e920346d68ae5d673ebaacf8e953c389e2
7
- data.tar.gz: 6cdc0b4e80653ae44fa231e18007a829f6216a348b4fb6a5279dbf13f88caa7b50ed8d3053344c20680463f3aa5d2d681c6aa0edea48fd3452b8e916ac6ddaf5
6
+ metadata.gz: d7a17720e26f3226831d9381f91aa6202ae19be883d28c4b98210280c9afbda233550a0217d60212091d15b53ab708d636e62a953d21d04b5acc0c3dc31d0229
7
+ data.tar.gz: 9e9ce2229a98c994619f8b3a6f3134babf1acbf9c709d8a9a19d21c60c8d19da96e893aa7c571b074019402b3479bf903fbbd89c25ede452b17d51794b374fff
@@ -2,6 +2,23 @@
2
2
  class Iro::Api::StocksController < Iro::ApiController
3
3
  before_action :set_stock, only: [:destroy, :edit, :max_pain, :show, :update ]
4
4
 
5
+ def create
6
+ @stock = Iro::Stock.new(stock_params)
7
+ authorize! :create, @stock
8
+
9
+ if @stock.save
10
+ flash_notice @stock
11
+ else
12
+ flash_alert @stock
13
+ end
14
+ redirect_to action: :index
15
+ end
16
+
17
+ def destroy
18
+ @stock.destroy
19
+ redirect_to stocks_url, notice: 'Stock was successfully destroyed.'
20
+ end
21
+
5
22
  def index
6
23
  @stocks = Iro::Stock.active
7
24
  authorize! :index, Iro::Stock
@@ -14,8 +31,9 @@ class Iro::Api::StocksController < Iro::ApiController
14
31
 
15
32
  def max_pain
16
33
  authorize! :max_pain, @stock
34
+ Iro::Iro.schwab_sync
17
35
 
18
- hash = Tda::Option.get_chains({ ticker: @stock.ticker })
36
+ hash = Tda::Option.get_chains({ ticker: @stock.ticker, force: false })
19
37
  # hash = JSON.parse File.read './trash.json'
20
38
  @max_pain = Iro::Option.max_pain hash
21
39
 
@@ -27,6 +45,12 @@ class Iro::Api::StocksController < Iro::ApiController
27
45
  end
28
46
  end
29
47
 
48
+ def new
49
+ @stock = Iro::Stock.new
50
+ authorize! :new, @stock
51
+ end
52
+
53
+
30
54
  def show
31
55
  authorize! :show, @stock
32
56
  end_on = Time.now.to_date.in_time_zone('UTC')
@@ -56,26 +80,6 @@ class Iro::Api::StocksController < Iro::ApiController
56
80
  }).order_by({ quote_at: :asc })
57
81
  end
58
82
 
59
- def new
60
- @stock = Iro::Stock.new
61
- authorize! :new, @stock
62
- end
63
-
64
- def edit
65
- end
66
-
67
- def create
68
- @stock = Iro::Stock.new(stock_params)
69
- authorize! :create, @stock
70
-
71
- if @stock.save
72
- flash_notice @stock
73
- else
74
- flash_alert @stock
75
- end
76
- redirect_to action: :index
77
- end
78
-
79
83
  def update
80
84
  @stock = Iro::Stock.find params[:id]
81
85
  authorize! :update, @stock
@@ -87,10 +91,7 @@ class Iro::Api::StocksController < Iro::ApiController
87
91
  redirect_to request.referrer
88
92
  end
89
93
 
90
- def destroy
91
- @stock.destroy
92
- redirect_to stocks_url, notice: 'Stock was successfully destroyed.'
93
- end
94
+
94
95
 
95
96
  ##
96
97
  ## private
@@ -5,11 +5,6 @@ Po ||= Iro::Position
5
5
  O ||= Iro::Option
6
6
  Sto ||= Iro::Stock
7
7
 
8
- class Schwab
9
- include HTTParty
10
- debug_output $stdout
11
- end
12
-
13
8
  class Iro::ApplicationController < Wco::ApplicationController
14
9
  layout 'iro/application'
15
10
 
@@ -21,34 +16,7 @@ class Iro::ApplicationController < Wco::ApplicationController
21
16
 
22
17
  def schwab_sync
23
18
  authorize! :shwab_sync, Iro
24
- profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
25
-
26
- out = Schwab.post( "https://api.schwabapi.com/v1/oauth/token", {
27
- headers: {
28
- "Content-Type": "application/x-www-form-urlencoded",
29
- },
30
- basic_auth: { username: SCHWAB_DATA[:key], password: SCHWAB_DATA[:secret] },
31
- body: {
32
- grant_type: 'refresh_token',
33
- refresh_token: profile.schwab_refresh_token
34
- },
35
- })
36
- out = out.parsed_response
37
- # puts! out, 'out'
38
-
39
- attrs = {
40
- schwab_access_token: out['access_token'],
41
- schwab_refresh_token: out['refresh_token'],
42
- schwab_id_token: out['id_token'],
43
- }
44
- # puts! attrs, 'attrs'
45
-
46
- if attrs[:schwab_refresh_token]
47
- profile.update(attrs)
48
- profile.save!
49
- end
50
-
51
- render json: { attrs: attrs, out: out }
19
+ render json: Iro::Iro.schwab_sync
52
20
  end
53
21
 
54
22
  ##
@@ -38,8 +38,6 @@ class Iro::StocksController < Iro::ApplicationController
38
38
  end
39
39
  end
40
40
 
41
-
42
-
43
41
  def new
44
42
  @stock = Iro::Stock.new
45
43
  authorize! :new, @stock
@@ -66,13 +64,8 @@ class Iro::StocksController < Iro::ApplicationController
66
64
  symbol: @stock.ticker,
67
65
  }).order_by({ date: :desc }).limit(100)
68
66
 
69
- filename = "./data/schwab/#{Time.now.to_date.to_s}-#{@stock.ticker}-chains.json"
70
- if File.exists? filename
71
- hash = JSON.parse File.read filename
72
- else
73
- hash = Tda::Option.get_chains({ ticker: @stock.ticker })
74
- File.write filename, hash.to_json
75
- end
67
+ ## @deprecated, use api/stocks_controller#max_pain
68
+ hash = Tda::Option.get_chains({ ticker: @stock.ticker, force: false })
76
69
  @max_pain = Iro::Option.max_pain hash
77
70
  @max_pain_summary = {}
78
71
  @max_pain.each do |date, types|
@@ -96,8 +96,9 @@ class Iro::Option
96
96
  date = _date.split(':')[0].to_date.to_s
97
97
  outs[date] ||= {
98
98
  'all' => {},
99
- 'put' => {},
100
99
  'call' => {},
100
+ 'put' => {},
101
+ 'summary' => {},
101
102
  }
102
103
 
103
104
  strikes.each do |_strike, _v| ## _strike="18.5"
@@ -132,6 +133,17 @@ class Iro::Option
132
133
  end
133
134
  end
134
135
 
136
+ ## compute summary
137
+ outs.each do |date, types|
138
+ all = types['all']
139
+ outs[date]['summary'] = { 'value' => all.keys[0] }
140
+ all.each do |strike, amount|
141
+ if amount < all[ outs[date]['summary']['value'] ]
142
+ outs[date]['summary']['value'] = strike
143
+ end
144
+ end
145
+ end
146
+
135
147
  return outs
136
148
  end
137
149
 
@@ -19,69 +19,77 @@ class Tda::Option
19
19
 
20
20
  ##
21
21
  ## Get entire chains for a ticker
22
- ## params: { ticker, }
22
+ ## params: { ticker, force }
23
23
  ##
24
24
  ## 2024-08-09 :: Continue
25
+ ## 2024-08-21 :: Continue : )
25
26
  ##
26
27
  def self.get_chains params
27
- profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
28
-
29
- query = { symbol: params[:ticker] } ## use 'GME' as symbol here even though a symbol is eg 'GME_021023P2.5'
30
- puts! query, 'query'
31
-
32
- headers = {
33
- accept: 'application/json',
34
- Authorization: "Bearer #{profile[:schwab_access_token]}",
35
- }
36
- path = "/chains"
37
- out = self.get path, {
38
- headers: headers,
39
- query: query }
40
- timestamp = DateTime.parse out.headers['date']
41
- out = out.parsed_response
28
+ filename = "./data/schwab/#{Time.now.to_date.to_s}-#{params[:ticker]}-chains.json"
29
+ if !params[:force] && File.exists?( filename)
30
+ return JSON.parse File.read filename
42
31
 
43
- # byebug
32
+ else
33
+ profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
34
+ query = { symbol: params[:ticker] } ## use 'GME' as symbol here even though a symbol is eg 'GME_021023P2.5'
35
+ # puts! query, 'query'
44
36
 
45
- outs = []
46
- %w| put call |.each do |contractType|
47
- _out = out["#{contractType}ExpDateMap"]
48
- _out.each do |date, vs| ## date="2023-02-10:5"
49
- vs.each do |strike, _v| ## strike="18.5"
50
- _v = _v[0] ## weird, keep
51
- # puts! _v, '_v'
52
-
53
- v = {
54
- putCall: _v['putCall'],
55
- symbol: _v['symbol'],
56
- bid: _v['bid'],
57
- ask: _v['ask'],
58
- last: _v['last'],
59
- totalVolume: _v['totalVolume'],
60
- openInterest: _v['openInterest'],
61
- strikePrice: _v['strikePrice'],
62
- expirationDate: _v['expirationDate'],
63
- }
64
- v.each do |k, i|
65
- if i == 'NaN'
66
- v[k] = nil
37
+ headers = {
38
+ accept: 'application/json',
39
+ Authorization: "Bearer #{profile[:schwab_access_token]}",
40
+ }
41
+ path = "/chains"
42
+ out = self.get path, {
43
+ headers: headers,
44
+ query: query }
45
+ timestamp = DateTime.parse out.headers['date']
46
+ out = out.parsed_response
47
+ puts! out, 'outs'
48
+
49
+ # byebug
50
+
51
+ outs = []
52
+ %w| put call |.each do |contractType|
53
+ _out = out["#{contractType}ExpDateMap"]
54
+ _out.each do |date, vs| ## date="2023-02-10:5"
55
+ vs.each do |strike, _v| ## strike="18.5"
56
+ _v = _v[0] ## weird, keep
57
+ # puts! _v, '_v'
58
+
59
+ v = {
60
+ putCall: _v['putCall'],
61
+ symbol: _v['symbol'],
62
+ bid: _v['bid'],
63
+ ask: _v['ask'],
64
+ last: _v['last'],
65
+ totalVolume: _v['totalVolume'],
66
+ openInterest: _v['openInterest'],
67
+ strikePrice: _v['strikePrice'],
68
+ expirationDate: _v['expirationDate'],
69
+ }
70
+ v.each do |k, i|
71
+ if i == 'NaN'
72
+ v[k] = nil
73
+ end
67
74
  end
68
- end
69
75
 
70
- v[:timestamp] = timestamp
71
- v[:ticker] = params[:ticker]
72
- outs.push( v )
76
+ v[:timestamp] = timestamp
77
+ v[:ticker] = params[:ticker]
78
+ outs.push( v )
79
+ end
73
80
  end
74
81
  end
75
- end
76
82
 
77
- outs.each do |out|
78
- opi = ::Iro::Priceitem.create( out )
79
- if !opi.persisted?
80
- puts! opi.errors.full_messages, "Cannot create PriceItem"
83
+ outs.each do |out|
84
+ opi = ::Iro::Priceitem.create( out )
85
+ if !opi.persisted?
86
+ puts! opi.errors.full_messages, "Cannot create PriceItem"
87
+ end
81
88
  end
82
- end
83
89
 
84
- return out
90
+ File.write filename, out.to_json
91
+ return out
92
+ end
85
93
  end
86
94
 
87
95
  ##
@@ -1,5 +1,7 @@
1
1
 
2
2
  json.stocks @stocks do |stock|
3
- json.status stock.status
4
- json.ticker stock.ticker
3
+ # json.status stock.status
4
+ json.label stock.ticker
5
+ # json.ticker stock.ticker
6
+ json.value stock.ticker
5
7
  end
@@ -11,8 +11,14 @@ json.max_pain do
11
11
  json.value value
12
12
  end
13
13
  end
14
+ json.summary do
15
+ json.max_pain maps['summary']['value']
16
+ end
14
17
  end
15
18
  end
16
19
  end
17
20
 
18
21
 
22
+
23
+
24
+
data/lib/iron_warbler.rb CHANGED
@@ -5,6 +5,11 @@ require 'mongoid'
5
5
 
6
6
  require "iro/engine"
7
7
 
8
+ class Schwab
9
+ include HTTParty
10
+ debug_output $stdout
11
+ end
12
+
8
13
  class Iro::Iro
9
14
 
10
15
  def self.get_coins
@@ -162,4 +167,34 @@ class Iro::Iro
162
167
  end
163
168
  end
164
169
 
170
+ def self.schwab_sync
171
+ profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
172
+ out = Schwab.post( "https://api.schwabapi.com/v1/oauth/token", {
173
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
174
+ basic_auth: { username: SCHWAB_DATA[:key], password: SCHWAB_DATA[:secret] },
175
+ body: {
176
+ grant_type: 'refresh_token',
177
+ refresh_token: profile.schwab_refresh_token
178
+ },
179
+ })
180
+ out = out.parsed_response
181
+ puts! out, 'out'
182
+
183
+ attrs = {
184
+ schwab_access_token: out['access_token'],
185
+ schwab_refresh_token: out['refresh_token'],
186
+ schwab_id_token: out['id_token'],
187
+ }
188
+ # puts! attrs, 'attrs'
189
+
190
+ if attrs[:schwab_refresh_token]
191
+ profile.update(attrs)
192
+ profile.save!
193
+ return attrs
194
+ else
195
+ return false
196
+ end
197
+ end
198
+
199
+
165
200
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iron_warbler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7.41
4
+ version: 2.0.7.42
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Pudeyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-08-21 00:00:00.000000000 Z
11
+ date: 2024-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: business_time