iron_warbler 2.0.7.50 → 2.0.7.51

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: 34e2545b7c9088e737b36b2436c475bd820e1e0f00c507f84166eca1c616421e
4
- data.tar.gz: 1e0bb92359a9ebc0c3a0e9cd4dc252e48da5097096f94855a88c2a0dfd41fd10
3
+ metadata.gz: 27e79457c024254243edfd06b728c5b236da335b03880678f7bffdb72d4fb6b1
4
+ data.tar.gz: ed9263babe2e1bcff873de6924a0160596aa535675a690b3c96319b4e0b53391
5
5
  SHA512:
6
- metadata.gz: 3e0ea3ed8e276d87f870f295c61cf5c2119fe9b375d7f12f8b2090a1f161300883361f530d4855949cb2677f4a26d5a43f419efb52bf517d221d6182be2c2f0a
7
- data.tar.gz: 5236754132aeee57af308c4c86e73fdb4a39de56770a47a0c125444fcc7f437ca544a525fabc0158c064690eb2b4cb478d8167a627f68298015534ae62f96c78
6
+ metadata.gz: 7d5a2fbb95f4278e70d0055b591c3f337c257e37112e49f1f34f1ae3ba672ca03abafc5165611a94b20e29d8b0073f70f56db0cad37cca59a3ec66d3e0386ea2
7
+ data.tar.gz: 78d43e5d0142b8481593e5239c997e9756615307d97a0919dc970be22e645fb3ae2847d08992e28bc0b05a017636bd6ba8756a5411c965f5236eeaba75bc57ba
@@ -1,6 +1,6 @@
1
1
 
2
2
  .purses-gameuiW {
3
- border: 1px solid red;
3
+ border: 1px solid #333;
4
4
  width: 100%;
5
5
  // overflow-x: scroll;
6
6
  overflow-y: hidden;
@@ -11,12 +11,12 @@
11
11
  .divider-expiry {
12
12
  height: 5px;
13
13
  width: 100%;
14
- background: red;
14
+ background: #333;
15
15
  }
16
16
  .divider-ticker {
17
17
  height: 2px;
18
18
  width: 100%;
19
- background: red;
19
+ background: #333;
20
20
  margin-bottom: 20px;
21
21
  }
22
22
 
@@ -5,11 +5,48 @@ class Iro::PositionsController < Iro::ApplicationController
5
5
  @position = Iro::Position.find params[:id]
6
6
  authorize! :check, @position
7
7
  outs = Tda::Order.check_status @position.schwab_order_id
8
- @position.update({ schwab_status: outs[:status] })
9
8
  puts! outs, 'outs'
9
+
10
+ if outs[:errors]
11
+ flash[:alert] = 'need to sync?!'
12
+ redirect_to request.referrer
13
+ return
14
+ end
15
+
16
+ attrs = { schwab_status: outs[:status] }
17
+ if 'FILLED' == outs[:status]
18
+ attrs[:status] = Iro::Position::STATUS_CLOSED
19
+ outs[:orderLegCollection].each do |leg|
20
+ hash = Iro::Option.symbol_to_h leg[:instrument][:symbol]
21
+ price = outs[:orderActivityCollection][0][:executionLegs].select do |exec_leg|
22
+ exec_leg[:instrumentId] == leg[:instrument][:instrumentId]
23
+ end[0][:price]
24
+ if @position.inner.matches_h( hash )
25
+ attrs[:inner_attributes] = { end_price: price }
26
+ end
27
+ if @position.outer.matches_h( hash )
28
+ attrs[:outer_attributes] = { end_price: price }
29
+ end
30
+ end
31
+ end
32
+ puts! attrs,' attrs'
33
+ @position.update(attrs)
34
+
10
35
  redirect_to request.referrer
11
36
  end
12
37
 
38
+ def close_prep2
39
+ @position = Iro::Position.find params[:id]
40
+ authorize! :close, @position
41
+ @position.inner.sync
42
+ @position.inner.update({ begin_price: @position.inner.end_price })
43
+ @position.outer.sync
44
+ @position.outer.update({ begin_price: @position.outer.end_price })
45
+ @position.update({ pending_price: @position.close_price, intent: Iro::Position::INTENT_CLOSE })
46
+ @query = Tda::Order.close_credit_spread_q @position
47
+ @page_title = "Closing #{@position} ..."
48
+ end
49
+
13
50
  def create
14
51
  @position = Iro::Position.new pos_params
15
52
  authorize! :create, @position
@@ -121,7 +158,30 @@ class Iro::PositionsController < Iro::ApplicationController
121
158
  redirect_to request.referrer
122
159
  end
123
160
 
161
+ def place_order
162
+ @position = Iro::Position.find params[:id]
163
+ authorize! :place_order, @position
164
+
165
+ query = case @position.intent
166
+ when Iro::Position::INTENT_CLOSE
167
+ Tda::Order.close_credit_spread_q @position
168
+ else
169
+ throw '_TODO: hls - placing order, not implemented'
170
+ end
171
+ outs = Tda::Order.place_order!( query )
172
+
173
+ flag = @position.update({
174
+ schwab_order_id: outs[:schwab_order_id],
175
+ schwab_status: outs[:schwab_status],
176
+ status: Iro::Position::STATUS_PENDING,
177
+ })
178
+
179
+ flash_notice flag
180
+ redirect_to controller: :purses, action: :show, template: 'show', view_status: 'pending', id: @position.purse_id
181
+ end
182
+
124
183
  ## place2 = credit-spread
184
+ ## should be renamped to open_prep2
125
185
  def place2
126
186
  @position = Iro::Position.find params[:id]
127
187
  authorize! :roll, @position
@@ -46,11 +46,12 @@ class Iro::PursesController < Iro::ApplicationController
46
46
  ).order_by( expires_on: :asc, ticker: :asc, long_or_short: :asc, inner_strike: :asc )
