iron_warbler 2.0.7.37 → 2.0.7.39

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: 7207f71989ba452eb0b9de7db2d9a66a6571112e23057a225519cbdab4fb1f79
4
- data.tar.gz: 4a2663f019822b6c6fded27cd41dcd23beb7cf12818e10d4f6057e8620449a6e
3
+ metadata.gz: 706bc42f34e116f0071a21611468365ac0a6a2b76fc722c812a9d0158380898b
4
+ data.tar.gz: 670933ff9f081f0c7d31a32a1a99e4af6b933e4d1b019c51b5923d3efd244395
5
5
  SHA512:
6
- metadata.gz: 43c22a4d167d7b7c8095bcee5bc5280826586b2c583e92cb1353a30459ce578bfc6e603fdb008b3582f1dfadbca342dd4c866590f3a6b332f15198cd9a919818
7
- data.tar.gz: 0d5183d3b41c67afbb4dfdc3a9fade2ec65400483aacb2b71439d88f630b0e9f570755884d7d316d3feba71ad70c9d2cccd6d5c4e2b8676b028d1a0c78fa210d
6
+ metadata.gz: 7e3039883ab46c0a8231500f29fffba931f2ba8fb45529ea139464246c1657940d97279f1b4f61f9d8a563640384874096c87949cb617c0e96aa34c6e978d946
7
+ data.tar.gz: b0b80caa5be42c0062836150043e89ef719df3caac02b4535887b17ea8e6b7d180073b2585db7195f83b0adec264ab4421f7f3fcc830fcf2394657081d2fde40
data/README.txt CHANGED
@@ -10,3 +10,8 @@ From: https://docs.galpy.org/en/latest/installation.html
10
10
  calculator: https://www.omnicalculator.com/finance/black-scholes
11
11
 
12
12
  From: https://pythoninoffice.com/calculate-black-scholes-option-price-in-python/
13
+
14
+ = schwab =
15
+ == swagger ==
16
+
17
+ * https://developer.schwab.com/products/trader-api--individual
@@ -1,5 +1,9 @@
1
1
 
2
2
  //= require ./gameui
3
+ //= require ./stock
3
4
 
4
5
  // console.log('Loaded iron_warbler/application.js')
5
6
 
7
+ const appRouter = {
8
+ showStockPath: (symbol) => `/trading/stocks/${symbol}`,
9
+ }
@@ -0,0 +1,9 @@
1
+
2
+ $(document).ready(() => {
3
+
4
+ $('select[name="stock_selector"]').on('change', (ev) => {
5
+ // logg(ev, 'ev')
6
+ window.location = appRouter.showStockPath(ev.target.value)
7
+ })
8
+
9
+ })
@@ -34,7 +34,7 @@ class Iro::ApplicationController < Wco::ApplicationController
34
34
  },
35
35
  })
36
36
  out = out.parsed_response
37
- puts! out, 'out'
37
+ # puts! out, 'out'
38
38
 
39
39
  attrs = {
40
40
  schwab_access_token: out['access_token'],
@@ -43,10 +43,12 @@ class Iro::ApplicationController < Wco::ApplicationController
43
43
  }
44
44
  # puts! attrs, 'attrs'
45
45
 
46
- profile.update(attrs)
47
- profile.save!
46
+ if attrs[:schwab_refresh_token]
47
+ profile.update(attrs)
48
+ profile.save!
49
+ end
48
50
 
49
- render json: { status: :ok }
51
+ render json: { attrs: attrs, out: out }
50
52
  end
51
53
 
52
54
  ##
@@ -1,4 +1,7 @@
1
1
 
2
+ ##
3
+ ## https://www.macrotrends.net/stocks/charts/META/meta-platforms/stock-price-history
4
+ ##
2
5
  class Iro::StocksController < Iro::ApplicationController
3
6
  before_action :set_stock, only: [:show, :edit, :update, :destroy]
4
7
 
@@ -57,6 +60,9 @@ class Iro::StocksController < Iro::ApplicationController
57
60
  @priceitems = ::Iro::Priceitem.where({
58
61
  ticker: @stock.ticker,
59
62
  })
