iron_warbler 2.0.7.19 → 2.0.7.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascript/iron_warbler/application.js +2 -0
  3. data/app/assets/javascript/iron_warbler/gameui.js +9 -0
  4. data/app/assets/stylesheets/iron_warbler/application.css +13 -3
  5. data/app/assets/stylesheets/iron_warbler/positions.scss +9 -1
  6. data/app/assets/stylesheets/iron_warbler/purses_gameui.scss +191 -0
  7. data/app/assets/stylesheets/iron_warbler/purses_gameui.scss-bk +112 -0
  8. data/app/assets/stylesheets/iron_warbler/utils.scss +82 -0
  9. data/app/controllers/iro/api/stocks_controller.rb +87 -0
  10. data/app/controllers/iro/api_controller.rb +19 -0
  11. data/app/controllers/iro/positions_controller.rb +16 -4
  12. data/app/controllers/iro/purses_controller.rb +8 -3
  13. data/app/controllers/iro/strategies_controller.rb +7 -7
  14. data/app/helpers/iro/application_helper.rb +5 -2
  15. data/app/models/iro/datapoint.rb +48 -8
  16. data/app/models/iro/position.rb +55 -14
  17. data/app/models/iro/position_covered_call.rb +4 -0
  18. data/app/models/iro/position_debit_spread.rb +251 -0
  19. data/app/models/iro/price_item.rb +51 -1
  20. data/app/models/iro/stock.rb +5 -2
  21. data/app/models/iro/strategy.rb +76 -10
  22. data/app/views/iro/_main_header.haml +18 -17
  23. data/app/views/iro/api/stocks/show.jbuilder +11 -0
  24. data/app/views/iro/positions/_form.haml +11 -38
  25. data/app/views/iro/positions/_formpart_4data.haml +46 -0
  26. data/app/views/iro/positions/_gameui_covered_call.haml +36 -0
  27. data/app/views/iro/positions/_gameui_covered_call.haml-bk +59 -0
  28. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +37 -0
  29. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +39 -0
  30. data/app/views/iro/positions/_header.haml +6 -0
  31. data/app/views/iro/positions/_header_covered_call.haml +6 -0
  32. data/app/views/iro/positions/_header_long_debit_call_spread.haml +14 -0
  33. data/app/views/iro/positions/_header_short_debit_put_spread.haml +1 -0
  34. data/app/views/iro/positions/_table.haml +118 -123
  35. data/app/views/iro/positions/roll.haml +83 -0
  36. data/app/views/iro/positions/trash/_header_short_debit_put_spread.haml +9 -0
  37. data/app/views/iro/purses/_header.haml +18 -0
  38. data/app/views/iro/purses/gameui.haml +18 -0
  39. data/app/views/iro/purses/gameui.haml-bk +44 -0
  40. data/app/views/iro/purses/gameui.haml-bk2 +89 -0
  41. data/app/views/iro/purses/show.haml +1 -7
  42. data/app/views/iro/stocks/_grid_is_long.haml +13 -0
  43. data/app/views/iro/stocks/_grid_is_short.haml +13 -0
  44. data/app/views/iro/strategies/_form.haml +12 -5
  45. data/app/views/iro/strategies/_show.haml +3 -2
  46. data/app/views/iro/strategies/_table.haml +16 -10
  47. data/app/views/iro/strategies/index.haml +8 -0
  48. data/app/views/layouts/iro/application.haml +1 -1
  49. data/config/routes.rb +14 -1
  50. data/lib/tasks/db_tasks.rake +9 -3
  51. metadata +29 -8
  52. data/app/assets/stylesheets/iron_warbler/alerts.css +0 -8
  53. data/app/assets/stylesheets/iron_warbler/datapoints.css +0 -0
  54. data/app/assets/stylesheets/iron_warbler/profiles.css +0 -4
  55. data/app/assets/stylesheets/iron_warbler/strategies.scss +0 -0
  56. data/app/assets/stylesheets/iron_warbler/utils.css +0 -44
  57. data/app/jobs/iro/application_job.rb-trash +0 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3323961dddbc46a423f2f913a487c0944d1a39c88ace9517f42b02eb7e4951a9
