iron_warbler 2.0.7.24 → 2.0.7.26

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/iron_warbler/Card.scss +6 -0
  3. data/app/assets/stylesheets/iron_warbler/positions.scss +1 -1
  4. data/app/assets/stylesheets/iron_warbler/positions_gameui.scss +8 -0
  5. data/app/assets/stylesheets/iron_warbler/purses_gameui.scss +2 -4
  6. data/app/assets/stylesheets/iron_warbler/purses_summary.scss +31 -19
  7. data/app/controllers/iro/application_controller.rb +6 -0
  8. data/app/controllers/iro/positions_controller.rb +186 -137
  9. data/app/controllers/iro/purses_controller.rb +3 -1
  10. data/app/controllers/iro/stocks_controller.rb +2 -2
  11. data/app/models/iro/option.rb +41 -148
  12. data/app/models/iro/option_black_scholes.rb +149 -0
  13. data/app/models/iro/position.rb +156 -205
  14. data/app/models/iro/purse.rb +34 -4
  15. data/app/models/iro/strategy.rb +49 -47
  16. data/app/views/iro/_main_header.haml +4 -2
  17. data/app/views/iro/options/_show_mini.haml +8 -0
  18. data/app/views/iro/positions/_form.haml +8 -3
  19. data/app/views/iro/positions/_formpart_4data.haml +41 -38
  20. data/app/views/iro/positions/_gameui_covered_call.haml +1 -1
  21. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml +5 -5
  22. data/app/views/iro/positions/_gameui_long_debit_call_spread.haml-trash +42 -0
  23. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +1 -0
  24. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml-trash +40 -0
  25. data/app/views/iro/positions/_header.haml +2 -0
  26. data/app/views/iro/positions/_header_long_debit_call_spread.haml +43 -25
  27. data/app/views/iro/positions/_prepare_long_debit_call_spread.haml +6 -5
  28. data/app/views/iro/positions/_prepare_short_debit_put_spread.haml +2 -1
  29. data/app/views/iro/positions/_table.haml +25 -26
  30. data/app/views/iro/positions/prepare.haml +6 -4
  31. data/app/views/iro/positions/prepare2.haml +22 -0
  32. data/app/views/iro/purses/_form_extra_fields.haml +8 -4
  33. data/app/views/iro/purses/_header.haml +19 -5
  34. data/app/views/iro/purses/_summary.haml +69 -62
  35. data/app/views/iro/purses/show.haml +1 -1
  36. data/app/views/iro/strategies/_form.haml +26 -19
  37. data/app/views/iro/strategies/_show.haml +6 -4
  38. data/config/routes.rb +10 -7
  39. metadata +8 -2
  40. data/app/views/iro/positions/_gameui_short_debit_put_spread.haml +0 -40
@@ -1,23 +1,23 @@
1
- require 'distribution'
2
- N = Distribution::Normal
3
- # include Math
4
- # require 'business_time'
5
1
 
6
2
  class Iro::Option
7
3
  include Mongoid::Document
8
4
  include Mongoid::Timestamps
9
5
  include Mongoid::Paranoia
6
+ include Iro::OptionBlackScholes
10
7
  store_in collection: 'iro_options'
11
8
 
12
9
  attr_accessor :recompute
13
10
 
14
- field :ticker
15
- validates :ticker, presence: true
11
+ belongs_to :stock, class_name: 'Iro::Stock', inverse_of: :strategies
12
+ def ticker; stock.ticker; end
13
+ # field :ticker
14
+ # validates :ticker, presence: true
16
15
 
17
16
  field :symbol
18
- validates :symbol, uniqueness: true, presence: true
17
+ ## each option can be a leg in a position, no uniqueness
18
+ # validates :symbol, uniqueness: true, presence: true
19
19
 
20
- field :put_call, type: :string
20
+ field :put_call, type: :string # 'PUT' or 'CALL'
21
21
  validates :put_call, presence: true
22
22
 
23
23
  field :delta, type: :float
@@ -27,9 +27,29 @@ class Iro::Option
27
27
 
28
28
  field :expires_on, type: :date
29
29
  validates :expires_on, presence: true
30
+ def self.expirations_list full: false
31
+ [
32
+ [ nil, nil ],
33
+ [ 'Mar 22', '2024-03-22'.to_date ],
34
+ [ 'Mar 28', '2024-03-28'.to_date ],
35
+ [ 'Apr 5', '2024-04-05'.to_date ],
36
+ [ 'Mar 12', '2024-03-12'.to_date ],
37
+ [ 'Mar 19', '2024-03-19'.to_date ],
38
+ ]
39
+ end
30
40
 
31
- belongs_to :stock, class_name: 'Iro::Stock', inverse_of: :strategies
41
+ field :begin_price, type: :float
42
+ field :begin_delta, type: :float
43
+ field :end_price, type: :float
44
+ field :end_delta, type: :float
45
+
46
+
47
+ has_one :outer, class_name: 'Iro::Position', inverse_of: :outer
48
+ has_one :inner, class_name: 'Iro::Position', inverse_of: :inner
49
+
50
+ field :last, type: :float
32
51
 
