iron_warbler 2.0.7.24 → 2.0.7.26

Sign up to get free protection for your applications and to get access to all the features.
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