iron_warbler 2.0.7.25 → 2.0.7.26

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