iron_warbler 2.0.7.32 → 2.0.7.33
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.
- checksums.yaml +4 -4
- data/README.txt +0 -4
- data/app/models/iro/position.rb +23 -4
- data/app/models/iro/strategy.rb +23 -5
- data/app/models/tda/option.rb +20 -5
- data/app/views/iro/positions/_gameui_long_credit_put_spread.haml +42 -0
- data/app/views/iro/positions/_header_long_credit_put_spread.haml +4 -0
- data/app/views/iro/positions/_table.haml +1 -1
- data/app/views/iro/purses/_form_extra_fields.haml +1 -1
- data/app/views/iro/strategies/_table.haml +6 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e4baf29056fb5eea6a152c68d259e00dc77c1b8933038ffa57f7cf26ea57a6c1
|
|
4
|
+
data.tar.gz: 5cc60160b9be49f2e3521c14de595307d3f4352168c56be8c75be13ee5012af0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a494cbf2307b6ab42f76d7db61bb9ca3e729363d015ed3be4456b53f65e2bb4d690a225bdcd16d5c341394ed24b8e4cc098ab243a04302ab544965da125697de
|
|
7
|
+
data.tar.gz: 67e3fb70e47cabd54f59bb9a592d60ba3b9e549795287b396607e777d04a172ca55838929b8550da6eee85e84ce5b8580bdd87fc6332e85c44d3179ebd72f29f
|
data/README.txt
CHANGED
|
@@ -10,7 +10,3 @@ From: https://docs.galpy.org/en/latest/installation.html
|
|
|
10
10
|
calculator: https://www.omnicalculator.com/finance/black-scholes
|
|
11
11
|
|
|
12
12
|
From: https://pythoninoffice.com/calculate-black-scholes-option-price-in-python/
|
|
13
|
-
|
|
14
|
-
= swagger =
|
|
15
|
-
|
|
16
|
-
* https://developer.schwab.com/products/trader-api--individual
|
data/app/models/iro/position.rb
CHANGED
|
@@ -138,7 +138,6 @@ class Iro::Position
|
|
|
138
138
|
save
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
-
## @TODO: herehere 2024-05-09
|
|
142
141
|
def calc_nxt
|
|
143
142
|
pos = self
|
|
144
143
|
|
|
@@ -154,6 +153,12 @@ class Iro::Position
|
|
|
154
153
|
out[:bidSize] + out[:askSize] > 0
|
|
155
154
|
end
|
|
156
155
|
|
|
156
|
+
if 'CALL' == pos.put_call
|
|
157
|
+
;
|
|
158
|
+
elsif 'PUT' == pos.put_call
|
|
159
|
+
outs = outs.reverse
|
|
160
|
+
end
|
|
161
|
+
|
|
157
162
|
## next_inner_strike
|
|
158
163
|
outs = outs.select do |out|
|
|
159
164
|
if Iro::Strategy::SHORT == pos.long_or_short
|
|
@@ -165,6 +170,7 @@ class Iro::Position
|
|
|
165
170
|
end
|
|
166
171
|
end
|
|
167
172
|
puts! outs[0][:strikePrice], 'after calc next_inner_strike'
|
|
173
|
+
puts! outs, 'outs'
|
|
168
174
|
|
|
169
175
|
## next_buffer_above_water
|
|
170
176
|
outs = outs.select do |out|
|
|
@@ -177,17 +183,30 @@ class Iro::Position
|
|
|
177
183
|
end
|
|
178
184
|
end
|
|
179
185
|
puts! outs[0][:strikePrice], 'after calc next_buffer_above_water'
|
|
186
|
+
puts! outs, 'outs'
|
|
180
187
|
|
|
181
188
|
## next_inner_delta
|
|
182
189
|
outs = outs.select do |out|
|
|
183
|
-
|
|
184
|
-
|
|
190
|
+
if 'CALL' == pos.put_call
|
|
191
|
+
out_delta = out[:delta] rescue 1
|
|
192
|
+
out_delta <= strategy.next_inner_delta
|
|
193
|
+
elsif 'PUT' == pos.put_call
|
|
194
|
+
out_delta = out[:delta] rescue 0
|
|
195
|
+
out_delta <= strategy.next_inner_delta
|
|
196
|
+
else
|
|
197
|
+
raise 'zz5 - this cannot happen'
|
|
198
|
+
end
|
|
185
199
|
end
|
|
186
200
|
puts! outs[0][:strikePrice], 'after calc next_inner_delta'
|
|
201
|
+
puts! outs, 'outs'
|
|
187
202
|
|
|
188
203
|
inner = outs[0]
|
|
189
204
|
outs = outs.select do |out|
|
|
190
|
-
|
|
205
|
+
if 'CALL' == pos.put_call
|
|
206
|
+
out[:strikePrice] >= inner[:strikePrice].to_f + strategy.next_spread_amount
|
|
207
|
+
elsif 'PUT' == pos.put_call
|
|
208
|
+
out[:strikePrice] <= inner[:strikePrice].to_f - strategy.next_spread_amount
|
|
209
|
+
end
|
|
191
210
|
end
|
|
192
211
|
outer = outs[0]
|
|
193
212
|
|
data/app/models/iro/strategy.rb
CHANGED
|
@@ -16,10 +16,10 @@ class Iro::Strategy
|
|
|
16
16
|
validates :long_or_short, presence: true
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
has_many :positions,
|
|
20
|
-
has_one :next_position,
|
|
21
|
-
belongs_to :stock,
|
|
22
|
-
has_and_belongs_to_many :purses, class_name: 'Iro::Purse',
|
|
19
|
+
has_many :positions, class_name: 'Iro::Position', inverse_of: :strategy
|
|
20
|
+
has_one :next_position, class_name: 'Iro::Position', inverse_of: :next_strategy
|
|
21
|
+
belongs_to :stock, class_name: 'Iro::Stock', inverse_of: :strategies
|
|
22
|
+
has_and_belongs_to_many :purses, class_name: 'Iro::Purse', inverse_of: :strategies
|
|
23
23
|
|
|
24
24
|
KIND_COVERED_CALL = 'covered_call'
|
|
25
25
|
KIND_IRON_CONDOR = 'iron_condor'
|
|
@@ -34,11 +34,13 @@ class Iro::Strategy
|
|
|
34
34
|
KIND_LONG_DEBIT_CALL_SPREAD,
|
|
35
35
|
KIND_SHORT_CREDIT_CALL_SPREAD,
|
|
36
36
|
KIND_SHORT_DEBIT_PUT_SPREAD,
|
|
37
|
-
]
|
|
37
|
+
];
|
|
38
38
|
field :kind
|
|
39
39
|
|
|
40
40
|
def put_call
|
|
41
41
|
case kind
|
|
42
|
+
when Iro::Strategy::KIND_LONG_CREDIT_PUT_SPREAD
|
|
43
|
+
put_call = 'PUT'
|
|
42
44
|
when Iro::Strategy::KIND_LONG_DEBIT_CALL_SPREAD
|
|
43
45
|
put_call = 'CALL'
|
|
44
46
|
when Iro::Strategy::KIND_SHORT_CREDIT_CALL_SPREAD
|
|
@@ -47,6 +49,8 @@ class Iro::Strategy
|
|
|
47
49
|
put_call = 'PUT'
|
|
48
50
|
when Iro::Strategy::KIND_COVERED_CALL
|
|
49
51
|
put_call = 'CALL'
|
|
52
|
+
else
|
|
53
|
+
throw 'zz9 - this should never happen'
|
|
50
54
|
end
|
|
51
55
|
end
|
|
52
56
|
|
|
@@ -70,6 +74,9 @@ class Iro::Strategy
|
|
|
70
74
|
def begin_delta_covered_call p
|
|
71
75
|
p.inner.begin_delta
|
|
72
76
|
end
|
|
77
|
+
def begin_delta_long_credit_put_spread p
|
|
78
|
+
p.inner.begin_delta - p.outer.begin_delta
|
|
79
|
+
end
|
|
73
80
|
def begin_delta_long_debit_call_spread p
|
|
74
81
|
p.outer.begin_delta - p.inner.begin_delta
|
|
75
82
|
end
|
|
@@ -89,6 +96,9 @@ class Iro::Strategy
|
|
|
89
96
|
def end_delta_covered_call p
|
|
90
97
|
p.inner.end_delta
|
|
91
98
|
end
|
|
99
|
+
def end_delta_long_credit_put_spread p
|
|
100
|
+
p.inner.end_delta - p.outer.end_delta
|
|
101
|
+
end
|
|
92
102
|
def end_delta_long_debit_call_spread p
|
|
93
103
|
p.outer.end_delta - p.inner.end_delta
|
|
94
104
|
end
|
|
@@ -99,6 +109,10 @@ class Iro::Strategy
|
|
|
99
109
|
def max_gain_covered_call p
|
|
100
110
|
p.inner.begin_price * 100 - 0.66 # @TODO: is this *100 really?
|
|
101
111
|
end
|
|
112
|
+
def max_gain_long_credit_put_spread p
|
|
113
|
+
## 100 * disallowed for gameui
|
|
114
|
+
p.inner.begin_price - p.outer.begin_price
|
|
115
|
+
end
|
|
102
116
|
def max_gain_long_debit_call_spread p
|
|
103
117
|
## 100 * disallowed for gameui
|
|
104
118
|
( p.inner.strike - p.outer.strike - p.outer.begin_price + p.inner.begin_price ) # - 2*0.66
|
|
@@ -115,6 +129,9 @@ class Iro::Strategy
|
|
|
115
129
|
def max_loss_covered_call p
|
|
116
130
|
p.inner.begin_price*10 # just suppose 10,000%
|
|
117
131
|
end
|
|
132
|
+
def max_loss_long_credit_put_spread p
|
|
133
|
+
out = p.inner.strike - p.outer.strike
|
|
134
|
+
end
|
|
118
135
|
def max_loss_long_debit_call_spread p
|
|
119
136
|
out = p.outer.strike - p.inner.strike
|
|
120
137
|
end
|
|
@@ -134,6 +151,7 @@ class Iro::Strategy
|
|
|
134
151
|
inner = p.inner.begin_price - p.inner.end_price
|
|
135
152
|
out = ( outer + inner )
|
|
136
153
|
end
|
|
154
|
+
alias_method :net_amount_long_credit_put_spread , :net_amount_long_debit_call_spread
|
|
137
155
|
alias_method :net_amount_short_credit_call_spread , :net_amount_long_debit_call_spread
|
|
138
156
|
alias_method :net_amount_short_debit_put_spread, :net_amount_long_debit_call_spread
|
|
139
157
|
|
data/app/models/tda/option.rb
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
|
|
2
2
|
require 'httparty'
|
|
3
3
|
|
|
4
|
+
=begin
|
|
5
|
+
class Schwab
|
|
6
|
+
include HTTParty
|
|
7
|
+
debug_output $stdout
|
|
8
|
+
base_uri 'https://api.schwabapi.com/marketdata/v1'
|
|
9
|
+
end
|
|
10
|
+
=end
|
|
11
|
+
|
|
4
12
|
class Tda::Option
|
|
5
13
|
|
|
6
14
|
include ::HTTParty
|
|
15
|
+
debug_output $stdout
|
|
7
16
|
# base_uri 'https://api.tdameritrade.com'
|
|
8
17
|
base_uri 'https://api.schwabapi.com/marketdata/v1'
|
|
9
18
|
|
|
@@ -70,6 +79,8 @@ class Tda::Option
|
|
|
70
79
|
##
|
|
71
80
|
def self.get_quotes params
|
|
72
81
|
puts! params, 'Tda::Option#get_quotes'
|
|
82
|
+
|
|
83
|
+
profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
|
|
73
84
|
opts = {}
|
|
74
85
|
|
|
75
86
|
#
|
|
@@ -99,18 +110,22 @@ class Tda::Option
|
|
|
99
110
|
end
|
|
100
111
|
|
|
101
112
|
query = { }.merge opts
|
|
102
|
-
|
|
113
|
+
puts! query, 'input opts'
|
|
103
114
|
|
|
104
115
|
headers = {
|
|
105
116
|
accept: 'application/json',
|
|
106
|
-
Authorization: "Bearer #{
|
|
117
|
+
Authorization: "Bearer #{profile[:schwab_access_token]}",
|
|
107
118
|
}
|
|
108
119
|
|
|
109
|
-
|
|
110
120
|
path = "/chains"
|
|
111
|
-
out = self.get path, {
|
|
121
|
+
out = self.get path, {
|
|
122
|
+
# basic_auth: { username: SCHWAB_DATA[:key], password: SCHWAB_DATA[:secret] },
|
|
123
|
+
headers: headers,
|
|
124
|
+
query: query,
|
|
125
|
+
}
|
|
126
|
+
puts! out, 'out'
|
|
112
127
|
timestamp = DateTime.parse out.headers['date']
|
|
113
|
-
|
|
128
|
+
# out = HTTParty.get "https://api.tdameritrade.com#{path}", { query: query }
|
|
114
129
|
out = out.parsed_response.deep_symbolize_keys
|
|
115
130
|
|
|
116
131
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
- pos = position
|
|
3
|
+
- stock = pos.stock
|
|
4
|
+
- nearest_strike = stock.last.round
|
|
5
|
+
- u = pos.purse.unit # pixels per dollar
|
|
6
|
+
|
|
7
|
+
-#
|
|
8
|
+
-# 2024-07-30 I have not verified any of this - copied from long_debit_call_spread.
|
|
9
|
+
-#
|
|
10
|
+
|
|
11
|
+
.collapse-expand.d-flex{ id: "gameui-pos-#{pos.id}" }
|
|
12
|
+
[<>]
|
|
13
|
+
.maxwidth= render "/iro/positions/header", pos: pos
|
|
14
|
+
.a
|
|
15
|
+
= render "/iro/positions/header_#{pos.strategy.kind}", pos: pos
|
|
16
|
+
.StockCoordinatesW
|
|
17
|
+
.StockCoordinates{ style: "height: #{pos.q() *pos.purse.height}px " }
|
|
18
|
+
.grid= render "/iro/stocks/grid_#{pos.strategy.long_or_short}", stock: stock, position: pos
|
|
19
|
+
|
|
20
|
+
.Origin{ style: "left: #{ ( nearest_strike - stock.last )* u}px" }
|
|
21
|
+
.label Last: #{pp_amount stock.last}
|
|
22
|
+
.c
|
|
23
|
+
|
|
24
|
+
- left = "#{ ( pos.outer.strike - stock.last ).abs() *-1*u}px"
|
|
25
|
+
- width = "#{ ( pos.inner.strike - pos.outer.strike ).abs() *u}px"
|
|
26
|
+
.PositionW{ class: pos.strategy.kind, style: "left: #{left}; width: #{width}; " }
|
|
27
|
+
.Position
|
|
28
|
+
.MaxGain{ style: "width: #{pos.max_gain * u}px" }
|
|
29
|
+
.RollGuide
|
|
30
|
+
|
|
31
|
+
- if pos.net_amount >= 0
|
|
32
|
+
.Net.NetPositive{ style: "width: #{ (pos.net_amount) * u }px; right: 0" }
|
|
33
|
+
.label
|
|
34
|
+
net
|
|
35
|
+
= pp_amount pos.net_amount
|
|
36
|
+
- else
|
|
37
|
+
.Net.NetNegative{ style: "width: #{ (-1 * pos.net_amount) * u }px; left: 100%" }
|
|
38
|
+
.label
|
|
39
|
+
net
|
|
40
|
+
= pp_amount pos.net_amount
|
|
41
|
+
.c
|
|
42
|
+
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
%th.actions
|
|
10
10
|
%th kind
|
|
11
11
|
%th slug
|
|
12
|
+
%th stock
|
|
13
|
+
%th long or short
|
|
12
14
|
%th next_inner_delta
|
|
13
15
|
%th.actions
|
|
14
16
|
%tbody
|
|
@@ -20,6 +22,10 @@
|
|
|
20
22
|
= button_to 'x', strategy_path(sss), method: :delete, data: { confirm: 'Are you sure?' }
|
|
21
23
|
%td= sss.kind
|
|
22
24
|
%td= link_to sss.slug, strategy_path(sss)
|
|
25
|
+
%td.stock
|
|
26
|
+
= sss.stock
|
|
27
|
+
%td.long-or-short
|
|
28
|
+
= sss.long_or_short
|
|
23
29
|
%td= sss.next_inner_delta
|
|
24
30
|
%td
|
|
25
31
|
= form_tag propose_position_path do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: iron_warbler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.7.
|
|
4
|
+
version: 2.0.7.33
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Victor Pudeyev
|
|
@@ -267,6 +267,7 @@ files:
|
|
|
267
267
|
- app/views/iro/positions/_formpart_4data.haml
|
|
268
268
|
- app/views/iro/positions/_gameui_covered_call.haml
|
|
269
269
|
- app/views/iro/positions/_gameui_covered_call.haml-bk
|
|
270
|
+
- app/views/iro/positions/_gameui_long_credit_put_spread.haml
|
|
270
271
|
- app/views/iro/positions/_gameui_long_debit_call_spread.haml
|
|
271
272
|
- app/views/iro/positions/_gameui_long_debit_call_spread.haml-trash
|
|
272
273
|
- app/views/iro/positions/_gameui_short_credit_call_spread.haml
|
|
@@ -274,6 +275,7 @@ files:
|
|
|
274
275
|
- app/views/iro/positions/_gameui_short_debit_put_spread.haml-trash
|
|
275
276
|
- app/views/iro/positions/_header.haml
|
|
276
277
|
- app/views/iro/positions/_header_covered_call.haml
|
|
278
|
+
- app/views/iro/positions/_header_long_credit_put_spread.haml
|
|
277
279
|
- app/views/iro/positions/_header_long_debit_call_spread.haml
|
|
278
280
|
- app/views/iro/positions/_header_short_credit_call_spread.haml
|
|
279
281
|
- app/views/iro/positions/_header_short_debit_put_spread.haml
|