wco_models 3.1.0.267 → 3.1.0.269
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/app/models/iro/option.rb +1 -1
- data/app/models/iro/position.rb +39 -10
- data/app/models/iro/purse.rb +3 -0
- data/app/models/iro/stock.rb +10 -0
- data/app/models/iro/strategy.rb +16 -2
- data/app/models/tda/option.rb +8 -8
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 91f4c3c5f908983786abe2b1fbc402d18fcad4222323fbccbf662175c3603ea4
|
|
4
|
+
data.tar.gz: 6cc8d4b4cf40fff0c84a4e1c6b76202551a2a5e22ccc4f7e8e1f96596701be2e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 18b383d3a25ebb58fce4406279f1f1921b0a3932b763074f6183d6bcc417591fb8ec04d73083753e51c4954c453bf331a33f1e44116a429515d2ece4fb1b8ab2
|
|
7
|
+
data.tar.gz: 3506848b877ff5bd81d41077406005e5483b36a7ea3f0984d3c2aeb187dc82022e1ac91e4e32af557487ca6331969a62a9b3d303dc7244e667ed50e151d4692c
|
data/app/models/iro/option.rb
CHANGED
|
@@ -102,7 +102,7 @@ class Iro::Option
|
|
|
102
102
|
expirationDate: expires_on.strftime('%Y-%m-%d'),
|
|
103
103
|
ticker: ticker,
|
|
104
104
|
})
|
|
105
|
-
puts! out, "option sync of `#{self.to_s}`"
|
|
105
|
+
# puts! out, "option sync of `#{self.to_s}`"
|
|
106
106
|
self.end_price = ( out.bid + out.ask ) / 2 rescue 0
|
|
107
107
|
self.end_delta = out.delta ? out.delta : 0.0
|
|
108
108
|
self.save! ## 2026-02-19 this must be present.
|
data/app/models/iro/position.rb
CHANGED
|
@@ -25,8 +25,6 @@ class Iro::Position
|
|
|
25
25
|
return labels[st] || st
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
INTENT_CLOSE = 'close.'
|
|
29
|
-
INTENTS = [ nil, INTENT_CLOSE ]
|
|
30
28
|
field :intent
|
|
31
29
|
|
|
32
30
|
belongs_to :purse, class_name: 'Iro::Purse', inverse_of: :positions
|
|
@@ -210,6 +208,37 @@ class Iro::Position
|
|
|
210
208
|
outer.sync
|
|
211
209
|
end
|
|
212
210
|
|
|
211
|
+
def self.sync_all
|
|
212
|
+
@positions = Iro::Position.where( :status.in => [ 'active', 'pending' ] )
|
|
213
|
+
expiration_dates = @positions.map { |p| p.expires_on.to_s }.sort
|
|
214
|
+
# puts! expiration_dates, 'expiration_dates'
|
|
215
|
+
|
|
216
|
+
count = 1
|
|
217
|
+
@positions.each do |pos|
|
|
218
|
+
# puts! pos.to_s, 'pos TMP'
|
|
219
|
+
|
|
220
|
+
quotes_h = Tda::Option.get_quotes_h({
|
|
221
|
+
contractType: 'ALL',
|
|
222
|
+
ticker: pos.ticker,
|
|
223
|
+
fromDate: expiration_dates.first,
|
|
224
|
+
toDate: expiration_dates.last,
|
|
225
|
+
})
|
|
226
|
+
|
|
227
|
+
pos.inner.end_price = quotes_h[pos.expires_on.to_s][pos.put_call][pos.inner.strike][:price]
|
|
228
|
+
pos.inner.end_delta = quotes_h[pos.expires_on.to_s][pos.put_call][pos.inner.strike][:delta]
|
|
229
|
+
pos.inner.save ? print("#{count}^") : print("#{count}X")
|
|
230
|
+
if [ Iro::Strategy::KIND_LONG_CREDIT_PUT_SPREAD, Iro::Strategy::KIND_SHORT_CREDIT_CALL_SPREAD ].include?( pos.strategy.kind )
|
|
231
|
+
pos.outer.end_price = quotes_h[pos.expires_on.to_s][pos.put_call][pos.outer.strike][:price]
|
|
232
|
+
pos.outer.end_delta = quotes_h[pos.expires_on.to_s][pos.put_call][pos.outer.strike][:delta]
|
|
233
|
+
pos.outer.save ? print('^') : print('X')
|
|
234
|
+
end
|
|
235
|
+
count = count+1
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
print 'synced-all.'
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
|
|
213
242
|
|
|
214
243
|
##
|
|
215
244
|
## decisions
|
|
@@ -232,7 +261,7 @@ class Iro::Position
|
|
|
232
261
|
|
|
233
262
|
def calc_nxt
|
|
234
263
|
pos = self
|
|
235
|
-
puts! pos, '#calc_nxt...'
|
|
264
|
+
# puts! pos, '#calc_nxt...'
|
|
236
265
|
|
|
237
266
|
## 7 days ahead - not configurable
|
|
238
267
|
params = {
|
|
@@ -240,9 +269,9 @@ class Iro::Position
|
|
|
240
269
|
expirationDate: next_expires_on,
|
|
241
270
|
ticker: ticker,
|
|
242
271
|
}
|
|
243
|
-
puts! params, 'ze params'
|
|
272
|
+
# puts! params, 'ze params'
|
|
244
273
|
outs = Tda::Option.get_quotes(params)
|
|
245
|
-
puts! outs, 'outs'
|
|
274
|
+
# puts! outs, 'outs'
|
|
246
275
|
outs_bk = outs.dup
|
|
247
276
|
|
|
248
277
|
outs = outs.select do |out|
|
|
@@ -271,7 +300,7 @@ class Iro::Position
|
|
|
271
300
|
raise 'zt3 - @TODO: implement, debit spreads'
|
|
272
301
|
end
|
|
273
302
|
end
|
|
274
|
-
puts! outs[0][:strikePrice], 'after calc next_inner_strike'
|
|
303
|
+
# puts! outs[0][:strikePrice], 'after calc next_inner_strike'
|
|
275
304
|
# puts! outs, 'outs'
|
|
276
305
|
end
|
|
277
306
|
|
|
@@ -285,8 +314,8 @@ class Iro::Position
|
|
|
285
314
|
raise 'zt4 - this cannot happen'
|
|
286
315
|
end
|
|
287
316
|
end
|
|
288
|
-
puts! outs[0][:strikePrice], 'after calc next_usd_above_mark'
|
|
289
|
-
puts! outs, 'outs'
|
|
317
|
+
# puts! outs[0][:strikePrice], 'after calc next_usd_above_mark'
|
|
318
|
+
# puts! outs, 'outs'
|
|
290
319
|
|
|
291
320
|
## next_inner_delta
|
|
292
321
|
outs = outs.select do |out|
|
|
@@ -300,8 +329,8 @@ class Iro::Position
|
|
|
300
329
|
raise 'zt5 - this cannot happen'
|
|
301
330
|
end
|
|
302
331
|
end
|
|
303
|
-
puts! outs[0][:strikePrice], 'after calc next_inner_delta'
|
|
304
|
-
puts! outs, 'outs'
|
|
332
|
+
# puts! outs[0][:strikePrice], 'after calc next_inner_delta'
|
|
333
|
+
# puts! outs, 'outs'
|
|
305
334
|
|
|
306
335
|
inner = outs[0]
|
|
307
336
|
outs = outs.select do |out|
|
data/app/models/iro/purse.rb
CHANGED
|
@@ -12,6 +12,9 @@ class Iro::Purse
|
|
|
12
12
|
validates :slug, presence: true, uniqueness: true
|
|
13
13
|
index({ slug: -1 }, { unique: true })
|
|
14
14
|
|
|
15
|
+
TEMPLATE_GAMEUI = 'gameui'
|
|
16
|
+
TEMPLATE_TABLE = 'table'
|
|
17
|
+
|
|
15
18
|
has_many :positions, class_name: 'Iro::Position', inverse_of: :purse
|
|
16
19
|
|
|
17
20
|
has_many :strategies, class_name: 'Iro::Strategy', inverse_of: :purse
|
data/app/models/iro/stock.rb
CHANGED
|
@@ -198,4 +198,14 @@ class ::Iro::Stock
|
|
|
198
198
|
end
|
|
199
199
|
end
|
|
200
200
|
|
|
201
|
+
def self.sync
|
|
202
|
+
tickers = Iro::Stock.all.map { |s| s.ticker }.join(',')
|
|
203
|
+
outs = Tda::Stock.get_quotes tickers
|
|
204
|
+
outs.map do |out|
|
|
205
|
+
Iro::Stock.where( ticker: out[:symbol] ).update_all( last: out[:last] )
|
|
206
|
+
end
|
|
207
|
+
puts "+++ Synced stocks."
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
|
|
201
211
|
end
|
data/app/models/iro/strategy.rb
CHANGED
|
@@ -94,6 +94,20 @@ class Iro::Strategy
|
|
|
94
94
|
field :next_usd_above_mark, type: :float
|
|
95
95
|
validates :next_usd_above_mark, presence: true
|
|
96
96
|
|
|
97
|
+
|
|
98
|
+
INTENT_CLOSE = 'try-close'
|
|
99
|
+
INTENT_OPEN = 'try-open'
|
|
100
|
+
INTENT_ROLL = 'try-roll'
|
|
101
|
+
INTENTS = [ nil, INTENT_CLOSE, INTENT_ROLL ]
|
|
102
|
+
field :intent
|
|
103
|
+
|
|
104
|
+
field :sentiment, type: :float
|
|
105
|
+
field :sentiment_sector, type: :float
|
|
106
|
+
field :sentiment_market, type: :float
|
|
107
|
+
|
|
108
|
+
field :tgt_exposure, type: :float
|
|
109
|
+
|
|
110
|
+
|
|
97
111
|
def begin_delta_covered_call p
|
|
98
112
|
p.inner.begin_delta
|
|
99
113
|
end
|
|
@@ -324,7 +338,7 @@ class Iro::Strategy
|
|
|
324
338
|
## 2026-02-21 ok
|
|
325
339
|
## 2026-04-05 ok
|
|
326
340
|
def calc_rollp_short_credit_call_spread p
|
|
327
|
-
puts! p, 'calc_rollp_short_credit_call_spread...'
|
|
341
|
+
# puts! p, 'calc_rollp_short_credit_call_spread...'
|
|
328
342
|
stock.reload
|
|
329
343
|
|
|
330
344
|
if ( p.expires_on.to_date - Time.now.to_date ).to_i <= threshold_dte
|
|
@@ -365,7 +379,7 @@ class Iro::Strategy
|
|
|
365
379
|
|
|
366
380
|
|
|
367
381
|
def to_s
|
|
368
|
-
"#{kind} #{stock} #{descr}"
|
|
382
|
+
"#{kind} #{stock} #{next_spread_amount}- #{intent} #{descr}"
|
|
369
383
|
end
|
|
370
384
|
def self.list long_or_short = nil
|
|
371
385
|
these = long_or_short ? where( long_or_short: long_or_short ) : all
|
data/app/models/tda/option.rb
CHANGED
|
@@ -12,7 +12,7 @@ end
|
|
|
12
12
|
class Tda::Option
|
|
13
13
|
|
|
14
14
|
include ::HTTParty
|
|
15
|
-
debug_output $stdout
|
|
15
|
+
# debug_output $stdout
|
|
16
16
|
base_uri 'https://api.schwabapi.com/marketdata/v1'
|
|
17
17
|
|
|
18
18
|
|
|
@@ -43,7 +43,7 @@ class Tda::Option
|
|
|
43
43
|
query: query }
|
|
44
44
|
timestamp = DateTime.parse out.headers['date']
|
|
45
45
|
out = out.parsed_response
|
|
46
|
-
puts! out, 'outs'
|
|
46
|
+
# puts! out, 'outs'
|
|
47
47
|
|
|
48
48
|
outs = []
|
|
49
49
|
%w| put call |.each do |contractType|
|
|
@@ -109,7 +109,7 @@ class Tda::Option
|
|
|
109
109
|
## 2023-02-06 _vp_ :: Continue.
|
|
110
110
|
##
|
|
111
111
|
def self.get_quotes params
|
|
112
|
-
puts! params, 'core Tda::Option#get_quotes...'
|
|
112
|
+
# puts! params, 'core Tda::Option#get_quotes...'
|
|
113
113
|
|
|
114
114
|
profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
|
|
115
115
|
opts = {}
|
|
@@ -178,7 +178,7 @@ class Tda::Option
|
|
|
178
178
|
|
|
179
179
|
## 2026-02-23 use this instead.
|
|
180
180
|
def self.get_quotes_h params
|
|
181
|
-
puts! params, 'Tda::Option#get_quotes_h ...'
|
|
181
|
+
# puts! params, 'Tda::Option#get_quotes_h ...'
|
|
182
182
|
|
|
183
183
|
profile = Wco::Profile.find_by email: 'piousbox@gmail.com'
|
|
184
184
|
opts = {}
|
|
@@ -214,7 +214,7 @@ class Tda::Option
|
|
|
214
214
|
|
|
215
215
|
## query = { contractType: "PUT", toDate: "2026-02-26", fromDate: "2026-02-26", symbol: "TSLA", strike: 395.0}
|
|
216
216
|
query = { }.merge opts
|
|
217
|
-
puts! query, 'query'
|
|
217
|
+
# puts! query, 'query'
|
|
218
218
|
|
|
219
219
|
results = self.get( "/chains", {
|
|
220
220
|
headers: {
|
|
@@ -296,7 +296,7 @@ class Tda::Option
|
|
|
296
296
|
],
|
|
297
297
|
}
|
|
298
298
|
File.write('tmp/query.json', JSON.pretty_generate( query ))
|
|
299
|
-
puts! query, 'query'
|
|
299
|
+
# puts! query, 'query'
|
|
300
300
|
|
|
301
301
|
return
|
|
302
302
|
|
|
@@ -305,11 +305,11 @@ class Tda::Option
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
path = "/v1/accounts/#{::TD_AMERITRADE[:accountId]}/orders"
|
|
308
|
-
puts! path, 'path'
|
|
308
|
+
# puts! path, 'path'
|
|
309
309
|
out = self.post path, { query: query, headers: headers }
|
|
310
310
|
timestamp = DateTime.parse out.headers['date']
|
|
311
311
|
out = out.parsed_response.deep_symbolize_keys
|
|
312
|
-
puts! out, 'created credit call?'
|
|
312
|
+
# puts! out, 'created credit call?'
|
|
313
313
|
end
|
|
314
314
|
def self.create_long_debit_call_spread
|
|
315
315
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: wco_models
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.1.0.
|
|
4
|
+
version: 3.1.0.269
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Victor Pudeyev
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ahoy_matey
|