4
- data.tar.gz: 2f28158b88fe50b7d190c5151da808819c816de9abf773c70063e39b8ed6a8da
3
+ metadata.gz: 0deda82521a6d2995c6cf495e7276550ce2d9f12541b829dbc903c0c1d64050c
4
+ data.tar.gz: 8742db15fd84ccd0f344f194380b4074d9b615dc9b95b1f88ddf41504601408c
5
5
  SHA512:
6
- metadata.gz: 509add67004fa9cda9757fc71bd3319db109acb0cb981a4ac265dc5777f39680bbcfb265a0685f357b0b073604087df756c084b98d333f0c21616d535d205a62
7
- data.tar.gz: f1b24ce8505853cbc1723b5117ff3a3c79f85bf793f2f8aa00f7bdd4d57ae47e2a9014f0739920609595c16376b2b7c2e0b4a1c13822f4477455fec68aa55d74
6
+ metadata.gz: ae6c37ed5e85029f73f1fefcb825020e8da3ab4e69e7e85ae16bdfa29ba62673bb3a32f75124026fba0e6155423cbc5fd0cc3695a7c994bf6662d6287b7f4c69
7
+ data.tar.gz: 4bbb876537fb451b1734fd3b0a431de13ff03e8cff9eeed75851b19048580091dbb16ef2376dee6ee9ddd9df65d8bee9b2d50a15e8b0afaa9403323f306a8de1
@@ -1,3 +1,5 @@
1
1
 
2
+ //= require ./gameui
3
+
2
4
  // console.log('Loaded iron_warbler/application.js')
3
5
 
@@ -0,0 +1,9 @@
1
+
2
+ $(function() {
3
+
4
+ const tmp = $('.purses-gameuiW').attr('data-margin-left')
5
+ logg(tmp, 'tmp')
6
+
7
+ $('.purses-gameuiW').scrollLeft( tmp );
8
+
9
+ }); // END
@@ -12,8 +12,18 @@
12
12
  *
13
13
  *= require_tree .
14
14
  *= require_self
15
- */
15
+ **/
16
16
 
17
- body {
18
- colod: red !important;
17
+ html {
18
+ --iro-color-long: lightseagreen;
19
+ --iro-color-short: orange;
20
+
21
+ --iro-color-grid1: #ccc;
22
+ --iro-color-grid2: #999;
23
+ --iro-color-bg1: #efefef;
24
+ --iro-color-bg2: #fefefe;
19
25
  }
26
+
27
+ /* body {
28
+ color: red !important;
29
+ } */
@@ -15,7 +15,7 @@
15
15
  border: 1px solid red;
16
16
 
17
17
  > * {
18
- border: 1px solid yellow;
18
+ // border: 1px solid yellow;
19
19
  // background: #ddd;
20
20
 
21
21
  transform-origin: 0 0;
@@ -43,5 +43,13 @@
43
43
  th.next_symbol {
44
44
  width: 120px;
45
45
  }
46
+
47
+ tr.is_long {
48
+ border-left: 5px solid var(--iro-color-long);
49
+ }
50
+ tr.is_short {
51
+ border-left: 5px solid var(--iro-color-short);
52
+ }
53
+
46
54
  }
47
55
  }