63
+ @datapoints = Iro::Datapoint.where({
64
+ symbol: @stock.ticker,
65
+ }).order_by({ date: :desc }).limit(100)
60
66
 
61
67
  respond_to do |format|
62
68
  format.html
@@ -84,7 +90,12 @@ class Iro::StocksController < Iro::ApplicationController
84
90
  private
85
91
 
86
92
  def set_stock
87
- @stock = Iro::Stock.find(params[:id])
93
+ begin
94
+ @stock = Iro::Stock.find(params[:id])
95
+ rescue Mongoid::Errors::DocumentNotFound => e
96
+ @stock = Iro::Stock.find_by ticker: params[:id]
97
+ end
98
+ @stocks_list = Iro::Stock.tickers_list
88
99
  end
89
100
 
90
101
  def stock_params
@@ -1,5 +1,8 @@
1
1
 
2
-
2
+ ##
3
+ ## Datapoints are at most daily!
4
+ ## See Priceitem for intra-day data
5
+ ##
3
6
  class Iro::Datapoint
4
7
  include Mongoid::Document
5
8
  include Mongoid::Timestamps
@@ -31,25 +34,23 @@ class Iro::Datapoint
31
34
  SYMBOL_T20YR = 'T20YR'
32
35
  SYMBOL_T30YR = 'T30YR'
33
36
 
34
- field :date, type: Date ## @obsolete, use quote_at
37
+ field :date, type: Date
35
38
  index({ kind: -1, date: -1 })
39
+ validates :date, uniqueness: { scope: [ :symbol ] }
36
40
 
37
41
  field :quote_at, type: DateTime
38
42
  index({ kind: -1, quote_at: -1 })
39
- validates :quote_at, uniqueness: { scope: [ :kind, :symbol ] }
43
+ validates :quote_at, uniqueness: { scope: [ :kind, :symbol ] } ## scope-by-kind is unnecessary here? _vp_ 2024-08-08
40
44
 
41
45
  field :open, type: Float
42
46
  field :high, type: Float
43
47
  field :low, type: Float
48
+ def close; value; end
49
+ def close= a; value= a; end
44
50
 
45
51
  field :value, type: Float
46
52
  validates :value, presence: true
47
- def close
48
- value
49
- end
50
- def close= a
51
- value= a
52
- end
53
+
53
54
 
54
55
  field :volume, type: Integer
55
56
 
@@ -156,7 +157,7 @@ class Iro::Datapoint
156
157
  csv = CSV.read(path, headers: true)
157
158
  csv.each do |row|
158
159
  flag = create({
159
- kind: KIND_STOCK,
160
+ kind: KIND_STOCK,
160
161
  symbol: symbol,
161
162
  date: row['Date'],
162
163
  quote_at: row['Date'],
@@ -168,7 +169,11 @@ class Iro::Datapoint
168
169
  low: row['Low'],
169
170
  value: row['Close'],
170
171
  })
171
- print '.' if flag.persisted?
172
+ if flag.persisted?
173
+ print '^'
174
+ else
175
+ puts flag.errors.messages
176
+ end
172
177
  end
173
178
  puts 'ok'
174
179
  end
@@ -1,6 +1,7 @@
1
1
 
2
2
  ##
3
- ## specifically Option or Stock priceitem?
3
+ ## Specifically Option or Stock priceitem?
4
+ ## Priceitems are intra-day! See Datapoint for daily data
4
5
  ##
5
6
  class Iro::Priceitem
6
7
  include Mongoid::Document
@@ -8,7 +9,7 @@ class Iro::Priceitem
8
9
  store_in collection: 'iro_price_items'
9
10
 
10
11
  ## PUT, CALL, STOCK
11
- field :putCall, type: String
12
+ field :putCall, type: String ## kind
12
13
  field :symbol, type: String
13
14
  field :ticker, type: String
14
15
  # belongs_to :stock, inverse_of: :priceitems
