iron_warbler 2.0.7.26 → 2.0.7.28

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/iron_warbler/purses.scss +31 -0
  3. data/app/assets/stylesheets/iron_warbler/utils.scss +28 -3
  4. data/app/controllers/iro/api/stocks_controller.rb +7 -4
  5. data/app/controllers/iro/positions_controller.rb +27 -21
  6. data/app/controllers/iro/stocks_controller.rb +20 -0
  7. data/app/models/iro/datapoint.rb +1 -1
  8. data/app/models/iro/option.rb +23 -11
  9. data/app/models/iro/position.rb +51 -53
  10. data/app/models/iro/{price_item.rb → priceitem.rb} +5 -1
  11. data/app/models/iro/purse.rb +9 -2
  12. data/app/models/iro/stock.rb +2 -0
  13. data/app/models/iro/strategy.rb +87 -50
  14. data/app/models/tda/option.rb +10 -4
  15. data/app/models/tda/stock.rb +13 -7
  16. data/app/views/iro/_main_header.haml +4 -3
  17. data/app/views/iro/api/stocks/index.json.jbuilder +5 -0
  18. data/app/views/iro/api/stocks/show.json.jbuilder +11 -0
  19. data/app/views/iro/api/stocks/show.json.jbuilder-bk +12 -0
  20. data/app/views/iro/positions/_form.haml +4 -2
  21. data/app/views/iro/positions/_gameui_short_credit_call_spread.haml +38 -0
  22. data/app/views/iro/positions/_header_short_credit_call_spread.haml +50 -0
  23. data/app/views/iro/positions/_new.haml +23 -0
  24. data/app/views/iro/positions/_prepare_short_credit_call_spread.haml +1 -0
  25. data/app/views/iro/purses/_form_extra_fields.haml +18 -22
  26. data/app/views/iro/purses/_header.haml +8 -17
  27. data/app/views/iro/purses/show.haml +3 -2
  28. data/app/views/iro/stocks/_form.haml +4 -3
  29. data/app/views/iro/stocks/edit.haml +4 -0
  30. data/app/views/iro/stocks/index.haml +21 -6
  31. data/app/views/iro/stocks/show.haml +5 -0
  32. data/app/views/iro/strategies/_form.haml +14 -11
  33. data/app/views/iro/strategies/_show.haml +1 -1
  34. data/config/routes.rb +2 -1
  35. data/lib/iro/engine.rb +1 -0
  36. data/lib/iron_warbler.rb +0 -2
  37. data/lib/tasks/iro_tasks.rake +2 -2
  38. metadata +13 -4
  39. data/app/views/iro/api/stocks/show.jbuilder +0 -11
@@ -8,56 +8,74 @@ class Iro::Strategy
8
8
  field :slug
9
9
  validates :slug, presence: true, uniqueness: true
10
10
 
11
- LONG = 'is_long'
11
+ field :description
12
+
13
+ LONG = 'is_long'
12
14
  SHORT = 'is_short'
13
15
  field :long_or_short, type: :string
14
16
  validates :long_or_short, presence: true
15
17
 
16
- field :description
17
-
18
- has_many :positions, class_name: 'Iro::Position', inverse_of: :strategy
19
18
 
19
+ has_many :positions, class_name: 'Iro::Position', inverse_of: :strategy
20
+ has_one :next_position, class_name: 'Iro::Position', inverse_of: :next_strategy
20
21
  belongs_to :stock, class_name: 'Iro::Stock', inverse_of: :strategies
21
22
  has_and_belongs_to_many :purses, class_name: 'Iro::Purse', inverse_of: :strategies
22
23
 
23
- KIND_COVERED_CALL = 'covered_call'
24
- KIND_LONG_DEBIT_CALL_SPREAD = 'long_debit_call_spread'
25
- KIND_SHORT_DEBIT_PUT_SPREAD = 'short_debit_put_spread'
24
+ KIND_COVERED_CALL = 'covered_call'
25
+ KIND_IRON_CONDOR = 'iron_condor'
26
+ KIND_LONG_CREDIT_PUT_SPREAD = 'long_credit_put_spread'
27
+ KIND_LONG_DEBIT_CALL_SPREAD = 'long_debit_call_spread'
28
+ KIND_SHORT_CREDIT_CALL_SPREAD = 'short_credit_call_spread'
29
+ KIND_SHORT_DEBIT_PUT_SPREAD = 'short_debit_put_spread'
26
30
  KINDS = [ nil,
27
31
  KIND_COVERED_CALL,
32
+ KIND_IRON_CONDOR,
33
+ KIND_LONG_CREDIT_PUT_SPREAD,
28
34
  KIND_LONG_DEBIT_CALL_SPREAD,
35
+ KIND_SHORT_CREDIT_CALL_SPREAD,
29
36
  KIND_SHORT_DEBIT_PUT_SPREAD,
30
37
  ]