52
+ ## for TDA
33
53
  def symbol
34
54
  if !self[:symbol]
35
55
  p_c_ = put_call == 'PUT' ? 'P' : 'C'
@@ -41,146 +61,19 @@ class Iro::Option
41
61
  self[:symbol]
42
62
  end
43
63
 
44
- ##
45
- ## black-scholes pricing
46
- ##
47
-
48
- =begin
49
- ##
50
- ##
51
- ##
52
- annual to daily:
53
-
54
- AR = ((DR + 1)^365 – 1) x 100
55
-
56
- ##
57
- ##
58
- ##
59
- From: https://www.investopedia.com/articles/optioninvestor/07/options_beat_market.asp
60
-
61
- K :: strike price
62
- S_t :: last
63
- r :: risk-free rate
64
- t :: time to maturity
65
-
66
- C = S_t N( d1 ) - K e^-rt N( d2 )
67
-
68
- d1 = ln( St / K ) + (r + theta**2 / 2 )t
69
- /{ theta_s * sqrt( t ) }
70
-
71
- d2 = d1 - theta_s sqrt( t )
72
-
73
- ##
74
- ## From: https://en.wikipedia.org/wiki/Black%E2%80%93Scholes_model
75
- ##
76
-
77
- D :: e^(rt) # discount factor
78
- F :: e^(rt) S # forward price of underlying
79
-
80
- C(F,t) = D[ N(d1)F - N(d2)K ]
81
-
82
- d1 = ln(F/K) + stdev**2 t / 2
83
- /{ stdev sqrt(t) }
84
- d2 = d1 - stdev sqrt(t)
85
-
86
- ##
87
- ## From: https://www.daytrading.com/options-pricing-models
88
- ##
89
- C0 = S0N(d1) – Xe-rtN(d2)
90
-
91
- C0 = current call premium
92
- S0 = current stock price
93
- N(d1) = the probability that a value in a normal distribution will be less than d
94
- N(d2) = the probability that the option will be in the money by expiration
95
- X = strike price of the option
96
- T = time until expiration (expressed in years)
97
- r = risk-free interest rate
98
- e = 2.71828, the base of the natural logarithm
99
- ln = natural logarithm function
100
- σ = standard deviation of the stock’s annualized rate of return (compounded continuously)
101
- d1 = ln(S0/X) + (r + σ2/2)Tσ√T
102
-
103
- d2 = d1 – σ√T
104
-
105
- Note that:
106
-
107
- Xe-rt = X/ert = the present value of the strike price using a continuously compounded interest rate
108
-
109
- ##
110
- ## From: https://www.wallstreetmojo.com/black-scholes-model/
111
- ##
112
-
113
-
114
- ## init
115
- require 'distribution'
116
- N = Distribution::Normal
117
- stock = Iro::Stock.find_by ticker: 'NVDA'
118
- strike = 910.0
119
- r = Iro::Option.rate_daily
120
- stdev = 91.0
121
- t = 7.0
122
- expires_on = '2024-03-22'
123
-
124
- =end
125
- def d1
126
- last = stock.last
127
- r = self.class.rate_annual
128
-
129
- out = Math.log( last / strike ) + ( r + stdev**2 / 2 ) * t
130
- out = out /( stdev * Math.sqrt(t) )
131
- return out
132
- end
133
- def d2
134
- last = stock.last
135
- r = self.class.rate_annual
136
-
137
- out = d1 - stdev * Math.sqrt( t )
138
- return out
139
- end
140
- def t
141
- # t = 1.0 / 365 * Date.today.business_days_until( expires_on )
142
- t = 1.0 / 365 * (expires_on - Date.today).to_i
143
- end
144
- def stdev
145
- recompute = nil
146
- stock.stdev( recompute: recompute )
147
- end
148
- def call_price
149
- last = stock.last
150
- r = self.class.rate_annual
151
-
152
- out = N.cdf( d1 ) * last - N.cdf( d2 ) * strike * Math::E**( -1 * r * t )
153
- return out
64
+ def sync
65
+ out = Tda::Option.get_quote({
66
+ contractType: put_call,
67
+ strike: strike,
68
+ expirationDate: expires_on,
69
+ ticker: ticker,
70
+ })
71
+ puts! out, 'option sync'
72
+ self.end_price = ( out.bid + out.ask ) / 2 rescue 0
73
+ self.end_delta = out.delta
74
+ # self.save
154
75
  end
155
76
 
156
- def put_price
157
- last = stock.last
158
- r = self.class.rate_annual
159
-
160
- out = N.cdf(-d2) * strike * exp(-r*t) - N.cdf(-d1) * last
161
- return out
162
- end
163
-
164
-
165
- def self.rate_annual
166
- 0.05
167
- end
168
-
169
- =begin
170
- # test
171
-
172
- inn = 100
173
- n.times { inn = inn*(1.0+out) }
174
- inn
175
-
176
- =end
177
- def self.rate_daily
178
- n = 250.0 # days
179
- # n = 12 # months
180
-
181
- out = (1.0+self.rate_annual)**(1.0/n) - 1.0
182
- puts! out, 'rate_daily'
183
- return out
184
- end
77
+ before_save :sync
185
78
 