@@ -24,6 +25,7 @@ class Iro::Priceitem
24
25
  field :highPrice, type: Float
25
26
  field :closePrice, type: Float
26
27
 
28
+ field :quote_at, type: DateTime
27
29
  field :quoteTimeInLong, type: Integer
28
30
  field :timestamp, type: Integer
29
31
  field :totalVolume, type: Integer
@@ -31,6 +33,8 @@ class Iro::Priceitem
31
33
  field :exchangeName, type: String
32
34
  field :volatility, type: Float
33
35
 
36
+ field :expires_on, type: :date
37
+
34
38
  def self.my_find props={}
35
39
  lookup = { '$lookup': {
36
40
  'from': 'iro_price_items',
@@ -1,6 +1,9 @@
1
1
  include Math
2
2
  require 'business_time'
3
3
 
4
+ ##
5
+ ## https://www.macrotrends.net/stocks/charts/META/meta-platforms/stock-price-history
6
+ ##
4
7
  class Iro::Stock
5
8
  include Mongoid::Document
6
9
  include Mongoid::Timestamps
@@ -18,6 +21,8 @@ class Iro::Stock
18
21
  field :ticker
19
22
  validates :ticker, uniqueness: true, presence: true
20
23
  index({ ticker: -1 }, { unique: true })
24
+ def symbol; ticker; end
25
+ def symbol= a; ticker = a; end
21
26
 
22
27
  field :last, type: :float
23
28
  field :options_price_increment, type: :float
@@ -30,6 +35,8 @@ class Iro::Stock
30
35
  has_many :options, class_name: 'Iro::Option', inverse_of: :stock
31
36
  has_many :priceitems, inverse_of: :stock
32
37
 
38
+ default_scope { order_by({ ticker: :asc }) }
39
+
33
40
  ## my_find
34
41
  def self.f ticker
35
42
  self.find_by ticker: ticker
@@ -55,7 +62,14 @@ class Iro::Stock
55
62
  stock.volatility_from_yr
56
63
 
57
64
  =end
58
- def volatility duration:
65
+ field :volatility, type: :float
66
+ def volatility duration: 1.year, recompute: false
67
+ if self[:volatility]
68
+ if !recompute
69
+ return self[:volatility]
70
+ end
71
+ end
72
+
59
73
  stock = self
60
74
  begin_on = Time.now - duration - 1.day
61
75
  points = Iro::Datapoint.where( kind: 'STOCK', symbol: stock.ticker,
@@ -86,6 +100,7 @@ class Iro::Stock
86
100
  adjustment = 2.0
87
101
  out = out * adjustment
88
102
  puts! out, 'volatility (adjusted)'
103
+ self.update volatility: out
89
104
  return out
90
105
  end
91
106
 
@@ -18,18 +18,30 @@ class Tda::Option
18
18
 
19
19
 
20
20
  ##
21
- ## 2023-02-05 _vp_ :: Gets the entire chain
21
+ ## Get entire chains for a ticker
22
+ ## params: { ticker, }
22
23
  ##
23
- def self.get_chain params
24
- opts = { symbol: params[:ticker] } ## use 'GME' as symbol here even though a symbol is eg 'GME_021023P2.5'
25
- query = { apikey: ::TD_AMERITRADE[:apiKey] }.merge opts
26
- puts! query, 'input opts'
24
+ ## 2024-08-09 :: Continue
25
+ ##
26
+ def self.get_chains params
27
+ profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
27
28
 
28
- path = "/v1/marketdata/chains"
29
- out = self.get path, { query: query }
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
+ basic_auth: { username: SCHWAB_DATA[:key], password: SCHWAB_DATA[:secret] },
39
+ headers: headers,
40
+ query: query }
30
41
  timestamp = DateTime.parse out.headers['date']
31
42
  out = out.parsed_response.deep_symbolize_keys
32
43
 
44
+ byebug
33
45
 
34
46
  outs = []
35
47
  %w| put call |.each do |contractType|
@@ -53,8 +65,8 @@ class Tda::Option
53
65
  end
54
66
  end
55
67
 
56
- outs.each do |x|
57
- opi = ::Iro::OptionPriceItem.create( x )
68
+ outs.each do |out|
69
+ opi = ::Iro::PriceItem.create( out )
58
70
  if !opi.persisted?
59
71
  puts! opi.errors.full_messages, "Cannot create OptionPriceItem"
60
72
  end
@@ -125,7 +137,6 @@ class Tda::Option
125
137
  }
126
138
  puts! out, 'out'
127
139
  timestamp = DateTime.parse out.headers['date']
128
- # out = HTTParty.get "https://api.tdameritrade.com#{path}", { query: query }
129
140
  out = out.parsed_response.deep_symbolize_keys
130
141
 
131
142
 
@@ -9,17 +9,20 @@
9
9
  %td Ticker
10
10
  %td last price
11
11
  %td n priceitems
12
+ %td volatility
12
13
  %tbody
13
14
  - @stocks.each do |stock|
14
15
  %tr
15
16
  %td
16
17
  = link_to '[~]', edit_stock_path(stock)
17
18
  = link_to '[api]', stock_path(stock, format: :json)
18
- <b>#{stock.ticker}</b>
19
+ <b>#{link_to stock.ticker, stock_path(stock)}</b>
19
20
  %td
20
21
  #{pp_amount stock.last}
21
22
  %td
22
23
  = stock.priceitems.length
24
+ %td
25
+ = stock.volatility rescue nil
23
26
 
24
27
  %hr
25
28
  = render 'iro/stocks/form', stock: Iro::Stock.new
@@ -1,5 +1,27 @@
1
1
 
2
2
  .stocks-show.maxwidth
3
- %h4= @stock
3
+ .header
4
+ %h3.title
5
+ = select_tag :stock_selector, options_for_select( @stocks_list, selected: @stock.ticker ), class: 'select2'
4
6
 
5
- %h5 Max Pain
7
+ .row
8
+ .col-md-3
9
+ %h4 Datapoints
10
+ %table.bordered
11
+ %thead
12
+ %td Date
13
+ %td Value
14
+ %tbody
15
+ - @datapoints.each do |pt|
16
+ %tr
17
+ %td= pt.date
18
+ %td= pt.value
19
+
20
+
21
+ .col-md-9
22
+ %ul
23
+ %li
24
+ %b 1 yr volatility <br />
25
+ = @stock.volatility
26
+
27
+ %h4 Max Pain
@@ -38,6 +38,21 @@ namespace :iro do
38
38
  print '^'
39
39
  end
40
40
 
41
+ ## Expected headers: Date, Open, High, Low, Close
42
+ desc 'import_stock stock=<stock> path=<path>'
43
+ task :import_stock => :environment do
44
+ # puts! ARGV, 'ARGV'
45
+ # puts! ENV, 'ENV'
46
+ if ARGV.length != 3
47
+ puts! ''
48
+ puts! "Usage: import_stock <stock> <path>"
49
+ puts! 'Expected headers: Date, Open, High, Low, Close'
50
+ puts! ''
51
+ exit 0
52
+ end
53
+ Iro::Datapoint.import_stock symbol: ENV['stock'], path: ENV['path']
54
+ end
55
+
41
56
  desc 'import historic treasuries'
42
57
  task :import_1990_2023_treasuries => :environment do
43
58
  ::Iro::Iro.import_1990_2023_treasuries
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.37
4
+ version: 2.0.7.39
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-07-31 00:00:00.000000000 Z
11
+ date: 2024-08-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: business_time
@@ -217,6 +217,7 @@ files:
217
217
  - app/assets/config/iron_warbler_manifest.js
218
218
  - app/assets/javascript/iron_warbler/application.js
219
219
  - app/assets/javascript/iron_warbler/gameui.js
220
+ - app/assets/javascript/iron_warbler/stock.js
220
221
  - app/assets/stylesheets/iron_warbler/Card.scss
221
222
  - app/assets/stylesheets/iron_warbler/alerts.scss
222
223
  - app/assets/stylesheets/iron_warbler/application.css