31
38
  field :kind
32
39
 
33
- def kind_short
40
+ def put_call
34
41
  case kind
35
- when KIND_COVERED_CALL
36
- 'cc'
37
- when KIND_LONG_DEBIT_CALL_SPREAD
38
- 'long-spread'
39
- when KIND_SHORT_DEBIT_PUT_SPREAD
40
- 'short-spread'
41
- else
42
- '@TODO-zez'
42
+ when Iro::Strategy::KIND_LONG_DEBIT_CALL_SPREAD
43
+ put_call = 'CALL'
44
+ when Iro::Strategy::KIND_SHORT_CREDIT_CALL_SPREAD
45
+ put_call = 'CALL'
46
+ when Iro::Strategy::KIND_SHORT_DEBIT_PUT_SPREAD
47
+ put_call = 'PUT'
48
+ when Iro::Strategy::KIND_COVERED_CALL
49
+ put_call = 'CALL'
43
50
  end
44
51
  end
45
52
 
46
- field :buffer_above_water, type: :float
47
- field :threshold_delta, type: :float
48
- field :threshold_netp, type: :float
49
- field :min_dte, type: :integer, default: 0
53
+ field :threshold_buffer_above_water, type: :float
54
+ field :threshold_delta, type: :float
55
+ field :threshold_netp, type: :float
56
+ field :threshold_dte, type: :integer, default: 1
50
57
 
51
- field :next_inner_delta, type: :float
52
- field :next_outer_delta, type: :float
53
- field :next_inner_strike, type: :float
54
- field :next_outer_strike, type: :float
55
- field :next_spread_amount, type: :float # e.g. $20 for a $2000 NVDA spread
58
+ field :next_inner_delta, type: :float
59
+ field :next_inner_strike, type: :float
60
+ field :next_outer_delta, type: :float
61
+ field :next_outer_strike, type: :float
62
+ field :next_spread_amount, type: :float # e.g. $20 for a $2000 NVDA spread
56
63
  field :next_buffer_above_water, type: :float
57
64
 
58
- def self.for_ticker ticker
59
- where( ticker: ticker )
65
+
66
+
67
+
68
+
69
+
70
+ def begin_delta_covered_call p
71
+ p.inner.begin_delta
60
72
  end
73
+ def begin_delta_long_debit_call_spread p
74
+ p.outer.begin_delta - p.inner.begin_delta
75
+ end
76
+ alias_method :begin_delta_short_debit_put_spread, :begin_delta_long_debit_call_spread
77
+ alias_method :begin_delta_short_credit_call_spread, :begin_delta_long_debit_call_spread
78
+
61
79
 
62
80
  def breakeven_covered_call p
63
81
  p.inner.strike + p.inner.begin_price
@@ -67,27 +85,32 @@ class Iro::Strategy
67
85
  end
68
86
  alias_method :breakeven_short_debit_put_spread, :breakeven_long_debit_call_spread
69
87
 
88
+
89
+ def end_delta_covered_call p
90
+ p.inner.end_delta
91
+ end
92
+ def end_delta_long_debit_call_spread p
93
+ p.outer.end_delta - p.inner.end_delta
94
+ end
95
+ alias_method :end_delta_short_debit_put_spread, :end_delta_long_debit_call_spread
96
+ alias_method :end_delta_short_credit_call_spread, :end_delta_long_debit_call_spread
97
+
98
+
70
99
  def max_gain_covered_call p
71
100
  p.inner.begin_price * 100 - 0.66 # @TODO: is this *100 really?
72
101
  end
73
102
  def max_gain_long_debit_call_spread p
74
- ## 100 * disalloed for gameui
103
+ ## 100 * disallowed for gameui
75
104
  ( p.inner.strike - p.outer.strike - p.outer.begin_price + p.inner.begin_price ) # - 2*0.66