@@ -0,0 +1,191 @@
1
+
2
+ .purses-gameuiW {
3
+ border: 1px solid red;
4
+ width: 100%;
5
+ overflow: scroll;
6
+ }
7
+
8
+ .purses-gameui {
9
+
10
+ .Origin::before {
11
+ position: absolute;
12
+ top: -1em;
13
+ content: "";
14
+ margin-left: -1em;
15
+ border: 1em solid transparent;
16
+ border-top: 1em solid black;
17
+ }
18
+ .Origin {
19
+ position: absolute;
20
+ top: 0;
21
+ // background: rgba(255,255,0, 0.5);
22
+ height: 100%;
23
+ width: 100%;
24
+
25
+ > .label {
26
+ width: 300px;
27
+
28
+ position: absolute;
29
+ top: -1.5em;
30
+ left: 1.2em;
31
+ z-index: 2;
32
+ }
33
+ }
34
+ .PositionW {
35
+ top: 0;
36
+ border: 2px solid black;
37
+ background: rgba(0,255,255, 0.25);
38
+ position: absolute;
39
+ height: 100%;
40
+ }
41
+ .reviewing {
42
+ .PositionW {
43
+ border-radius: 10px 10px 0 0;
44
+ height: 90%;
45
+ }
46
+ }
47
+
48
+ .Position {
49
+ position: absolute;
50
+ background: rgba(0,255,255, 0.25);
51
+ width: 100%;
52
+ height: 90%;
53
+
54
+ left: 0;
55
+ top: 0;
56
+
57
+ }
58
+
59
+ .MaxGain {
60
+ position: absolute;
61
+ right: 0;
62
+ bottom: -10%;
63
+ border: 2px solid green;
64
+ background: rgba(0,255,0, 0.5);
65
+ height: 10%;
66
+ }
67
+
68
+ .sprite {
69
+ position: absolute;
70
+ }
71
+ .sprite-bottom {
72
+ bottom: 0;
73
+ }
74
+
75
+ .StockCoordinatesW {
76
+ // width: 500px;
77
+
78
+ // background: var(--iro-color-bg2);
79
+ // border: 1px solid red;
80
+ margin-bottom: 2em;
81
+
82
+ position: relative;
83
+
84
+ z-index: 1;
85
+ }
86
+ .StockCoordinates {
87
+ border-left: 1px solid var(--iro-color-grid1);
88
+ border-bottom: 1px solid var(--iro-color-grid1);
89
+
90
+ height: 50px;
91
+
92
+ margin-left: 50%;
93
+ margin-bottom: 0em;
94
+
95
+ position: relative;
96
+
97
+ .Breakeven {
98
+ // background: cyan;
99
+ border-right: 2px solid lightblue;
100
+
101
+ .half-circle {
102
+ width: 100%;
103
+ height: 100%; /* as the half of the width */
104
+ background-color: lightblue;
105
+ border-top-left-radius: 100%; /* 100px of height + 10px of border */
106
+ border-top-right-radius: 100%; /* 100px of height + 10px of border */
107
+ // border: 10px solid gray;
108
+ // border-bottom: 0;
109
+ }
110
+ }
111
+
112
+ .Last {
113
+ border-left: 2px dotted red;
114
+ }
115
+ .label {
116
+ width: 200px;
117
+ color: gray;
118
+ }
119
+
120
+ .marker {
121
+ position: absolute;
122
+ height: 100%;
123
+ }
124
+
125
+ .Net {
126
+ position: absolute;
127
+ // bottom: 3em;
128
+ // z-index: 3;
129
+ height: 90%;
130
+
131
+ // border-bottom: 5px solid red;
132
+ .label {
133
+ color: white;
134
+ text-shadow: 1px 1px black;
135
+ }
136
+ }
137
+ .NetPositive {
138
+ border: 2px dashed #339966;
139
+ background: rgba(32,64,96, 0.5);
140
+ }
141
+ .NetNegative {
142
+ background: rgba(255,0,0, 0.75);
143
+ }
144
+
145
+ .grid-mark:nth-child(4n + 1) {
146
+ border: 1px solid red;
147
+ display: none;
148
+ }
149
+ .grid-mark:nth-child(4n) {
150
+ border: 1px solid red;
151
+ display: none;
152
+ }
153
+ .grid-mark:nth-child(6n + 1) {
154
+ border: 1px solid red;
155
+ display: none;
156
+ }
157
+ .grid-mark:nth-child(6n) {
158
+ border: 1px solid red;
159
+ display: none;
160
+ }
161
+ .grid-mark:nth-child(3n + 1) {
162
+ border: 1px solid red;
163
+ display: none;
164
+ }
165
+ .grid-mark:nth-child(3n) {
166
+ border: 1px solid red;
167
+ display: none;
168
+ }
169
+
170
+ .grid-mark {
171
+ height: 100%;
172
+ position: absolute;
173
+ top: 0;
174
+ width: 100px;
175
+ z-index: -2;
176
+ border-left: 1px dashed var(--iro-color-grid1);
177
+
178
+ .label {
179
+ transform: rotate(-30deg);
180
+ font-size: 0.8em;
181
+
182
+ position: absolute;
183
+ // bottom: -1em;
184
+ z-index: 0;
185
+ }
186
+ }
187
+
188
+
189
+ }
190
+
191
+ }
@@ -0,0 +1,112 @@
1
+
2
+ .purses-gameui {
3
+
4
+
5
+ .Origin::before {
6
+ content: "";
7
+ margin-left: -1em;
8
+ border: 1em solid transparent;
9
+ border-top: 1em solid black;
10
+ }
11
+ .Origin {
12
+ position: absolute;
13
+ top: 0;
14
+ left: calc( 50% );
15
+ // z-index: -2;
16
+ }
17
+ .sprite {
18
+ position: absolute;
19
+ }
20
+ .sprite-bottom {
21
+ bottom: 0;
22
+ }
23
+
24
+ .CoordinatesW {
25
+ // width: 500px;
26
+
27
+ background: var(--iro-color-bg2);
28
+ border: 1px solid red;
29
+ margin-bottom: 3em;
30
+
31
+ position: relative;
32
+
33
+ z-index: 1;
34
+ }
35
+ .Coordinates {
36
+ border-left: 1px solid var(--iro-color-grid1);
37
+ border-bottom: 1px solid var(--iro-color-grid1);
38
+
39
+ background: yellow;
40
+
41
+ height: 100px;
42
+
43
+ margin-left: 50%;
44
+
45
+ position: relative;
46
+
47
+ .Breakeven {
48
+ // background: cyan;
49
+ border-right: 2px solid lightblue;
50
+
51
+ .half-circle {
52
+ width: 100%;
53
+ height: 100%; /* as the half of the width */
54
+ background-color: lightblue;
55
+ border-top-left-radius: 100%; /* 100px of height + 10px of border */
56
+ border-top-right-radius: 100%; /* 100px of height + 10px of border */
57
+ // border: 10px solid gray;
58
+ // border-bottom: 0;
59
+ }
60
+ }
61
+
62
+ .Last {
63
+ border-left: 2px dotted red;
64
+ }
65
+ .label {
66
+ width: 200px;
67
+ color: gray;
68
+ }
69
+
70
+ .marker {
71
+ position: absolute;
72
+ height: 100%;
73
+ }
74
+
75
+ .Net {
76
+
77
+ position: absolute;
78
+ bottom: 3em;
79
+ z-index: 3;
80
+
81
+ background: #339966;
82
+ // border-bottom: 5px solid red;
83
+ .label {
84
+ color: white;
85
+ }
86
+ }
87
+
88
+ .grid-mark {
89
+ height: 100%;
90
+ position: absolute;
91
+ top: 0;
92
+ width: 100px;
93
+ z-index: 1;
94
+ border-left: 1px dashed var(--iro-color-grid1);
95
+
96
+ .label {
97
+ position: absolute;
98
+ bottom: -1em;
99
+ z-index: 0;
100
+ }
101
+ }
102
+ .mark0 {
103
+ .label {
104
+ bottom: -2em;
105
+ }
106
+ }
107
+
108
+
109
+
110
+ }
111
+
112
+ }
@@ -0,0 +1,82 @@
1
+
2
+
3
+
4
+ .long-or-short::before {
5
+ // content: '[LONG]';
6
+ }
7
+ .long-or-short-item,
8
+ .long-or-short-container .is_long,
9
+ .long-or-short-container .is_short {
10
+ display: flex;
11
+ flex-direction: column;
12
+ }
13
+
14
+ .long-or-short-container .is_long,
15
+ .is_long .long-or-short-item {
16
+ border-left: 3px solid var(--iro-color-long);
17
+ padding-left: 5px;
18
+ }
19
+ .long-or-short-container .is_short,
20
+ .is_short .long-or-short-item {
21
+ border-left: 3px solid var(--iro-color-short);
22
+ padding-left: 5px;
23
+ }
24
+
25
+ .is_short .long-or-short-item::before {
26
+ // content: '[SHORT]';
27
+ }
28
+ .is_short .long-or-short-item,
29
+ .long-or-short-container .is_short {
30
+ flex-direction: column-reverse;
31
+ }
32
+
33
+ /* F */
34
+
35
+ .flex-row {
36
+ display: flex;
37
+ margin-bottom: 0.4em;
38
+ }
39
+
40
+ .floaty-collapse {
41
+ float: left;
42
+ z-index: 5;
43
+ position: relative;
44
+ background: white;
45
+ }
46
+ .field {
47
+ min-width: 100px;
48
+ margin-right: 1em;
49
+ }
50
+
51
+ /* M */
52
+
53
+ .modal-absolute {
54
+ border: 1px solid green;
55
+ border-radius: 5px;
56
+ box-shadow: 2px 2px;
57
+
58
+ padding: 0.5em;
59
+
60
+ position: absolute;
61
+
62
+ min-width: 200px;
63
+ width: 400px;
64
+
65
+ min-height: 200px;
66
+ height: 300px;
67
+ /* overflow: auto; */
68
+
69
+ background: white;
70
+
71
+ z-index: 2;
72
+
73
+ }
74
+
75
+
76
+
77
+ /* W */
78
+
79
+ .w-min-50px {
80
+ min-width: 50px;
81
+ }
82
+
@@ -0,0 +1,87 @@
1
+
2
+ class Iro::Api::StocksController < Iro::ApiController
3
+ before_action :set_stock, only: [:show, :edit, :update, :destroy]
4
+
5
+ def index
6
+ authorize! :index, Iro::Stock
7
+
8
+ respond_to do |format|
9
+ format.json do
10
+ render
11
+ end
12
+ end
13
+ end
14
+
15
+ def show
16
+ authorize! :show, @stock
17
+ end_on = Time.now.to_date.in_time_zone('UTC')
18
+
19
+ begin_on = params[:begin_on].to_date.in_time_zone('UTC') if params[:begin_on]
20
+ end_on = params[:end_on].to_date.in_time_zone('UTC') if params[:end_on]
21
+
22
+ case params[:period]
23
+ when '1-mo'
24
+ begin_on = ( Time.now - 30.days ).to_date.in_time_zone('UTC')
25
+ # end_on = Time.now.to_date.in_time_zone('UTC')
26
+ when '3-mo'
27
+ begin_on = ( Time.now - 90.days ).to_date.in_time_zone('UTC')
28
+ # end_on = Time.now.to_date.in_time_zone('UTC')
29
+ when '1-yr'
30
+ begin_on = ( Time.now - 1.year ).to_date.in_time_zone('UTC')
31
+ # end_on = Time.now.to_date.in_time_zone('UTC')
32
+ end
33
+
34
+ @datapoints = Iro::Datapoint.where({
35
+ :quote_at.gte => begin_on,
36
+ :quote_at.lte => end_on,
37
+ symbol: params[:ticker],
38
+ }).order_by({ quote_at: :asc })
39
+ end
40
+
41
+ def new
42
+ @stock = Iro::Stock.new
43
+ authorize! :new, @stock
44
+ end
45
+
46
+ def edit
47
+ end
48
+
49
+ def create
50
+ @stock = Iro::Stock.new(stock_params)
51
+ authorize! :create, @stock
52
+
53
+ if @stock.save
54
+ flash_notice @stock
55
+ else
56
+ flash_alert @stock
57
+ end
58
+ redirect_to action: :index
59
+ end
60
+
61
+ def update
62
+ @stock = Iro::Stock.find params[:id]
63
+ authorize! :update, @stock
64
+ if @stock.update(stock_params)
65
+ flash_notice @stock
66
+ else
67
+ flash_alert @stock
68
+ end
69
+ redirect_to request.referrer
70
+ end
71
+
72
+ def destroy
73
+ @stock.destroy
74
+ redirect_to stocks_url, notice: 'Stock was successfully destroyed.'
75
+ end
76
+
77
+ ##
78
+ ## private
79
+ ##
80
+ private
81
+
82
+ def set_stock
83
+ @stock = Iro::Stock.find_by({ ticker: params[:ticker] })
84
+ end
85
+
86
+ end
87
+
@@ -0,0 +1,19 @@
1
+
2
+ class Iro::ApiController < ActionController::Base
3
+ layout false
4
+
5
+ before_action :decode_jwt
6
+
7
+ ##
8
+ ## private
9
+ ##
10
+ private
11
+
12
+ def decode_jwt
13
+ out = JWT.decode params[:jwt_token], nil, false
14
+ email = out[0]['email']
15
+ user = User.find_by({ email: email })
16
+ sign_in user
17
+ end
18
+
19
+ end
@@ -1,6 +1,5 @@
1
1
 