47
47
 
48
48
  if 'all' == params[:view_status]
49
- @positions = @positions.unscope( where: :status )
49
+ @positions = @positions.where( :status.in => Iro::Position::STATUSES )
50
50
  end
51
51
 
52
52
  calc_summary
53
53
 
54
+ @page_title = @purse.to_s
54
55
  render params[:template]
55
56
  end
56
57
 
@@ -12,20 +12,37 @@ class Iro::StocksController < Iro::ApplicationController
12
12
  if @stock.save
13
13
  flash_notice @stock
14
14
  else
15
+ @stock = Iro::Stock.unscoped.find_by ticker: stock_params[:ticker]
16
+ flag = @stock.update( deleted_at: nil, options_price_increment: stock_params[:options_price_increment] )
15
17
  flash_alert @stock
16
18
  end
17
19
  redirect_to action: :index
18
20
  end
19
21
 
20
22
  def destroy
23
+ authorize! :destroy, @stock
21
24
  @stock.destroy
22
- redirect_to stocks_url, notice: 'Stock was successfully destroyed.'
25
+ redirect_to stocks_url, notice: 'Stock was destroyed.'
23
26
  end
24
27
 
25
28
  def edit
26
29
  authorize! :edit, @stock
27
30
  end
28
31
 
32
+ def get_historic_data
33
+ authorize! :show, Iro::Stock
34
+ @stock = Iro::Stock.find params[:id]
35
+ @stock.get_historic_data( params[:date_from].to_date )
36
+ redirect_to action: :show, id: params[:id]
37
+ end
38
+
39
+ def recompute_volatility
40
+ authorize! :show, Iro::Stock
41
+ @stock = Iro::Stock.find params[:id]
42
+ @stock.volatility( recompute: true )
43
+ redirect_to action: :show, id: params[:id]
44
+ end
45
+
29
46
  def index
30
47
  @all_stocks = Iro::Stock.all