76
105
  end
106
+ def max_gain_short_credit_call_spread p
107
+ p.inner.begin_price - p.outer.begin_price
108
+ end
77
109
  def max_gain_short_debit_put_spread p
78
- ## 100 * disalloed for gameui
110
+ ## 100 * disallowed for gameui
79
111
  ( p.outer.strike - p.inner.strike - p.outer.begin_price + p.inner.begin_price ) # - 2*0.66
80
112
  end
81
113
 
82
- def net_amount_covered_call p
83
- ( p.inner.begin_price - p.inner.end_price )
84
- end
85
- def net_amount_long_debit_call_spread p
86
- outer = p.outer.end_price - p.outer.begin_price
87
- inner = p.inner.begin_price - p.inner.end_price
88
- out = ( outer + inner )
89
- end
90
- alias_method :net_amount_short_debit_put_spread, :net_amount_long_debit_call_spread
91
114
 
92
115
  def max_loss_covered_call p
93
116
  p.inner.begin_price*10 # just suppose 10,000%
@@ -98,22 +121,31 @@ class Iro::Strategy
98
121
  def max_loss_short_debit_put_spread p # different
99
122
  out = p.inner.strike - p.outer.strike
100
123
  end
124
+ def max_loss_short_credit_call_spread p
125
+ out = p.outer.strike - p.inner.strike
126
+ end
101
127
 
102
- def begin_delta_covered_call p
103
- p.inner.begin_delta
128
+
129
+ def net_amount_covered_call p
130
+ ( p.inner.begin_price - p.inner.end_price )
104
131
  end
105
- def begin_delta_long_debit_call_spread p
106
- p.outer.begin_delta - p.inner.begin_delta
132
+ def net_amount_long_debit_call_spread p
133
+ outer = p.outer.end_price - p.outer.begin_price
134
+ inner = p.inner.begin_price - p.inner.end_price
135
+ out = ( outer + inner )
107
136
  end
108
- alias_method :begin_delta_short_debit_put_spread, :begin_delta_long_debit_call_spread
137
+ alias_method :net_amount_short_credit_call_spread , :net_amount_long_debit_call_spread
138
+ alias_method :net_amount_short_debit_put_spread, :net_amount_long_debit_call_spread
109
139
 
110
- def end_delta_covered_call p
111
- p.inner.end_delta
112
- end
113
- def end_delta_long_debit_call_spread p
114
- p.outer.end_delta - p.inner.end_delta
140
+
141
+ ## 2024-05-09 @TODO
142
+ def next_inner_strike_on expires_on
143
+ outs = Tda::Option.get_quotes({
144
+ contractType: put_call,
145
+ expirationDate: expires_on,
146
+ ticker: stock.ticker,
147
+ })
115
148
  end
116
- alias_method :end_delta_short_debit_put_spread, :end_delta_long_debit_call_spread
117
149
 
118
150
 
119
151
 
@@ -196,10 +228,15 @@ class Iro::Strategy
196
228
  end
197
229
 
198
230
 
231
+ ## scopes
232
+
233
+ def self.for_ticker ticker
234
+ where( ticker: ticker )
235
+ end
199
236
 
200
237
 
201
238
  def to_s
202
- "#{stock} #{kind_short} #{slug}"
239
+ slug
203
240
  end
204
241
  def self.list long_or_short = nil
205
242
  these = long_or_short ? where( long_or_short: long_or_short ) : all
@@ -4,7 +4,8 @@ require 'httparty'
4
4
  class Tda::Option
5
5
 
6
6
  include ::HTTParty
7
- base_uri 'https://api.tdameritrade.com'
7
+ # base_uri 'https://api.tdameritrade.com'
8
+ base_uri 'https://api.schwabapi.com/marketdata/v1'
8
9
 
9
10
 
10
11
  ##
@@ -68,7 +69,7 @@ class Tda::Option
68
69
  ## 2023-02-06 _vp_ :: Continue.
69
70
  ##
70
71
  def self.get_quotes params
71
- # puts! params, 'Tda::Option#get_quotes'
72
+ puts! params, 'Tda::Option#get_quotes'
72
73
  opts = {}
73
74
 
74
75
  #