2
2
  class Iro::PositionsController < Iro::ApplicationController
3
-
4
3
  before_action :set_lists
5
4
 
6
5
  def new
@@ -32,8 +31,21 @@ class Iro::PositionsController < Iro::ApplicationController
32
31
  def edit
33
32
  @position = Iro::Position.find params[:id]
34
33
  authorize! :edit, @position
34
+ end
35
+
36
+ def roll
37
+ @position = Iro::Position.find params[:id]
38
+ authorize! :roll, @position
39
+
40
+ stock = @position.stock
35
41
 
36
- @strategies_list = Iro::Strategy.for_ticker( @position.ticker ).list
42
+ @positions = [
43
+ Iro::Position.new({ stock: stock, begin_inner_price: 5.21, inner_strike: 91, expires_on: '2024-04-05', gain_loss_amount: -1.25 }),
44
+ Iro::Position.new({ stock: stock, begin_inner_price: 5.77, inner_strike: 90, expires_on: '2024-04-05', gain_loss_amount: -0.7 }),
45
+ Iro::Position.new({ stock: stock, begin_inner_price: 6.4, inner_strike: 89, expires_on: '2024-04-05', gain_loss_amount: -0.03 }),
46
+ Iro::Position.new({ stock: stock, begin_inner_price: 6.85, inner_strike: 88, expires_on: '2024-04-05', gain_loss_amount: 0.6 }),
47
+ Iro::Position.new({ stock: stock, begin_inner_price: 7.07, inner_strike: 87, expires_on: '2024-04-05', gain_loss_amount: 1.22 }),
48
+ ]
37
49
  end