186
79
  end
@@ -0,0 +1,149 @@
1
+
2
+ require 'distribution'
3
+ N = Distribution::Normal
4
+
5
+ module Iro::OptionBlackScholes
6
+
7
+ ##
8
+ ## black-scholes pricing
9
+ ##
10
+
11
+ =begin
12
+ ##
13
+ ##
14
+ ##
15
+ annual to daily:
16
+
17
+ AR = ((DR + 1)^365 – 1) x 100
18
+
19
+ ##
20
+ ##
21
+ ##
22
+ From: https://www.investopedia.com/articles/optioninvestor/07/options_beat_market.asp
23
+
24
+ K :: strike price
25
+ S_t :: last
26
+ r :: risk-free rate
27
+ t :: time to maturity
28
+
29
+ C = S_t N( d1 ) - K e^-rt N( d2 )
30
+
31
+ d1 = ln( St / K ) + (r + theta**2 / 2 )t
32
+ /{ theta_s * sqrt( t ) }
33
+
34
+ d2 = d1 - theta_s sqrt( t )
35
+
36
+ ##
37
+ ## From: https://en.wikipedia.org/wiki/Black%E2%80%93Scholes_model
38
+ ##
39
+
40
+ D :: e^(rt) # discount factor
41
+ F :: e^(rt) S # forward price of underlying
42
+
43
+ C(F,t) = D[ N(d1)F - N(d2)K ]
44
+
45
+ d1 = ln(F/K) + stdev**2 t / 2
46
+ /{ stdev sqrt(t) }
47
+ d2 = d1 - stdev sqrt(t)
48
+
49
+ ##
50
+ ## From: https://www.daytrading.com/options-pricing-models
51
+ ##
52
+ C0 = S0N(d1) – Xe-rtN(d2)
53
+
54
+ C0 = current call premium
55
+ S0 = current stock price
56
+ N(d1) = the probability that a value in a normal distribution will be less than d
57
+ N(d2) = the probability that the option will be in the money by expiration
58
+ X = strike price of the option
59
+ T = time until expiration (expressed in years)
60
+ r = risk-free interest rate
61
+ e = 2.71828, the base of the natural logarithm
62
+ ln = natural logarithm function
63
+ σ = standard deviation of the stock’s annualized rate of return (compounded continuously)
64
+ d1 = ln(S0/X) + (r + σ2/2)Tσ√T
65
+
66
+ d2 = d1 – σ√T
67
+
68
+ Note that:
69
+
70
+ Xe-rt = X/ert = the present value of the strike price using a continuously compounded interest rate
71
+
72
+ ##
73
+ ## From: https://www.wallstreetmojo.com/black-scholes-model/
74
+ ##
75
+
76
+
77
+ ## init
78
+ require 'distribution'
79
+ N = Distribution::Normal
80
+ stock = Iro::Stock.find_by ticker: 'NVDA'
81
+ strike = 910.0
82
+ r = Iro::Option.rate_daily
83
+ stdev = 91.0
84
+ t = 7.0
85
+ expires_on = '2024-03-22'
86
+
87
+ =end
88
+ def d1
89
+ last = stock.last
90
+ r = self.class.rate_annual
91
+
92
+ out = Math.log( last / strike ) + ( r + stdev**2 / 2 ) * t
93
+ out = out /( stdev * Math.sqrt(t) )
94
+ return out
95
+ end
96
+ def d2
97
+ last = stock.last
98
+ r = self.class.rate_annual
99
+
100
+ out = d1 - stdev * Math.sqrt( t )
101
+ return out
102
+ end
103
+ def t
104
+ # t = 1.0 / 365 * Date.today.business_days_until( expires_on )
105
+ t = 1.0 / 365 * (expires_on - Date.today).to_i
106
+ end
107
+ def stdev
108
+ recompute = nil
109
+ stock.stdev( recompute: recompute )
110
+ end
111
+ def call_price
112
+ last = stock.last
113
+ r = self.class.rate_annual
114
+
115
+ out = N.cdf( d1 ) * last - N.cdf( d2 ) * strike * Math::E**( -1 * r * t )
116
+ return out
117
+ end
118
+
119
+ def put_price
120
+ last = stock.last
121
+ r = self.class.rate_annual
122
+
123
+ out = N.cdf(-d2) * strike * exp(-r*t) - N.cdf(-d1) * last
124
+ return out
125
+ end
126
+
127
+
128
+ def self.rate_annual
129
+ 0.05
130
+ end
131
+
132
+ =begin
133
+ # test
134
+
135
+ inn = 100
136
+ n.times { inn = inn*(1.0+out) }
137
+ inn
138
+
139
+ =end
140
+ def self.rate_daily
141
+ n = 250.0 # days
142
+ # n = 12 # months
143
+
144
+ out = (1.0+self.rate_annual)**(1.0/n) - 1.0
145
+ puts! out, 'rate_daily'
146
+ return out
147
+ end
148
+
149
+ end