31
48
  authorize! :index, Iro::Stock
@@ -0,0 +1,24 @@
1
+
2
+ - pos = @position
3
+
4
+ .positions-close-prep2.maxwidth
5
+
6
+ %ul
7
+ %li= link_to '[table]', iro.purse_path(pos.purse)
8
+ %li= link_to '[gameUI]', iro.purse_gameui_path(pos.purse)
9
+
10
+ %ul
11
+ %li Intent: #{@position.intent}
12
+
13
+ %ul
14
+ %li
15
+ buy to close
16
+ = pos.inner
17
+ %li
18
+ sell to close
19
+ = pos.outer
20
+ %li
21
+ Query 2
22
+ %pre= JSON.pretty_generate( @query )
23
+
24
+ = button_to 'Place Order', position_place_order_path(@position), data: { confirm: 'Are you sure?' }
@@ -20,7 +20,7 @@
20
20
  .col-12
21
21
  %ul
22
22
  -# %li <b>Balance:</b> #{pp_amount purse.balance}
23
- %li <b>Available:</b> #{pp_amount purse.available}
23
+ %li <b>Available:</b> #{pp_amount purse.available_amount}
24
24
 
25
25
  .strategies--list
26
26
  %label strategies:
@@ -42,7 +42,7 @@
42
42
  .d-flex
43
43
  %h5 view_status
44
44
  = form_tag purse_path( @purse ), method: :get do
45
- = select_tag :view_status, options_for_select([ :all, :active, :proposed, :pending ], selected: params[:view_status] )
45
+ = select_tag :view_status, options_for_select(Iro::Position::STATUSES, selected: params[:view_status] )
46
46
  = hidden_field_tag :template, params[:template]
47
47
  = submit_tag '>'
48
48
 
@@ -3,28 +3,36 @@
3
3
  .maxwidth
4
4
  %h5 Stocks
5
5
 
6
- %table.bordered.padded
6
+ %table.bordered.data-table
7
7
  %thead
8
8
  %tr
9
9
  %td Ticker
10
10
  %td last price
11
11
  %td n priceitems
12
- %td volatility
12
+ %td volatility annual
13
+ %td volatility monthly
14
+ %td volatility daily
13
15
  %td strategies
14
16
  %td descr
15
17
  %tbody
16
18
  - @all_stocks.each do |stock|
17
19
  %tr
18
- %td.actions
19
- = link_to '[~]', edit_stock_path(stock)
20
- = link_to '[api]', stock_path(stock, format: :json)
21
- <b>#{link_to stock.ticker, stock_path(stock)}</b>
20
+ %td.actions{ style: 'min-width: 180px;' }
21
+ .d-flex
22
+ = link_to '[~]', edit_stock_path(stock)
23
+ = link_to '[api]', stock_path(stock, format: :json)
24
+ <b>#{link_to stock.ticker, stock_path(stock)}</b>&nbsp;
25
+ .d-inline= button_to 'x', stock_path(stock), method: :delete, data: { confirm: 'Are you sure?' }
22
26
  %td.last
23
27
  #{pp_amount stock.last}
24
28
  %td.priceitems
25
29
  = stock.priceitems.length
26
30
  %td.volatility
27
- = stock.volatility rescue nil
31
+ = stock.volatility_annual.round(4) rescue '___'
32
+ %td.volatility-monthly
33
+ = stock.volatility_monthly.round(4) rescue '___'
34
+ %td.volatility-daily
35
+ = stock.volatility_daily.round(4) rescue '___'
28
36
  %td.strategies
29
37
  %ul
30
38
  - stock.strategies.each do |s|
@@ -4,12 +4,34 @@
4
4
  %h3.title
5
5
  = select_tag :stock_selector, options_for_select( @stocks_list, selected: @stock.ticker ), class: 'select2'
6
6
 
7
+ = form_tag stock_get_historic_data_path(@stock) do
8
+ get historic data:
9
+ = text_field_tag :date_from
10
+ = submit_tag 'Go'
11
+
7
12
  .row