38
50
 
39
51
  def update
@@ -55,8 +67,8 @@ class Iro::PositionsController < Iro::ApplicationController
55
67
  private
56
68
 
57
69
  def set_lists
58
- @strategies_list = Iro::Strategy.list
59
- @tickers_list = Iro::Stock.tickers_list
70
+ @strategies_list = Iro::Strategy.list(params[:long_or_short])
71
+ @stocks_list = Iro::Stock.list
60
72
  end
61
73
 
62
74
  end
@@ -23,8 +23,6 @@ class Iro::PursesController < Iro::ApplicationController
23
23
  def edit
24
24
  @purse = Iro::Purse.find(params[:id])
25
25
  authorize! :edit, @purse
26
-
27
-
28
26
  end
29
27
 
30
28
  def index
@@ -36,7 +34,14 @@ class Iro::PursesController < Iro::ApplicationController
36
34
  @purse = Iro::Purse.find(params[:id])
37
35
  authorize! :show, @purse
38
36
 
39
- @positions = Iro::Position.all
37
+ @positions = @purse.positions.includes( :strategy
38
+ ).order({ expires_on: :desc })
39
+
40
+ @unit = 12 ## pixels per dollar
41
+ @height = 100 ## pixels
42
+ @grid_size = 75 ## dollars to each side of origin
43
+
44
+ render params[:template]
40
45
  end
