cotcube-level 0.3.2 → 0.3.3
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/CHANGELOG.md +8 -0
- data/VERSION +1 -1
- data/lib/cotcube-level/eod_stencil.rb +2 -2
- data/lib/cotcube-level/helpers.rb +73 -31
- data/lib/cotcube-level/tritangulate.rb +6 -3
- 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: 9a349cee7bdea128658af11ee026dcc2ff995d711c930c5ee188396b1cca045a
|
4
|
+
data.tar.gz: edc2b404b579336d585efeba20b12d8e2572ae3242a939aa060c286b405eee4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e395bcc4db6052b95b08a1daad0d3ed1b344f533aa779d257de64ba205daf23ccc40853e284ff55dace36c8d3e4e6053e2694a37cee75def861c29e8cab28efe
|
7
|
+
data.tar.gz: c6e059bd6dfbac4a4a4e3da069ff557f9ebecf46596983f056c78c6675447f6a3cd3eedde2b0ad2f48f9552c1e5bc01ba3fc2057a5f81f4129db3360d501ce50
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## 0.3.3 (October 05, 2021)
|
2
|
+
- helpers::load_swaps: added :exceed to allow 1(sic) swap to be exceeded while loading
|
3
|
+
- tritangulate: added :manual for feature of manual swap creation with base of 2 members
|
4
|
+
- helpers::load_swap added :digest to filter for swaps starting with pattern
|
5
|
+
- helpers: minor readability improvements
|
6
|
+
- eod_stencil: minor readability improvements
|
7
|
+
- helpers: few optimizations
|
8
|
+
|
1
9
|
## 0.3.2 (August 29, 2021)
|
2
10
|
- tritangulate: fixing 'finalize', as Integer zero won't comparte to Float zero
|
3
11
|
- cotcube-level.rb: added :check_exceedance
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.3
|
@@ -146,10 +146,10 @@ module Cotcube
|
|
146
146
|
ohlc = high ? :high : :low
|
147
147
|
start = base.find{|x| swap[:datetime] == x[:datetime]}
|
148
148
|
swap[:current_change] = (swap[:tpi] * start[:x]).round(8)
|
149
|
-
swap[:current_value] =
|
149
|
+
swap[:current_value] = swap[:members].last[ ohlc ] + swap[:current_change] * sym[:ticksize]
|
150
150
|
swap[:current_diff] = (swap[:current_value] - zero[ohlc]) * (high ? 1 : -1 )
|
151
151
|
swap[:current_dist] = (swap[:current_diff] / sym[:ticksize]).to_i
|
152
|
-
swap[:exceeded] =
|
152
|
+
swap[:exceeded] = zero[:datetime] if swap[:current_dist] < grace
|
153
153
|
swap
|
154
154
|
end
|
155
155
|
end
|
@@ -24,14 +24,14 @@ module Cotcube
|
|
24
24
|
# human readable output
|
25
25
|
# please note the format must be given, that should be taken from :sym
|
26
26
|
def member_to_human(member,side: ,format:, daily: false)
|
27
|
-
high = side == :upper
|
28
|
-
"#{member[:datetime].strftime("%a, %Y-%m-%d#{daily ? "" :" %I:%M%p"}")
|
29
|
-
} x: #{format '%-4d',
|
27
|
+
high = (side == :upper)
|
28
|
+
"#{ member[:datetime].strftime("%a, %Y-%m-%d#{daily ? "" :" %I:%M%p"}")
|
29
|
+
} x: #{format '%-4d', member[:x]
|
30
30
|
} dx: #{format '%-8.3f', (member[:dx].nil? ? member[:x] : member[:dx].round(3))
|
31
31
|
} #{high ? "high" : "low"
|
32
|
-
}: #{format format,
|
33
|
-
} i: #{(format '%4d',
|
34
|
-
} d: #{format '%6.2f',
|
32
|
+
}: #{format format, member[high ? :high : :low]
|
33
|
+
} i: #{(format '%4d', member[:i]) unless member[:i].nil?
|
34
|
+
} d: #{format '%6.2f', member[:dev] unless member[:dev].nil?
|
35
35
|
} #{member[:near].nil? ? '' : "near: #{member[:near]}"
|
36
36
|
}"
|
37
37
|
end
|
@@ -40,22 +40,23 @@ module Cotcube
|
|
40
40
|
# format: e.g. sym[:format]
|
41
41
|
# short: print one line / less verbose
|
42
42
|
# notice: add this to output as well
|
43
|
-
def puts_swap(swap, format: , short:
|
43
|
+
def puts_swap(swap, format: , short: true, notice: nil, hash: 3)
|
44
44
|
return if swap[:empty]
|
45
|
-
daily = %i[ continuous daily ].include?(swap[:interval])
|
45
|
+
daily = %i[ continuous daily ].include?(swap[:interval].to_sym)
|
46
46
|
datetime_format = daily ? '%Y-%m-%d' : '%Y-%m-%d %H:%M'
|
47
47
|
high = swap[:side] == :high
|
48
48
|
ohlc = high ? :high : :low
|
49
49
|
if short
|
50
|
-
puts "
|
51
|
-
|
52
|
-
}
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
56
|
-
}
|
57
|
-
}
|
58
|
-
}#{
|
50
|
+
puts (hash ? "#{swap[:digest][...hash]} ".colorize(:light_white) : '') +
|
51
|
+
"S: #{swap[:side]
|
52
|
+
} L: #{ format '%4d', swap[:length]
|
53
|
+
} R: #{ format '%4d', swap[:rating]
|
54
|
+
} D: #{ format '%4d', swap[:depth]
|
55
|
+
} P: #{ format '%10s', (format '%5.2f', swap[:ppi])
|
56
|
+
} F: #{ format format, swap[:members].last[ ohlc ]
|
57
|
+
} S: #{ swap[:members].first[:datetime].strftime(datetime_format)
|
58
|
+
} - #{ swap[:members].last[:datetime].strftime(datetime_format)
|
59
|
+
}#{ format('%20s', (swap[:exceeded] ? " XXX: #{swap[:exceeded].strftime(datetime_format)}" : ''))
|
59
60
|
}#{" NOTE: #{notice}" unless notice.nil?}".colorize(swap[:color] || :white )
|
60
61
|
else
|
61
62
|
puts "side: #{swap[:side] }\tlen: #{swap[:length]} \trating: #{swap[:rating]}".colorize(swap[:color] || :white )
|
@@ -114,7 +115,7 @@ module Cotcube
|
|
114
115
|
|
115
116
|
# loading of swaps is also straight forward
|
116
117
|
# it takes few more efforts to normalize the values to their expected format
|
117
|
-
def load_swaps(interval:, swap_type:, contract:, sym: nil, datetime: nil)
|
118
|
+
def load_swaps(interval:, swap_type:, contract:, sym: nil, datetime: nil, recent: false, digest: nil, quiet: false, exceed: false)
|
118
119
|
file = get_jsonl_name(interval: interval, swap_type: swap_type, contract: contract, sym: sym)
|
119
120
|
jsonl = File.read(file)
|
120
121
|
data = jsonl.
|
@@ -123,22 +124,22 @@ module Cotcube
|
|
123
124
|
JSON.parse(x).
|
124
125
|
deep_transform_keys(&:to_sym).
|
125
126
|
tap do |sw|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
127
|
+
sw[:datetime] = DateTime.parse(sw[:datetime]) rescue nil
|
128
|
+
(sw[:exceeded] = DateTime.parse(sw[:exceeded]) rescue nil) if sw[:exceeded]
|
129
|
+
sw[:interval] = interval
|
130
|
+
sw[:swap_type] = swap_type
|
131
|
+
sw[:contract] = contract
|
132
|
+
%i[ side ].each {|key| sw[key] = sw[key].to_sym rescue false }
|
133
|
+
unless sw[:empty] or sw[:exceeded]
|
134
|
+
sw[:color] = sw[:color].to_sym
|
135
|
+
sw[:members].map{|mem| mem[:datetime] = DateTime.parse(mem[:datetime]) }
|
136
|
+
end
|
136
137
|
end
|
137
138
|
end
|
138
139
|
# assign exceedance data to actual swaps
|
139
140
|
data.select{|swap| swap[:exceeded] }.each do |exc|
|
140
141
|
swap = data.find{|ref| ref[:digest] == exc[:ref]}
|
141
|
-
raise RuntimeError, "
|
142
|
+
raise RuntimeError, "Inconsistent history for '#{exc}'. Origin not found." if swap.nil?
|
142
143
|
swap[:exceeded] = exc[:exceeded]
|
143
144
|
end
|
144
145
|
# do not return bare exceedance information
|
@@ -146,9 +147,38 @@ module Cotcube
|
|
146
147
|
# do not return swaps that are found 'later'
|
147
148
|
data.reject!{|swap| swap[:datetime] > datetime } unless datetime.nil?
|
148
149
|
# do not return exceeded swaps, that are exceeded in the past
|
149
|
-
|
150
|
+
recent = 7.days if recent.is_a? TrueClass
|
151
|
+
recent += 5.hours if recent
|
152
|
+
data.reject!{|swap| swap[:exceeded] and swap[:exceeded] < datetime - (recent ? recent : 0) } unless datetime.nil?
|
150
153
|
# remove exceedance information that is found 'later'
|
151
|
-
data.map{|swap| swap.delete(:exceeded) if swap[:exceeded] and swap[:exceeded] > datetime}
|
154
|
+
data.map{|swap| swap.delete(:exceeded) if swap[:exceeded] and swap[:exceeded] > datetime} unless datetime.nil?
|
155
|
+
unless digest.nil?
|
156
|
+
data.select! do |z|
|
157
|
+
(Cotcube::Helpers.sub(minimum: digest.length){ z[:digest] } === digest) and
|
158
|
+
not z[:empty]
|
159
|
+
end
|
160
|
+
case data.size
|
161
|
+
when 0
|
162
|
+
puts "No swaps found for digest '#{digest}'." unless quiet
|
163
|
+
when 1
|
164
|
+
sym ||= Cotcube::Helpers.get_id_set(contract: contract)
|
165
|
+
if not quiet or exceed
|
166
|
+
puts "Found 1 digest: "
|
167
|
+
data.each {|d| puts_swap( d, format: sym[:format], short: true, hash: digest.size + 2) }
|
168
|
+
if exceed
|
169
|
+
exceed = DateTime.now if exceed.is_a? TrueClass
|
170
|
+
mark_exceeded(swap: data.first, datetime: exceed)
|
171
|
+
puts "Swap marked exceeded."
|
172
|
+
end
|
173
|
+
end
|
174
|
+
else
|
175
|
+
sym ||= Cotcube::Helpers.get_id_set(contract: contract)
|
176
|
+
unless quiet
|
177
|
+
puts "Too many digests found for digest '#{digest}', please consider sending more figures: "
|
178
|
+
data.each {|d| puts_swap( d, format: sym[:format], short: true, hash: digest.size + 3)}
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
152
182
|
data
|
153
183
|
end
|
154
184
|
|
@@ -175,6 +205,18 @@ module Cotcube
|
|
175
205
|
end.compact
|
176
206
|
end
|
177
207
|
|
208
|
+
def mark_exceeded(swap:, datetime:, debug: false)
|
209
|
+
to_save = {
|
210
|
+
datetime: datetime,
|
211
|
+
ref: swap[:digest],
|
212
|
+
side: swap[:side],
|
213
|
+
exceeded: datetime
|
214
|
+
}
|
215
|
+
save_swaps to_save, interval: swap[:interval], swap_type: swap[:swap_type], sym: Cotcube::Helpers.get_id_set(contract: swap[:contract]), contract: swap[:contract], quiet: (not debug)
|
216
|
+
swap[:exceeded] = datetime
|
217
|
+
swap
|
218
|
+
end
|
219
|
+
|
178
220
|
end
|
179
221
|
end
|
180
222
|
|
@@ -19,6 +19,7 @@ module Cotcube
|
|
19
19
|
swap_type: nil, # if not given, a warning is printed and swaps won't be saved or loaded
|
20
20
|
with_flaws: 0, # the maximum amount of consecutive bars that would actually break the current swap
|
21
21
|
# should be set to 0 for dailies and I suggest no more than 3 for intraday
|
22
|
+
manual: false, # some triggers must be set differently when manual entry is used
|
22
23
|
deviation: 2 # the maximum shift of :x-values of found members
|
23
24
|
)
|
24
25
|
|
@@ -70,8 +71,10 @@ module Cotcube
|
|
70
71
|
|
71
72
|
# abs_peak is the absolute high / low of the base. the shearing operation ends there,
|
72
73
|
# but results might be influenced when abs_peak becomes affected by :with_flaws
|
73
|
-
|
74
|
-
|
74
|
+
unless manual
|
75
|
+
abs_peak = base.send(high ? :max_by : :min_by){|x| x[high ? :high : :low] }[:datetime]
|
76
|
+
base.reject!{|x| x[:datetime] < abs_peak}
|
77
|
+
end
|
75
78
|
|
76
79
|
###########################################################################################################################z
|
77
80
|
# only if (and only if) the range portion above change the underlying base
|
@@ -155,7 +158,7 @@ module Cotcube
|
|
155
158
|
# first member is solitary
|
156
159
|
if new_members.empty?
|
157
160
|
mem_sorted=members.sort
|
158
|
-
if mem_sorted[1] == mem_sorted[0] + 1
|
161
|
+
if mem_sorted[1] == mem_sorted[0] + 1 and not manual
|
159
162
|
b2 = b[mem_sorted[1]..mem_sorted[-1]].map{|x| x.dup; x[:dx] = nil; x}
|
160
163
|
puts 'starting recursive rerun'.light_red if debug
|
161
164
|
alternative_slope = get_slope.call(b2)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cotcube-level
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin L. Tischendorf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|