@@ -100,8 +101,13 @@ class Tda::Option
100
101
  query = { apikey: ::TD_AMERITRADE[:apiKey] }.merge opts
101
102
  # puts! query, 'input opts'
102
103
 
103
- path = "/v1/marketdata/chains"
104
- out = self.get path, { query: query }
104
+ headers = {
105
+ Authorize: "Bearer #{::TD_AMERITRADE[:access_token]}",
106
+ }
107
+
108
+
109
+ path = "/chains"
110
+ out = self.get path, { headers: headers, query: query }
105
111
  timestamp = DateTime.parse out.headers['date']
106
112
  ## out = HTTParty.get "https://api.tdameritrade.com#{path}", { query: query }
107
113
  out = out.parsed_response.deep_symbolize_keys
@@ -3,7 +3,7 @@ require 'httparty'
3
3
 
4
4
  class Tda::Stock
5
5
  include ::HTTParty
6
- base_uri 'https://api.tdameritrade.com'
6
+ base_uri 'https://api.schwabapi.com/marketdata/v1'
7
7
 
8
8
  ## alias
9
9
  def self.get_quote which
@@ -13,9 +13,15 @@ class Tda::Stock
13
13
  ## tickers = "GME"
14
14
  ## tickers = "NVDA,GME"
15
15
  def self.get_quotes tickers
16
- path = "/v1/marketdata/quotes"
17
- inns = self.get path, { query: { apikey: ::TD_AMERITRADE[:apiKey], symbol: tickers } }
16
+ path = "/quotes"
17
+ headers = {
18
+ accept: 'application/json',
19
+ Authorization: "Bearer #{::SCHWAB_DATA[:access_token]}",
20
+ }
21
+ inns = self.get path, { headers: headers, query: { symbols: tickers } }
18
22
  inns = inns.parsed_response
23
+ # puts! inns, 'parsed response'
24
+
19
25
  if [ NilClass, String ].include?( inns.class )
20
26
  return []
21
27
  end
@@ -23,8 +29,9 @@ class Tda::Stock
23
29
  inns[k] = v.deep_symbolize_keys
24
30
  end
25
31
  outs = []