41
46
 
42
47
  def update
@@ -3,11 +3,6 @@ class Iro::StrategiesController < Iro::ApplicationController
3
3
 
4
4
  before_action :set_lists
5
5
 
6
- def new
7
- @strategy = Iro::Strategy.new
8
- authorize! :new, @posision
9
- end
10
-
11
6
  def create
12
7
  @strategy = Iro::Strategy.new params[:strategy].permit!
13
8
  authorize! :create, @strategy
@@ -37,7 +32,12 @@ class Iro::StrategiesController < Iro::ApplicationController
37
32
  def index
38
33
  authorize! :index, Iro::Strategy
39
34
  @strategies = Iro::Strategy.all
40
- render '_table'
35
+ # render '_table'
36
+ end
37
+
38
+ def new
39
+ @strategy = Iro::Strategy.new
40
+ authorize! :new, @posision
41
41
  end
42
42
 
43
43
  def update
@@ -60,7 +60,7 @@ class Iro::StrategiesController < Iro::ApplicationController
60
60
 
61
61
  def set_lists
62
62
  @strategies_list = Iro::Strategy.list
63
- @tickers_list = Iro::Stock.tickers_list
63
+ @tickers_list = Iro::Stock.list
64
64
  end
65
65
 
66
66
  end
@@ -1,4 +1,7 @@
1
- module Iro
2
- module ApplicationHelper
1
+ module Iro::ApplicationHelper
2
+
3
+ def pp_delta delta
4
+ '%.2f' % delta rescue '-'
3
5
  end
6
+
4
7
  end