13
+
8
14
  .col-md-6
9
- %h4 Strategies [+]
15
+ %hr
16
+ = button_to 'recompute', stock_recompute_volatility_path(@stock)
10
17
  %ul
11
- - @stock.strategies.each do |st|
12
- %li= link_to st, strategy_path(st)
18
+ %li
19
+ %b 1 yr volatility <br />
20
+ = @stock.volatility_annual
21
+
22
+ %li
23
+ %b monthly <br />
24
+ = @stock.volatility_monthly
25
+ %li
26
+ %b daily <br />
27
+ = @stock.volatility_daily
28
+
29
+
30
+ -# .col-md-6
31
+ -# %h4 Strategies [+]
32
+ -# %ul
33
+ -# - @stock.strategies.each do |st|
34
+ -# %li= link_to st, strategy_path(st)
13
35
 
14
36
  .row
15
37
  -#
@@ -41,7 +63,7 @@
41
63
  - start_date = @datapoints.last.date
42
64
  - today = Date.today
43
65
  - (start_date..today).group_by { |d| d.beginning_of_month }.each do |month, days|
44
- %div
66
+ %div.bordered
45
67
  %h5= month.strftime("%B %Y")
46
68
  %ol.no-dot
47
69
  - days.each do |_day|
@@ -51,12 +73,8 @@
51
73
  - elsif _day.saturday? || _day.sunday?
52
74
  S
53
75
  - else
54
- .red .
55
-
56
-
57
- .col-md-9
58
- %ul
59
- %li
60
- %b 1 yr volatility <br />
61
- = @stock.volatility
76
+ - if _day.workday?
77
+ .red .
78
+ - else
79
+ h
62
80
 
data/config/routes.rb CHANGED
@@ -11,20 +11,21 @@ Iro::Engine.routes.draw do
11
11
 
12
12
  resources :option_watches
13
13
 
14
- match 'positions/:id/close', to: 'positions#close', as: :close_position, via: [ :get, :post ]
15
- get 'positions/:id/duplicate', to: 'positions#new', as: :duplicate_position
16
- post 'positions/propose', to: 'positions#propose', as: :propose_position
17
- get 'positions/:id/prepare', to: 'positions#prepare', as: :position_prepare_to_roll, defaults: { template: 'gameui' }
18
- match 'positions/:id/prepare2', to: 'positions#prepare2', as: :prepare2_position, defaults: { template: 'gameui' }, via: [ :get, :post ]
19
- match 'positions/:id/prepare3', to: 'positions#prepare3', as: :prepare3_position, defaults: { template: 'gameui' }, via: [ :get, :post ]
20
- post 'positions/:id/roll', to: 'positions#do_roll', as: :roll_position
21
- get 'positions/:id/sync', to: 'positions#sync', as: :sync_position
22
- get 'positions/:id/eval', to: 'positions#eval', as: :position_eval
23
- match 'positions/:id/place2', to: 'positions#place2', as: :place2_position, via: [ :get, :post ]
24
- post 'positions/:id/place3', to: 'positions#place3', as: :place3_position
25
- post 'positions/:id/reprice', to: 'positions#reprice', as: :reprice_position
26
- delete 'positions', to: 'positions#destroy_multi'
27
- get 'positions/:id/check', to: 'positions#check', as: :check_position
14
+ match 'positions/:id/close', to: 'positions#close_prep2', as: :close_position, via: [ :get, :post ]
15
+ get 'positions/:id/duplicate', to: 'positions#new', as: :duplicate_position
16
+ post 'positions/propose', to: 'positions#propose', as: :propose_position
17
+ get 'positions/:id/prepare', to: 'positions#prepare', as: :position_prepare_to_roll, defaults: { template: 'gameui' }
18
+ match 'positions/:id/prepare2', to: 'positions#prepare2', as: :prepare2_position, defaults: { template: 'gameui' }, via: [ :get, :post ]
19
+ match 'positions/:id/prepare3', to: 'positions#prepare3', as: :prepare3_position, defaults: { template: 'gameui' }, via: [ :get, :post ]
20
+ post 'positions/:id/roll', to: 'positions#do_roll', as: :roll_position
21
+ get 'positions/:id/sync', to: 'positions#sync', as: :sync_position
22
+ get 'positions/:id/eval', to: 'positions#eval', as: :position_eval
23
+ match 'positions/:id/place2', to: 'positions#place2', as: :place2_position, via: [ :get, :post ]
24
+ post 'positions/:id/place3', to: 'positions#place3', as: :place3_position
25
+ post 'positions/:id/reprice', to: 'positions#reprice', as: :reprice_position
26
+ delete 'positions', to: 'positions#destroy_multi'
27
+ get 'positions/:id/check', to: 'positions#check', as: :check_position
28
+ post 'positions/:id/place-order', to: 'positions#place_order', as: :position_place_order
28
29
  resources :positions
