iron_warbler 2.0.7.7 → 2.0.7.9
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/Rakefile +3 -16
- data/app/assets/javascript/iron_warbler/application.js +3 -0
- data/app/assets/stylesheets/iron_warbler/positions.scss +47 -0
- data/app/assets/stylesheets/iron_warbler/strategies.scss +0 -0
- data/app/assets/stylesheets/iron_warbler/utils.css +44 -0
- data/app/controllers/iro/alerts_controller.rb +6 -6
- data/app/controllers/iro/application_controller.rb +3 -2
- data/app/controllers/iro/datapoints_controller.rb +0 -2
- data/app/controllers/iro/positions_controller.rb +62 -0
- data/app/controllers/iro/profiles_controller.rb +0 -2
- data/app/controllers/iro/purses_controller.rb +65 -0
- data/app/controllers/iro/stocks_controller.rb +11 -4
- data/app/controllers/iro/strategies_controller.rb +66 -0
- data/app/models/iro/alert.rb +15 -4
- data/app/models/iro/datapoint.rb +108 -3
- data/app/models/iro/date.rb +10 -0
- data/app/models/iro/option.rb +13 -5
- data/app/models/iro/position.rb +222 -0
- data/app/models/iro/price_item.rb +5 -2
- data/app/models/iro/purse.rb +17 -0
- data/app/models/iro/stock.rb +19 -8
- data/app/models/iro/strategy.rb +38 -0
- data/app/models/tda/option.rb +137 -0
- data/app/views/iro/_analytics.erb +16 -0
- data/app/views/iro/_main_header.haml +23 -0
- data/app/views/iro/alerts/index.haml +1 -1
- data/app/views/iro/positions/_form.haml +59 -0
- data/app/views/iro/positions/_reasons.haml +4 -0
- data/app/views/iro/positions/_table.haml +137 -0
- data/app/views/iro/positions/edit.haml +4 -0
- data/app/views/iro/positions/new.haml +4 -0
- data/app/views/iro/purses/_form.haml +9 -0
- data/app/views/iro/purses/edit.haml +3 -0
- data/app/views/iro/purses/index.haml +11 -0
- data/app/views/iro/purses/show.haml +10 -0
- data/app/views/iro/stocks/_form.haml +4 -0
- data/app/views/iro/strategies/_form.haml +37 -0
- data/app/views/iro/strategies/_header.haml +8 -0
- data/app/views/iro/strategies/_show.haml +18 -0
- data/app/views/iro/strategies/_table.haml +18 -0
- data/app/views/iro/strategies/edit.haml +3 -0
- data/app/views/iro/strategies/new.haml +3 -0
- data/app/views/layouts/iro/application.haml +48 -13
- data/config/initializers/assets.rb +10 -0
- data/config/routes.rb +6 -0
- data/lib/iron_warbler.rb +4 -1
- data/lib/tasks/db_tasks.rake +54 -1
- data/lib/tasks/iro_tasks.rake +35 -0
- data/lib/tasks/iro_tasks.rake-old +128 -0
- metadata +122 -40
- data/app/assets/stylesheets/iron_warbler/main.css +0 -13
- data/app/assets/stylesheets/scaffold.css +0 -80
- data/app/models/iro/application_record.rb +0 -4
- data/app/models/iro/profile.rb +0 -4
- data/app/views/iro/alerts/edit.html.erb +0 -6
- data/app/views/iro/alerts/new.html.erb +0 -5
- data/app/views/iro/alerts/show.html.erb +0 -34
- data/app/views/iro/profiles/_form.html.erb +0 -32
- data/app/views/iro/profiles/edit.html.erb +0 -6
- data/app/views/iro/profiles/index.html.erb +0 -31
- data/app/views/iro/profiles/new.html.erb +0 -5
- data/app/views/iro/profiles/show.html.erb +0 -19
- data/db/migrate/20231210204830_create_iro_profiles.rb +0 -12
- data/db/migrate/20231210205837_create_iro_alerts.rb +0 -16
- data/db/migrate/20231219204329_create_dates.rb +0 -13
- data/db/migrate/20231219205644_create_datapoint.rb +0 -15
- data/db/migrate/20231220193201_create_stocks.rb +0 -11
- data/db/migrate/20231220194903_add_alert_status.rb +0 -5
- data/db/migrate/20231220223730_create_iro_price_item.rb +0 -57
- /data/app/models/tda/{api.rb → stock.rb} +0 -0
@@ -0,0 +1,222 @@
|
|
1
|
+
|
2
|
+
class Iro::Position
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
store_in collection: 'iro_positions'
|
6
|
+
|
7
|
+
STATUS_ACTIVE = 'active'
|
8
|
+
STATUS_PROPOSED = 'proposed'
|
9
|
+
STATUSES = [ nil, 'active', 'inactive', 'proposed' ]
|
10
|
+
field :status
|
11
|
+
validates :status, presence: true
|
12
|
+
scope :active, ->{ where( status: 'active' ) }
|
13
|
+
|
14
|
+
belongs_to :purse, class_name: 'Iro::Purse', inverse_of: :positions
|
15
|
+
belongs_to :strategy, class_name: 'Iro::Strategy', inverse_of: :positions
|
16
|
+
|
17
|
+
field :ticker
|
18
|
+
validates :ticker, presence: true
|
19
|
+
index({ purse_id: 1, ticker: 1 })
|
20
|
+
|
21
|
+
KINDS = [ nil, 'covered_call', 'credit_put_spread', 'credit_call_spread' ]
|
22
|
+
field :kind
|
23
|
+
|
24
|
+
field :strike, type: :float
|
25
|
+
validates :strike, presence: true
|
26
|
+
|
27
|
+
field :expires_on
|
28
|
+
validates :expires_on, presence: true
|
29
|
+
|
30
|
+
field :quantity, type: :integer
|
31
|
+
validates :quantity, presence: true
|
32
|
+
|
33
|
+
field :begin_on
|
34
|
+
field :begin_price, type: :float
|
35
|
+
field :begin_delta, type: :float
|
36
|
+
|
37
|
+
field :end_on
|
38
|
+
field :end_price, type: :float
|
39
|
+
field :end_delta, type: :float
|
40
|
+
|
41
|
+
field :net_amount
|
42
|
+
field :net_percent
|
43
|
+
|
44
|
+
def current_underlying_strike
|
45
|
+
Iro::Stock.find_by( ticker: ticker ).last
|
46
|
+
end
|
47
|
+
|
48
|
+
def refresh
|
49
|
+
out = Tda::Option.get_quote({
|
50
|
+
contractType: 'CALL',
|
51
|
+
strike: strike,
|
52
|
+
expirationDate: expires_on,
|
53
|
+
ticker: ticker,
|
54
|
+
})
|
55
|
+
update({
|
56
|
+
end_delta: out[:delta],
|
57
|
+
end_price: out[:last],
|
58
|
+
})
|
59
|
+
print '_'
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
field :next_delta, type: :float
|
64
|
+
field :next_outcome, type: :float
|
65
|
+
field :next_symbol
|
66
|
+
field :next_mark
|
67
|
+
field :next_reasons, type: :array, default: []
|
68
|
+
field :should_rollp, type: :float
|
69
|
+
|
70
|
+
def should_roll?
|
71
|
+
puts! 'shold_roll?'
|
72
|
+
|
73
|
+
update({
|
74
|
+
next_reasons: [],
|
75
|
+
next_symbol: nil,
|
76
|
+
next_delta: nil,
|
77
|
+
})
|
78
|
+
|
79
|
+
if must_roll?
|
80
|
+
out = 1.0
|
81
|
+
elsif can_roll?
|
82
|
+
|
83
|
+
if end_delta < strategy.threshold_delta
|
84
|
+
next_reasons.push "delta is lower than threshold"
|
85
|
+
out = 0.91
|
86
|
+
elsif 1 - end_price/begin_price > strategy.threshold_netp
|
87
|
+
next_reasons.push "made enough percent profit (dubious)"
|
88
|
+
out = 0.61
|
89
|
+
else
|
90
|
+
next_reasons.push "neutral"
|
91
|
+
out = 0.33
|
92
|
+
end
|
93
|
+
|
94
|
+
else
|
95
|
+
out = 0.0
|
96
|
+
end
|
97
|
+
|
98
|
+
update({
|
99
|
+
next_delta: next_position[:delta],
|
100
|
+
next_outcome: next_position[:mark] - end_price,
|
101
|
+
next_symbol: next_position[:symbol],
|
102
|
+
next_mark: next_position[:mark],
|
103
|
+
should_rollp: out,
|
104
|
+
# status: Iro::Position::STATE_PROPOSED,
|
105
|
+
})
|
106
|
+
|
107
|
+
puts! next_reasons, 'next_reasons'
|
108
|
+
puts! out, 'out'
|
109
|
+
return out > 0.5
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
## expires_on = cc.expires_on ; nil
|
114
|
+
def can_roll?
|
115
|
+
## only if less than 7 days left
|
116
|
+
( expires_on.to_date - Time.now.to_date ).to_i < 7
|
117
|
+
end
|
118
|
+
|
119
|
+
## If I'm near below water
|
120
|
+
##
|
121
|
+
## expires_on = cc.expires_on ; strategy = cc.strategy ; strike = cc.strike ; nil
|
122
|
+
def must_roll?
|
123
|
+
if ( current_underlying_strike + strategy.buffer_above_water ) > strike
|
124
|
+
return true
|
125
|
+
end
|
126
|
+
## @TODO: This one should not happen, I should log appropriately. _vp_ 2023-03-19
|
127
|
+
if ( expires_on.to_date - Time.now.to_date ).to_i < 1
|
128
|
+
return true
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
## strike = cc.strike ; strategy = cc.strategy ; nil
|
133
|
+
def near_below_water?
|
134
|
+
strike < current_underlying_strike + strategy.buffer_above_water
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
## 2023-03-18 _vp_ Continue.
|
140
|
+
## 2023-03-19 _vp_ Continue.
|
141
|
+
## 2023-08-05 _vp_ an Important method
|
142
|
+
##
|
143
|
+
## expires_on = cc.expires_on ; strategy = cc.strategy ; ticker = cc.ticker ; end_price = cc.end_price ; next_expires_on = cc.next_expires_on ; nil
|
144
|
+
##
|
145
|
+
## out.map { |p| [ p[:strikePrice], p[:delta] ] }
|
146
|
+
##
|
147
|
+
def next_position
|
148
|
+
return @next_position if @next_position
|
149
|
+
return {} if ![ STATUS_ACTIVE, STATUS_PROPOSED ].include?( status )
|
150
|
+
|
151
|
+
## 7 days ahead - not configurable so far
|
152
|
+
out = Tda::Option.get_quotes({
|
153
|
+
ticker: ticker,
|
154
|
+
expirationDate: next_expires_on,
|
155
|
+
contractType: 'CALL',
|
156
|
+
})
|
157
|
+
|
158
|
+
## above_water
|
159
|
+
if strategy.buffer_above_water.present?
|
160
|
+
out = out.select do |i|
|
161
|
+
i[:strikePrice] > current_underlying_strike + strategy.buffer_above_water
|
162
|
+
end
|
163
|
+
# next_reasons.push "buffer_above_water above #{current_underlying_strike + strategy.buffer_above_water}"
|
164
|
+
end
|
165
|
+
|
166
|
+
if near_below_water?
|
167
|
+
msg = "Panic! climb at a loss. Skip the rest of the calculation."
|
168
|
+
next_reasons.push msg
|
169
|
+
## @TODO: if not enough money in the purse, cannot roll? 2023-03-19
|
170
|
+
|
171
|
+
# byebug
|
172
|
+
|
173
|
+
## Take a small loss here.
|
174
|
+
prev = nil
|
175
|
+
out.each_with_index do |i, idx|
|
176
|
+
next if idx == 0
|
177
|
+
if i[:last] < end_price
|
178
|
+
prev ||= i
|
179
|
+
end
|
180
|
+
end
|
181
|
+
out = [ prev ]
|
182
|
+
|
183
|
+
else
|
184
|
+
## Normal flow, making money.
|
185
|
+
## @TODO: test! _vp_ 2023-03-19
|
186
|
+
|
187
|
+
## next_min_strike
|
188
|
+
if strategy.next_min_strike.present?
|
189
|
+
out = out.select do |i|
|
190
|
+
i[:strikePrice] >= strategy.next_min_strike
|
191
|
+
end
|
192
|
+
# next_reasons.push "next_min_strike above #{strategy.next_min_strike}"
|
193
|
+
end
|
194
|
+
# json_puts! out.map { |p| [p[:delta], p[:symbol]] }, 'next_min_strike'
|
195
|
+
|
196
|
+
## max_delta
|
197
|
+
if strategy.next_max_delta.present?
|
198
|
+
out = out.select do |i|
|
199
|
+
i[:delta] = 0.0 if i[:delta] == "NaN"
|
200
|
+
i[:delta] <= strategy.next_max_delta
|
201
|
+
end
|
202
|
+
# next_reasons.push "next_max_delta below #{strategy.next_max_delta}"
|
203
|
+
end
|
204
|
+
# json_puts! out.map { |p| [p[:delta], p[:symbol]] }, 'next_max_delta'
|
205
|
+
end
|
206
|
+
|
207
|
+
@next_position = out[0] || {}
|
208
|
+
end
|
209
|
+
|
210
|
+
## @TODO: Test this. _vp_ 2023-04-01
|
211
|
+
def next_expires_on
|
212
|
+
out = expires_on.to_time + 7.days
|
213
|
+
while !out.friday?
|
214
|
+
out = out + 1.day
|
215
|
+
end
|
216
|
+
while !out.workday?
|
217
|
+
out = out - 1.day
|
218
|
+
end
|
219
|
+
return out
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
class Iro::Purse
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
store_in collection: 'iro_purses'
|
6
|
+
|
7
|
+
field :slug
|
8
|
+
validates :slug, presence: true, uniqueness: true
|
9
|
+
index({ slug: -1 }, { unique: true })
|
10
|
+
|
11
|
+
has_many :positions, class_name: 'Iro::Position', inverse_of: :purse
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
slug
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/app/models/iro/stock.rb
CHANGED
@@ -1,18 +1,29 @@
|
|
1
1
|
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
self.table_name = 'iro_stocks'
|
2
|
+
class Iro::Stock
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
store_in collection: 'iro_stocks'
|
7
6
|
|
8
7
|
STATUS_ACTIVE = 'active'
|
9
8
|
STATUS_INACTIVE = 'inactive'
|
10
|
-
STATUSES = [ 'active', 'inactive' ]
|
9
|
+
STATUSES = [ nil, 'active', 'inactive' ]
|
10
|
+
def self.active
|
11
|
+
where( status: STATUS_ACTIVE )
|
12
|
+
end
|
13
|
+
field :status
|
11
14
|
|
15
|
+
field :ticker
|
12
16
|
validates :ticker, uniqueness: true, presence: true
|
13
17
|
|
14
|
-
|
15
|
-
|
18
|
+
field :last, type: :float
|
19
|
+
|
20
|
+
def self.list
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.tickers_list
|
24
|
+
[nil] + all.map( &:ticker )
|
16
25
|
end
|
17
26
|
|
27
|
+
# has_many :strategies, class_name: 'Iro::Strategy', inverse_of: :stock
|
28
|
+
|
18
29
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
class Iro::Strategy
|
3
|
+
include Mongoid::Document
|
4
|
+
include Mongoid::Timestamps
|
5
|
+
store_in collection: 'iro_strategies'
|
6
|
+
|
7
|
+
field :slug
|
8
|
+
validates :slug, presence: true, uniqueness: true
|
9
|
+
|
10
|
+
has_many :positions, class_name: 'Iro::Position', inverse_of: :strategy
|
11
|
+
|
12
|
+
## multiple strategies per ticker
|
13
|
+
field :ticker
|
14
|
+
validates :ticker, presence: true
|
15
|
+
index({ ticker: 1 })
|
16
|
+
# belongs_to :stock, class_name: 'Iro::Stock', inverse_of: :strategies
|
17
|
+
|
18
|
+
|
19
|
+
field :buffer_above_water, type: :float
|
20
|
+
field :next_max_delta, type: :float
|
21
|
+
field :next_min_strike, type: :float
|
22
|
+
field :threshold_delta, type: :float
|
23
|
+
field :threshold_netp, type: :float
|
24
|
+
|
25
|
+
def self.for_ticker ticker
|
26
|
+
where( ticker: ticker )
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
slug
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.list
|
35
|
+
[[nil,nil]] + all.map { |ttt| [ ttt.slug, ttt.id ] }
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
|
2
|
+
require 'httparty'
|
3
|
+
|
4
|
+
class Tda::Option
|
5
|
+
|
6
|
+
include ::HTTParty
|
7
|
+
base_uri 'https://api.tdameritrade.com'
|
8
|
+
|
9
|
+
|
10
|
+
##
|
11
|
+
## 2023-02-05 _vp_ :: Gets the entire chain
|
12
|
+
##
|
13
|
+
def self.get_chain params
|
14
|
+
opts = { symbol: params[:ticker] } ## use 'GME' as symbol here even though a symbol is eg 'GME_021023P2.5'
|
15
|
+
query = { apikey: ::TD_AMERITRADE[:apiKey] }.merge opts
|
16
|
+
# puts! query, 'input opts'
|
17
|
+
|
18
|
+
path = "/v1/marketdata/chains"
|
19
|
+
out = self.get path, { query: query }
|
20
|
+
timestamp = DateTime.parse out.headers['date']
|
21
|
+
out = out.parsed_response.deep_symbolize_keys
|
22
|
+
|
23
|
+
|
24
|
+
outs = []
|
25
|
+
%w| put call |.each do |contractType|
|
26
|
+
tmp_sym = "#{contractType}ExpDateMap".to_sym
|
27
|
+
_out = out[tmp_sym]
|
28
|
+
_out.each do |date, vs| ## date="2023-02-10:5"
|
29
|
+
vs.each do |strike, _v| ## strike="18.5"
|
30
|
+
v = _v[0] ## v={} many attrs
|
31
|
+
v = v.except( :lastSize, :optionDeliverablesList, :settlementType,
|
32
|
+
:deliverableNote, :pennyPilot, :mini )
|
33
|
+
v.each do |k, i|
|
34
|
+
if i == 'NaN'
|
35
|
+
v[k] = nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
v[:timestamp] = timestamp
|
40
|
+
v[:ticker] = params[:ticker]
|
41
|
+
outs.push( v )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
outs.each do |x|
|
47
|
+
opi = ::Iro::OptionPriceItem.create( x )
|
48
|
+
if !opi.persisted?
|
49
|
+
puts! opi.errors.full_messages, "Cannot create OptionPriceItem"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
## 2023-03-18 _vp_ This is what I should be using to check if a position should be rolled.
|
56
|
+
##
|
57
|
+
def self.get_quote params
|
58
|
+
::Tda::Option.get_quotes(params)[0]
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
## params: contractType, strike, expirationDate, ticker
|
63
|
+
##
|
64
|
+
## ow = { contractType: 'PUT', ticker: 'GME', date: '2022-12-09' }
|
65
|
+
## query = {:apikey=>"<>", :toDate=>"2022-12-09", :fromDate=>"2022-12-09", :symbol=>"GME"}
|
66
|
+
##
|
67
|
+
## 2023-02-04 _vp_ :: Too specific, but I want the entire chain, every 1-min
|
68
|
+
## 2023-02-06 _vp_ :: Continue.
|
69
|
+
##
|
70
|
+
def self.get_quotes params
|
71
|
+
puts! params, 'Tda::Option#get_quotes'
|
72
|
+
opts = {}
|
73
|
+
|
74
|
+
#
|
75
|
+
# Validate input ???
|
76
|
+
#
|
77
|
+
validOpts = %i| contractType |
|
78
|
+
validOpts.each do |s|
|
79
|
+
if params[s]
|
80
|
+
opts[s] = params[s]
|
81
|
+
else
|
82
|
+
raise Iwa::InputError.new("Invalid input, missing '#{s}'.")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
if params[:expirationDate]
|
86
|
+
opts[:fromDate] = opts[:toDate] = params[:expirationDate]
|
87
|
+
else
|
88
|
+
raise Iwa::InputError.new("Invalid input, missing 'date'.")
|
89
|
+
end
|
90
|
+
if params[:ticker]
|
91
|
+
opts[:symbol] = params[:ticker].upcase
|
92
|
+
else
|
93
|
+
raise Iwa::InputError.new("Invalid input, missing 'ticker'.")
|
94
|
+
end
|
95
|
+
|
96
|
+
if params[:strike]
|
97
|
+
opts[:strike] = params[:strike]
|
98
|
+
end
|
99
|
+
|
100
|
+
query = { apikey: ::TD_AMERITRADE[:apiKey] }.merge opts
|
101
|
+
# puts! query, 'input opts'
|
102
|
+
|
103
|
+
path = "/v1/marketdata/chains"
|
104
|
+
out = self.get path, { query: query }
|
105
|
+
timestamp = DateTime.parse out.headers['date']
|
106
|
+
## out = HTTParty.get "https://api.tdameritrade.com#{path}", { query: query }
|
107
|
+
out = out.parsed_response.deep_symbolize_keys
|
108
|
+
|
109
|
+
|
110
|
+
tmp_sym = "#{opts[:contractType].to_s.downcase}ExpDateMap".to_sym
|
111
|
+
outs = []
|
112
|
+
out = out[tmp_sym]
|
113
|
+
out.each do |date, vs|
|
114
|
+
vs.each do |strike, _v|
|
115
|
+
v = _v[0]
|
116
|
+
v = v.except( :lastSize, :optionDeliverablesList, :settlementType,
|
117
|
+
:deliverableNote, :pennyPilot, :mini )
|
118
|
+
v[:timestamp] = timestamp
|
119
|
+
outs.push( v )
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# puts! outs, 'outs'
|
124
|
+
return outs
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
=begin
|
131
|
+
|
132
|
+
outs = Tda::Option.get_quotes({
|
133
|
+
contractType: 'CALL', strike: 20.0, expirationDate: '2024-01-12',
|
134
|
+
ticker: 'GME',
|
135
|
+
})
|
136
|
+
|
137
|
+
=end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
<!-- Matomo -->
|
3
|
+
<script>
|
4
|
+
var _paq = window._paq = window._paq || [];
|
5
|
+
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
6
|
+
_paq.push(['trackPageView']);
|
7
|
+
_paq.push(['enableLinkTracking']);
|
8
|
+
(function() {
|
9
|
+
var u="//analytics.wasya.co/";
|
10
|
+
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
11
|
+
_paq.push(['setSiteId', '13']); /* 13 :: email.wasya.co */
|
12
|
+
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
13
|
+
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
14
|
+
})();
|
15
|
+
</script>
|
16
|
+
<!-- End Matomo Code -->
|
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
.main-header.maxwidth
|
3
|
+
|
4
|
+
%i.fa.fa-compress.collapse-expand#collapseHeaderEmail
|
5
|
+
Iron Warbler
|
6
|
+
|
7
|
+
-# .header.collapse-expand#IroMenu
|
8
|
+
-# %h5.title Iron Warbler
|
9
|
+
|
10
|
+
%ul
|
11
|
+
%li= link_to 'ROOT', root_path
|
12
|
+
%li
|
13
|
+
= link_to "Stocks (#{Iro::Stock.all.length})", stocks_path
|
14
|
+
-# %li= link_to 'Options', options_path
|
15
|
+
-# %li Max Pain
|
16
|
+
%li
|
17
|
+
= link_to "Alerts (#{Iro::Alert.all.length})", alerts_path
|
18
|
+
%li
|
19
|
+
= link_to "Purses (#{Iro::Purse.all.length})", purses_path
|
20
|
+
%li
|
21
|
+
= render '/iro/strategies/header'
|
22
|
+
|
23
|
+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
|
2
|
+
.positions--form
|
3
|
+
= form_for position do |f|
|
4
|
+
.actions
|
5
|
+
= f.submit
|
6
|
+
|
7
|
+
.field
|
8
|
+
%label Purse
|
9
|
+
-# = f.select :purse_id, options_for_select( @
|
10
|
+
= f.text_field :purse_id
|
11
|
+
|
12
|
+
%label Status
|
13
|
+
= f.select :status, options_for_select( Iro::Position::STATUSES, selected: position.status )
|
14
|
+
|
15
|
+
%br
|
16
|
+
%br
|
17
|
+
|
18
|
+
.field
|
19
|
+
%label Ticker
|
20
|
+
= f.select :ticker, options_for_select( @tickers_list, selected: position.ticker )
|
21
|
+
|
22
|
+
|
23
|
+
%label Kind
|
24
|
+
= f.select :kind, options_for_select( Iro::Position::KINDS, selected: position.kind )
|
25
|
+
%label Strategy
|
26
|
+
= f.select :strategy_id, options_for_select( @strategies_list, selected: position.strategy_id )
|
27
|
+
|
28
|
+
|
29
|
+
%label Strike
|
30
|
+
= f.text_field :strike
|
31
|
+
|
32
|
+
.field
|
33
|
+
%label Expires on
|
34
|
+
= f.text_field :expires_on
|
35
|
+
|
36
|
+
|
37
|
+
%label Quantity
|
38
|
+
= f.text_field :quantity
|
39
|
+
|
40
|
+
%br
|
41
|
+
%br
|
42
|
+
|
43
|
+
.flex-row
|
44
|
+
%label Begin on
|
45
|
+
= f.text_field :begin_on
|
46
|
+
%label Begin price
|
47
|
+
= f.text_field :begin_price
|
48
|
+
%label Begin delta
|
49
|
+
= f.text_field :begin_delta
|
50
|
+
.flex-row
|
51
|
+
%label End on
|
52
|
+
= f.text_field :end_on
|
53
|
+
%label End price
|
54
|
+
= f.text_field :end_price
|
55
|
+
%label End delta
|
56
|
+
= f.text_field :end_delta
|
57
|
+
|
58
|
+
.actions
|
59
|
+
= f.submit
|