26
- inns.each do |symbol, obj|
27
- outs.push ::Iro::PriceItem.create!({
32
+ inns.each do |symbol, _obj|
33
+ obj = _obj[:quote]
34
+ outs.push ::Iro::Priceitem.create!({
28
35
  putCall: 'STOCK',
29
36
  symbol: symbol,
30
37
  ticker: symbol,
@@ -37,8 +44,7 @@ class Tda::Stock
37
44
  closePrice: obj[:closePrice],
38
45
  highPrice: obj[:highPrice],
39
46
  lowPrice: obj[:lowPrice],
40
- quoteTimeInLong: obj[:quoteTimeInLong],
41
- timestamp: Time.at( obj[:quoteTimeInLong]/1000 ),
47
+ timestamp: Time.at( obj[:quoteTime]/1000 ),
42
48
  totalVolume: obj[:totalVolume],
43
49
  mark: obj[:mark],
44
50
  exchangeName: obj[:exchangeName],
@@ -4,9 +4,9 @@
4
4
 
5
5
  %i.fa.fa-compress.collapse-expand#collapseHeaderTrading
6
6
  Wco Trading
7
- .a
8
- .d-flex
9
- %ul{ style: "margin-top: 2em;" }
7
+ .W
8
+ .d-flex.flex-wrap
9
+ %ul
10
10
  %li
11
11
  = link_to "Stocks (#{Iro::Stock.all.length})", stocks_path
12
12
  = link_to '[sync]', sync_stocks_path
@@ -26,6 +26,7 @@
26
26
  %li
27
27
  = link_to p, purse_path(p)
28
28
  = link_to '[ui]', purse_gameui_path(p)
29
+
29
30
  .a
30
31
  = link_to 'Strategies', strategies_path
31
32
  %ul
@@ -0,0 +1,5 @@
1
+
2
+ json.stocks @stocks do |stock|
3
+ json.status stock.status
4
+ json.ticker stock.ticker
5
+ end
@@ -0,0 +1,11 @@
1
+
2
+ json.ticker @stock.ticker
3
+ json.last @stock.last
4
+
5
+ json.datapoints @datapoints do |p|
6
+ json.quote_at Time.at(p.quote_at).strftime('%Y-%m-%d')
7
+ # json.timestamp p.timestamp
8
+ json.value p.value
9
+ end
10
+
11
+
@@ -0,0 +1,12 @@
1
+
2
+ json.priceitems do
3
+ json.array! @datapoints do |p|
4
+ json.date p[:quote_at].in_time_zone('UTC').to_date
5
+ json.quote_at p[:quote_at]
6
+ json.open p[:open]
7
+ json.high p[:high]
8
+ json.low p[:low]
9
+ json.close p[:value]
10
+ json.volume p[:volume]
11
+ end
12
+ end
@@ -1,5 +1,7 @@
1
1
 
2
- .positions--form{ class: params[:long_or_short] || position.strategy&.long_or_short }
2
+ - long_or_short = position.long_or_short || position.strategy&.long_or_short || params[:long_or_short]
3
+
4
+ .positions--form{ class: params[:long_or_short] || long_or_short }
3
5
  = form_for position do |f|
4
6
  .actions
5
7
  = f.submit
@@ -18,7 +20,7 @@
18
20
 
19
21
  .field
20
22
  %label long or short?
21
- = f.select :long_or_short, options_for_select([nil, Iro::Strategy::LONG, Iro::Strategy::SHORT], selected: position.long_or_short || params[:long_or_short] )
23
+ = f.select :long_or_short, options_for_select([nil, Iro::Strategy::LONG, Iro::Strategy::SHORT], selected: long_or_short )
22
24
 
23
25
  %label Strategy
24
26
  = f.select :strategy_id, options_for_select( @strategies_list, selected: position.strategy_id )
@@ -0,0 +1,38 @@
1
+
2
+ - pos = position
3
+ - stock = pos.stock
4
+ - nearest_strike = stock.last.round
5
+ - u = pos.purse.unit # pixels per dollar
6
+
7
+ .collapse-expand.d-flex{ id: "gameui-pos-#{pos.id}" }
8
+ [<>]
9
+ .maxwidth= render "/iro/positions/header", pos: pos
10
+ .a
11
+ = render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
12
+ .StockCoordinatesW
13
+ .StockCoordinates{ style: "height: #{pos.q() *pos.purse.height}px " }
14
+ .grid= render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock, position: pos
15
+
16
+ .Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
17
+ .label Last: #{pp_amount stock.last}
18
+ .c
19
+
20
+ - left = "#{ ( pos.outer.strike - stock.last ).abs() *-1*u}px"
21
+ - width = "#{ ( pos.inner.strike - pos.outer.strike ).abs() *u}px"
22
+ .PositionW{ class: pos.strategy.kind, style: "left: #{left}; width: #{width}; " }
23
+ .Position
24
+ .MaxGain{ style: "width: #{pos.max_gain * u}px" }
25
+ .RollGuide
26
+
27
+ - if pos.net_amount >= 0
28
+ .Net.NetPositive{ style: "width: #{ (pos.net_amount) * u }px; right: 0" }
29
+ .label
30
+ net
31
+ = pp_amount pos.net_amount
32
+ - else
33
+ .Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount) * u }px; left: 100%" }
34
+ .label
35
+ net
36
+ = pp_amount pos.net_amount
37
+ .c
38
+
@@ -0,0 +1,50 @@
1
+
2
+ -##
3
+ -## Same file for the spreads
4
+ -##
5
+
6
+ - collapse_key ||= pos.id
7
+ %i.fa.fa-expand.collapse-expand.floaty-collapse{ id: "gameui-pos-detail-#{collapse_key}" }
8
+ .maxwidth
9
+
10
+ %table.bordered{ class: pos.long_or_short }
11
+ %tbody.long-or-short-item
12
+ %tr
13
+ %td <b>#{pp_amount pos.outer.strike}</b>
14
+ %td= pp_amount pos.outer.begin_price
15
+ %td= pos.outer.begin_delta
16
+ %td &nbsp;-&nbsp;
17
+ %td= pp_amount pos.outer.end_price
18
+ %td= pp_delta pos.outer.end_delta
19
+ %tr
20
+ %td <b>#{pp_amount pos.inner.strike}</b>
21
+ %td= pp_amount pos.inner.begin_price
22
+ %td= pp_delta pos.inner.begin_delta
23
+ %td &nbsp;-&nbsp;
24
+ %td= pp_amount pos.inner.end_price
25
+ %td= pp_delta pos.inner.end_delta
26
+
27
+ .header.d-flex
28
+ %ul.mb-0
29
+ %li
30
+ -## yes *100
31
+ <b>max gain:</b> #{pp_amount pos.max_gain} :: #{pp_amount pos.max_gain * 100 * pos.q}
32
+ -# %li
33
+ -# <b>end_outer,inner_price:</b> #{pp_amount pos.end_outer_price} -> #{pp_amount pos.end_inner_price}
34
+ -# &nbsp;&nbsp;
35
+ -# -## yes *100
36
+ -# <b>max loss:</b> #{pp_amount pos.max_loss} :: #{pp_amount pos.max_loss * 100 * pos.q}
37
+
38
+ %li
39
+ <b>Exposure:</b> #{pp_amount pos.max_loss() *100*pos.q()}
40
+ %li
41
+ <b>Breakeven:</b> #{pp_amount pos.inner.strike + pos.max_gain()}
42
+ - ## no *100
43
+ %li <b>Net:</b> #{pp_amount pos.net_amount} :: #{pp_amount pos.net_amount() *100*pos.q} &nbsp;&nbsp; <i>#{pp_percent pos.net_percent}</i>
44
+
45
+ - if 'prepare' == pos.status
46
+ %ul.mb-0
47
+ %li
48
+ <b>next_gain_loss_amount:</b> #{pp_amount pos.next_gain_loss_amount}
49
+ \:: #{pp_amount pos.next_gain_loss_amount * 100 * pos.q}
50
+ &nbsp;&nbsp; <i>#{pp_percent pos.next_gain_loss_amount/pos.max_loss*-1}</i>
@@ -0,0 +1,23 @@
1
+
2
+ .d-flex
3
+ .Card
4
+ = form_for Iro::Position.new(strategy: Iro::Strategy.new), url: new_position_path, method: :get do |f|
5
+ = hidden_field_tag 'position[purse_id]', purse.id
6
+
7
+ .formrow-v1
8
+ .label +Position
9
+
10
+ .d-flex.flex-column
11
+ %label Strategy
12
+ = f.select :strategy_id, options_for_select(@strategies_list)
13
+
14
+ .d-flex.flex-column
15
+ %label Expires on
16
+ = f.select :expires_on, options_for_select( Iro::Option.expirations_list )
17
+
18
+ .d-flex.flex-column
19
+ %label Q
20
+ = f.text_field :quantity, class: 'w-3em'
21
+
22
+ = f.submit '>'
23
+
@@ -0,0 +1 @@
1
+ app/views/iro/positions/_prepare_short_debit_put_spread.haml
@@ -1,30 +1,26 @@
1
1
 
2
- .d-flex.flex-wrap
3
- %label unit
4
- = f.number_field :unit
5
- px/usd
6
- &nbsp;&nbsp;
7
- %label height
8
- = f.number_field :height
9
- px/q
10
- &nbsp;&nbsp;
2
+ .purses--form-extra-fields
11
3
 
12
- %label summary_unit
13
- = f.number_field :summary_unit, step: 0.000001, style: "width: 120px"
14
- px/usd
15
- &nbsp;&nbsp;
4
+ .d-flex.flex-wrap
5
+ %label unit
6
+ = f.number_field :unit
7
+ .unit px/usd
16
8
 
9
+ %label height
10
+ = f.number_field :height
11
+ .unit px/q
17
12
 
13
+ %label summary_unit
14
+ = f.number_field :summary_unit, step: 0.000001
15
+ .unit px/usd
18
16
 
19
- %label mark_every_n_usd
20
- = f.number_field :mark_every_n_usd, step: 0.01
21
- &nbsp;&nbsp;
17
+ .d-flex.flex-wrap
18
+ %label mark_every_n_usd
19
+ = f.number_field :mark_every_n_usd, step: 0.01
20
+ .unit
22
21
 
23
- %label n_next_positions
24
- = f.number_field :n_next_positions
25
- &nbsp;&nbsp;
26
-
27
-
28
- &nbsp;&nbsp;
22
+ %label n_next_positions
23
+ = f.number_field :n_next_positions
24
+ .unit
29
25
 
30
26
 
@@ -4,30 +4,21 @@
4
4
  .header
5
5
  %h5.title
6
6
  Purse `#{purse.slug}`
7
+ -# (#{purse.positions.length})
8
+ &nbsp;
7
9
  = link_to '[~]', edit_purse_path(purse)
8
10
  = link_to '[table]', purse_path(purse)
9
11
  = link_to '[gameUI]', purse_gameui_path(purse)
10
- (#{purse.positions.length})
11
12
 
12
- .d-flex
13
+ %ul
14
+ %li <b>Total:</b> #{pp_amount purse.balance}
15
+ %li <b>Available:</b> #{pp_amount purse.available}
13
16
 
14
- .Card.d-flex
15
- = form_for Iro::Position.new(strategy: Iro::Strategy.new), url: new_position_path, method: :get do |f|
16
- .a +Position
17
- = hidden_field_tag 'position[purse_id]', purse.id
18
- .field
19
- = f.select :strategy_id, options_for_select(@strategies_list)
20
- -# .field
21
- -# = f.radio_button :long_or_short, :long
22
- -# %label long
23
- -# = f.radio_button :long_or_short, :short
24
- -# %label short
25
- = f.submit 'Go'
26
- -# = link_to '[+position]', new_position_path({ purse_id: purse.id })
27
- -# = link_to '[+short]', new_position_path({ purse_id: purse.id, long_or_short: Iro::Strategy::SHORT })
28
17
 
18
+ = render '/iro/positions/new', purse: purse
29
19
 
30
- - if true || params[:template] == 'gameui'
20
+
21
+ - if true # params[:template] == 'gameui'
31
22
  .mini-inputs
32
23
  = form_for purse, html: { class: 'd-flex' } do |f|
33
24
  = render '/iro/purses/form_extra_fields', f: f
@@ -1,8 +1,9 @@
1
1
 
2
2
  .purses-show.padded
3
- .row
4
- .col-md-6
3
+ .row.no-gutters
4
+ .col-md-6.pr-3
5
5
  = render '/iro/purses/header', purse: @purse
6
6
  .col-md-6
7
7
  = render '/iro/purses/summary', purse: @purse, collapse_key: 'views-show'
8
+
8
9
  = render '/iro/positions/table', positions: @positions
@@ -7,14 +7,15 @@
7
7
  - if stock.new_record?
8
8
  %label New
9
9
  - else
10
+ %label status
10
11
  = f.select :status, options_for_select([ Iro::Stock::STATUS_ACTIVE, Iro::Stock::STATUS_INACTIVE ], selected: stock.status)
11
12
  .field
12
13
  = f.label :ticker
13
14
  = f.text_field :ticker
14
15
 
15
- .field
16
- %label Last
17
- = f.number_field :last, placeholder: '80.0', step: 0.01
16
+ -# .field
17
+ -# %label Last
18
+ -# = f.number_field :last, placeholder: '80.0', step: 0.01
18
19
 
19
20
  .field
20
21
  %label options price increment
@@ -0,0 +1,4 @@
1
+
2
+ .stocks-edit.maxwidth
3
+
4
+ = render 'form', stock: @stock
@@ -1,10 +1,25 @@
1
1
 
2
- .stocks--index.padded
2
+ .stocks-index.maxwidth
3
3
  .maxwidth
4
4
  %h5 Stocks
5
5
 
6
- %ul
7
- - @stocks.each do |stock|
8
- %li
9
- = render 'iro/stocks/form', stock: stock
10
- %li= render 'iro/stocks/form', stock: Iro::Stock.new
6
+ %table.bordered.padded
7
+ %thead
8
+ %tr
9
+ %td Ticker
10
+ %td last price
11
+ %td n priceitems
12
+ %tbody
13
+ - @stocks.each do |stock|
14
+ %tr
15
+ %td
16
+ = link_to '[~]', edit_stock_path(stock)
17
+ = link_to '[api]', stock_path(stock, format: :json)
18
+ <b>#{stock.ticker}</b>
19
+ %td
20
+ #{pp_amount stock.last}
21
+ %td
22
+ = stock.priceitems.length
23
+
24
+ %hr
25
+ = render 'iro/stocks/form', stock: Iro::Stock.new
@@ -0,0 +1,5 @@
1
+
2
+ .stocks-show.maxwidth
3
+ %h4= @stock
4
+
5
+ %h5 Max Pain