29
30
  resources :profiles
30
31
 
@@ -38,10 +39,10 @@ Iro::Engine.routes.draw do
38
39
  get 'schwab/sync_exec', to: 'application#schwab_sync_exec', as: :schwab_sync_exec
39
40
 
40
41
  get 'stocks/sync', to: 'stocks#sync', as: :sync_stocks
42
+ match 'stocks/:id/get-historic-data', to: 'stocks#get_historic_data', as: :stock_get_historic_data, via: [ :get, :post ]
43
+ match 'stocks/:id/recompute-volatility', to: 'stocks#recompute_volatility', as: :stock_recompute_volatility, via: [ :get, :post ]
41
44
  resources :stocks
42
45
 
43
- # get 'strategies/new-spread', to: 'strategies#new', as: :new_spread_strategy, defaults: { kind: 'spread' }
44
- # get 'strategies/new-wheel', to: 'strategies#new', as: :new_wheel_strategy, defaults: { kind: 'wheel' }
45
46
  resources :strategies
46
47
 
47
48
  get 'api/oauth2-redirect.html', to: 'api#oauth2_redirect'
data/lib/iron_warbler.rb CHANGED
@@ -3,6 +3,7 @@ require 'business_time'
3
3
  require 'haml'
4
4
  require 'mongoid'
5
5
  require 'httparty'
6
+ require 'holidays'
6
7
 
7
8
  require "iro/engine"
8
9
 
@@ -228,3 +229,12 @@ class Iro::Iro
228
229
 
229
230
 
230
231
  end
232
+
233
+ Holidays.between(Date.civil(2015, 1, 1), 2.years.from_now, :us, :observed).map do |holiday|
234
+ BusinessTime::Config.holidays << holiday[:date]
235
+ # Implement long weekends if they apply to the region, eg:
236
+ # BusinessTime::Config.holidays << holiday[:date].next_week if !holiday[:date].weekday?
237
+ end
238
+ BusinessTime::Config.holidays << '2025-04-18'.to_date
239
+ BusinessTime::Config.holidays << '2026-04-03'.to_date
240
+ # puts! 'all the holidays'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iron_warbler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.7.50
4
+ version: 2.0.7.51
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Pudeyev
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: holidays
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: cancancan
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -277,6 +291,7 @@ files:
277
291
  - app/views/iro/positions/_table_tr_covered_call.haml
278
292
  - app/views/iro/positions/_table_tr_long_credit_put_spread.haml
279
293
  - app/views/iro/positions/_table_tr_short_credit_call_spread.haml
294
+ - app/views/iro/positions/close_prep2.haml
280
295
  - app/views/iro/positions/done/_gameui_covered_call.haml-bk
281
296
  - app/views/iro/positions/done/_gameui_long_credit_put_spread.haml
282
297
  - app/views/iro/positions/done/_gameui_long_debit_call_spread.haml