iron_warbler 2.0.7.40 → 2.0.7.42

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f3f78d3df3906d30951b5cb346a7fbe4e04f4b4e3585cd2aab6b71de0f734e3
4
- data.tar.gz: 5054b253d6f7e944ffdfd09575b3401f2bd6371a5ea90190c9ba8dcfd16a3e58
3
+ metadata.gz: 63cc89c7ffba2eebf079f6470e3d7346d7fae502a5789e3822210ddb747fc3e1
4
+ data.tar.gz: faf3977f0f75b27653d9112c6ee993627a8a465aacb904866d5e047253989aa8
5
5
  SHA512:
6
- metadata.gz: d117e27f37ed366fe1fde852da5d7083d757e917d4badf9e1af4419885d4ea8a906571518572ca39842b6f34347dd010ea8e2e735cc63dcf194c3988246ff05a
7
- data.tar.gz: 9e87de47b40b4ae05197ad764f5e8f0c9d941798dfff736553d579d1eba06f5552de354e5b21cd5cc4446897646168eb1fd846f7c8ae5f02646fe192970f021f
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|
@@ -18,8 +18,14 @@ class Iro::Datapoint
18
18
  KIND_TREASURY = 'TREASURY'
19
19
 
20
20
  field :symbol ## ticker, but use 'symbol' here
21
- SYMBOL_BTC = 'BTC'
22
- SYMBOL_ETH = 'ETH'
21
+ ## crypto
22
+ SYMBOL_BTC = 'BTC'
23
+ SYMBOL_ETH = 'ETH'
24
+ ## currencies
25
+ SYMBOL_JPY = 'JPY'
26
+ SYMBOL_COP = 'COP'
27
+ SUMBOL_EUR = 'EUR'
28
+ ## treasuries
23
29
  SYMBOL_T1MO = 'T1MO'
24
30
  SYMBOL_T2MO = 'T2MO'
25
31
  SYMBOL_T3MO = 'T3MO'
@@ -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
@@ -25,6 +30,35 @@ class Iro::Iro
25
30
  end
26
31
  end
27
32
 
33
+ def self.get_currencies
34
+ out = HTTParty.get "https://api.currencyfreaks.com/v2.0/rates/latest?apikey=#{CURRENCYFREAKS[:key]}&symbols=COP,EUR,JPY"
35
+ out = out.parsed_response.deep_symbolize_keys!
36
+ out[:rates].each do |currency, value|
37
+
38
+ # opi = OPI.new({
39
+ # putCall: 'CURRENCY',
40
+ # symbol: currency,
41
+ # ticker: currency,
42
+ # exchangeName: 'currencyfreaks',
43
+ # mark: value,
44
+ # lastPrice: value,
45
+ # timestamp: Time.now.to_date,
46
+ # })
47
+ # opi.save!
48
+
49
+ datapoint = Iro::Datapoint.new({
50
+ date: Time.now.to_date,
51
+ quote_at: Time.now,
52
+ kind: Iro::Datapoint::KIND_CURRENCY,
53
+ symbol: currency,
54
+ value: value,
55
+ })
56
+ datapoint.save!
57
+
58
+ print '^'
59
+ end
60
+ end
61
+
28
62
  def self.get_treasuries
29
63
  response = HTTParty.get( "https://home.treasury.gov/resource-center/data-chart-center/interest-rates/daily-treasury-rates.csv/all/#{Time.now.strftime('%Y%m')}?type=daily_treasury_yield_curve&field_tdr_date_value_month=#{Time.now.strftime('%Y%m')}&page&_format=csv")
30
64
  outs = CSV.parse( response.body, { headers: true })
@@ -133,4 +167,34 @@ class Iro::Iro
133
167
  end
134
168
  end
135
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
+
136
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.40
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-20 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