spanbars 0.1.2beta
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 +7 -0
- data/README.md +69 -0
- data/bin/spanbars +97 -0
- data/features/01_spanbarprocessor_initialization.feature +29 -0
- data/features/02_spanbarprocessor_add.feature +40 -0
- data/features/03_spanbar_initialization.feature +30 -0
- data/features/04_spanbars_commandline.feature +19 -0
- data/features/step_definitions/01_spanbar_processor_initialization_steps.rb +36 -0
- data/features/step_definitions/02_spanbarprocessor_add_steps.rb +42 -0
- data/features/step_definitions/03_spanbar_initialization_steps.rb +18 -0
- data/features/step_definitions/04_spanbars_commandline_steps.rb +26 -0
- data/features/support/env.rb +6 -0
- data/features/support/ref1.csv +51464 -0
- data/features/support/ref1_out_0.25_25.csv +296 -0
- data/features/support/ref2.csv +6358 -0
- data/features/support/ref2_out_1_25.csv +28 -0
- data/features/support/ref3.csv +3566 -0
- data/features/support/ref3_out_0.0000005_10.csv +47 -0
- data/lib/spanbar.rb +147 -0
- data/lib/spanbarprocessor.rb +196 -0
- metadata +162 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
simple,1555027810103,0.009,1555028866704,0.0090015,1555028361598,0.0089965,1555028866704,0.0090015,1056,3.65e-05,3.0e-08,3,bottom
|
2
|
+
strict,1555028361598,0.0089965,1555028875619,0.0090015,514,2.2e-05,4.0e-08,10,up
|
3
|
+
simple,1555028868208,0.009001,1555028875619,0.0090015,1555029270853,0.0089965,1555029270853,0.0089965,402,1.65e-05,4.0e-08,-9,top
|
4
|
+
strict,1555028875620,0.0090015,1555029674690,0.0089945,799,4.4e-05,6.0e-08,-13,down
|
5
|
+
simple,1555029271053,0.008997,1555030003672,0.009,1555029674690,0.0089945,1555030003672,0.009,732,4.2e-05,6.0e-08,5,bottom
|
6
|
+
strict,1555029674691,0.0089945,1555030015594,0.0090005,340,1.6e-05,5.0e-08,11,up
|
7
|
+
simple,1555030007679,0.0089995,1555030015594,0.0090005,1555030283081,0.008995,1555030283081,0.008995,275,1.65e-05,6.0e-08,-9,top
|
8
|
+
simple,1555030284285,0.0089955,1555030318652,0.008997,1555030344002,0.0089905,1555030344002,0.0089905,59,1.6e-05,2.7e-07,-9,top
|
9
|
+
simple,1555030344202,0.008991,1555030399708,0.008994,1555030421650,0.008988,1555030421650,0.008988,77,1.9e-05,2.5e-07,-6,top
|
10
|
+
strict,1555030015595,0.0090005,1555030424755,0.008988,409,5.35e-05,1.3e-07,-24,down
|
11
|
+
simple,1555030421750,0.0089885,1555030479161,0.0089935,1555030424755,0.008988,1555030479161,0.0089935,57,1.4e-05,2.5e-07,9,bottom
|
12
|
+
simple,1555030487477,0.0089925,1555030508723,0.0089955,1555030492488,0.00899,1555030508723,0.0089955,21,1.8e-05,8.6e-07,5,bottom
|
13
|
+
strict,1555030424756,0.008988,1555030678129,0.0089965,253,5.25e-05,2.1e-07,16,up
|
14
|
+
simple,1555030508824,0.008995,1555030678129,0.0089965,1555030801155,0.008991,1555030801155,0.008991,292,3.4e-05,1.2e-07,-7,top
|
15
|
+
simple,1555030801856,0.0089915,1555030913566,0.0089945,1555031382526,0.0089895,1555031382526,0.0089895,580,2.0e-05,3.0e-08,-4,top
|
16
|
+
strict,1555030678130,0.0089965,1555031563056,0.0089875,884,4.7e-05,5.0e-08,-17,down
|
17
|
+
simple,1555031385132,0.00899,1555032144345,0.008993,1555031563056,0.0089875,1555032144345,0.008993,759,2.9e-05,4.0e-08,5,bottom
|
18
|
+
simple,1555032154368,0.0089935,1555034282118,0.0089965,1555032392101,0.008991,1555034282118,0.0089965,2127,4.5e-05,2.0e-08,5,bottom
|
19
|
+
strict,1555031563057,0.0089875,1555036341361,0.0089975,4778,0.000101,2.0e-08,19,up
|
20
|
+
simple,1555034340129,0.008996,1555036341361,0.0089975,1555039961893,0.008992,1555039961893,0.008992,5621,8.0e-05,1.0e-08,-8,top
|
21
|
+
simple,1555039967000,0.0089915,1555043323622,0.008995,1555047080899,0.0089895,1555047080899,0.0089895,7113,8.1e-05,1.0e-08,-4,top
|
22
|
+
strict,1555036341362,0.0089975,1555047900711,0.008986,11559,0.0001415,1.0e-08,-22,down
|
23
|
+
simple,1555047086109,0.00899,1555049115751,0.008991,1555047900711,0.008986,1555049115751,0.008991,2029,4.1e-05,2.0e-08,2,bottom
|
24
|
+
strict,1555047900712,0.008986,1555049115751,0.008991,1215,2.3e-05,2.0e-08,9,up
|
25
|
+
simple,1555049144807,0.0089905,1555049285467,0.0089905,1555050220412,0.008985,1555050220412,0.008985,1075,2.45e-05,2.0e-08,-11,down
|
26
|
+
simple,1555050221113,0.0089855,1555051580965,0.008988,1555054260302,0.0089825,1555054260302,0.0089825,4039,8.4e-05,2.0e-08,-6,top
|
27
|
+
simple,1555054282243,0.008983,1555055459355,0.0089855,1555056264677,0.0089795,1555056264677,0.0089795,1982,4.45e-05,2.0e-08,-7,top
|
28
|
+
strict,1555049115752,0.008991,1555058550101,0.0089755,9434,0.0002295,2.0e-08,-31,down
|
29
|
+
simple,1555056264776,0.008979,1555060529342,0.008981,1555058550101,0.0089755,1555060529342,0.008981,4264,0.00012,3.0e-08,4,bottom
|
30
|
+
strict,1555058550102,0.0089755,1555061122664,0.008985,2572,6.05e-05,2.0e-08,18,up
|
31
|
+
simple,1555060537257,0.0089815,1555061122664,0.008985,1555062281053,0.0089795,1555062281053,0.0089795,1743,3.9e-05,2.0e-08,-4,top
|
32
|
+
simple,1555062289070,0.00898,1555063319883,0.0089815,1555065802473,0.008976,1555065802473,0.008976,3513,8.6e-05,2.0e-08,-8,top
|
33
|
+
simple,1555065836939,0.0089765,1555066423283,0.008979,1555069022947,0.0089735,1555069022947,0.0089735,3186,7.0e-05,2.0e-08,-5,top
|
34
|
+
strict,1555061122665,0.008985,1555069050906,0.0089735,7928,0.0001825,2.0e-08,-22,down
|
35
|
+
simple,1555069039183,0.008974,1555072066248,0.008979,1555069050906,0.0089735,1555072066248,0.008979,3027,8.4e-05,3.0e-08,9,bottom
|
36
|
+
strict,1555069050907,0.0089735,1555072173333,0.008979,3122,8.75e-05,3.0e-08,10,up
|
37
|
+
simple,1555072070359,0.0089785,1555072173333,0.008979,1555072345801,0.0089735,1555072345801,0.0089735,275,1.6e-05,6.0e-08,-9,top
|
38
|
+
strict,1555072173334,0.008979,1555072989884,0.008973,816,4.0e-05,5.0e-08,-11,down
|
39
|
+
simple,1555072349612,0.008974,1555074429826,0.0089785,1555072989884,0.008973,1555074429826,0.0089785,2080,5.15e-05,2.0e-08,9,bottom
|
40
|
+
simple,1555074484800,0.008978,1555077606252,0.008981,1555076788548,0.0089755,1555077606252,0.008981,3121,8.0e-05,3.0e-08,5,bottom
|
41
|
+
strict,1555072989885,0.008973,1555077646209,0.0089845,4656,0.0001125,2.0e-08,22,up
|
42
|
+
simple,1555077609865,0.0089805,1555077646209,0.0089845,1555080336231,0.008979,1555080336231,0.008979,2726,0.0001085,4.0e-08,-3,top
|
43
|
+
simple,1555080341046,0.0089795,1555080428210,0.0089805,1555080984657,0.008975,1555080984657,0.008975,643,2.45e-05,4.0e-08,-8,top
|
44
|
+
simple,1555080994388,0.0089755,1555082504200,0.008977,1555084253820,0.0089715,1555084253820,0.0089715,3259,0.000118,4.0e-08,-8,top
|
45
|
+
simple,1555084253921,0.008971,1555084551227,0.008974,1555095538507,0.0089685,1555095538507,0.0089685,11284,0.0001765,2.0e-08,-4,top
|
46
|
+
strict,1555077646210,0.0089845,1555095737956,0.0089655,18091,0.000441,2.0e-08,-37,down
|
47
|
+
simple,1555095544426,0.008967,1555098169130,0.008971,1555095737956,0.0089655,1555098169130,0.008971,2624,8.2e-05,3.0e-08,8,bottom
|
data/lib/spanbar.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# A model for SpanBars
|
2
|
+
class SpanBar
|
3
|
+
|
4
|
+
attr_reader :type, :resources, :open, :high, :low, :close, :highval, :lowval
|
5
|
+
|
6
|
+
# Checks if instance has a type and is not :error
|
7
|
+
def valid?
|
8
|
+
not (@type.nil? or @type == :error)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Calculates the path of the instance, i.e. sums up all moves, regardless of up or down
|
12
|
+
def path
|
13
|
+
return @path unless @path.nil?
|
14
|
+
prev = @resources[0][:p]
|
15
|
+
@path = 0
|
16
|
+
1.upto(@resources.size-1) do |i|
|
17
|
+
@path += (@resources[i][:p] - prev).abs
|
18
|
+
prev = @resources[i][:p]
|
19
|
+
end
|
20
|
+
@path
|
21
|
+
end
|
22
|
+
|
23
|
+
# @!visibility private
|
24
|
+
def start; @start ||= @openval[:t]; end
|
25
|
+
# @!visibility private
|
26
|
+
def end; @end ||= @closeval[:t]; end
|
27
|
+
|
28
|
+
# Calculates the momentum, i.e. the speed of move in current instance
|
29
|
+
def momentum
|
30
|
+
@momentum ||= self.path.to_f / @duration
|
31
|
+
end
|
32
|
+
|
33
|
+
# Creates a new instance
|
34
|
+
#
|
35
|
+
# @option b [Array] expects an Array of measures in format [ {t: <timestamp>, p: <value>}, ... ]
|
36
|
+
# @option ticksize [Float] The ticksize of underlying processor (defaults to 1.0)
|
37
|
+
# @option strict [Boolean] Whether this is a strict or a simple SpanBar (defaults to :true)
|
38
|
+
def initialize(b, ticksize = 1.0, strict = true)
|
39
|
+
a = b.dup.flatten.compact
|
40
|
+
return if a.nil? or a.empty?
|
41
|
+
|
42
|
+
# Quick helper to calculate the amount of decimals in the ticksize
|
43
|
+
def decimals(a); num = 0; while (a != a.to_i); num += 1; a *= 10; end; num; end
|
44
|
+
|
45
|
+
@ticksize = ticksize
|
46
|
+
@format = "%1.#{decimals(@ticksize)}f"
|
47
|
+
@strict = strict
|
48
|
+
@openval = a[0]
|
49
|
+
@closeval = a[-1]
|
50
|
+
@highval = a.reverse.max_by{|x| x[:p]}
|
51
|
+
@lowval = a.reverse.min_by{|x| x[:p]}
|
52
|
+
@open = @openval[:p]
|
53
|
+
@high = @highval[:p]
|
54
|
+
@low = @lowval[:p]
|
55
|
+
@close = @closeval[:p]
|
56
|
+
@duration = (@closeval[:t] - @openval[:t]) / 1000
|
57
|
+
@resources = a
|
58
|
+
@path = self.path
|
59
|
+
@momentum = self.momentum.round(8)
|
60
|
+
if @high == @close
|
61
|
+
@type = @low == @open ? :up : :bottom
|
62
|
+
elsif @low == @close
|
63
|
+
@type = @high == @open ? :down : :top
|
64
|
+
else
|
65
|
+
@type = :error
|
66
|
+
end
|
67
|
+
raise "Validation error: Type must be :up or :down for #{self.inspect}" if @strict and not [:up,:down].include?(@type)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Method that splits the @resources Array (containing all measures of the bar) at peak
|
71
|
+
#
|
72
|
+
# @option peak (Symbol) Can be either :high or :low
|
73
|
+
def split_for(peak)
|
74
|
+
tmp0 = []
|
75
|
+
case peak
|
76
|
+
when :high
|
77
|
+
tmp0.prepend(@resources.pop) while @resources.last[:p] < @high
|
78
|
+
when :low
|
79
|
+
tmp0.prepend(@resources.pop) while @resources.last[:p] > @low
|
80
|
+
else
|
81
|
+
raise "Unknown peak #{peak} found in :split_for."
|
82
|
+
end
|
83
|
+
return [ @resources, tmp0 ]
|
84
|
+
end
|
85
|
+
|
86
|
+
# For human output, set output
|
87
|
+
def set_intraday
|
88
|
+
@intraday = true
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns an inspection string
|
92
|
+
def inspect
|
93
|
+
pval = lambda {|val| "#{val[:t]}::#{@format % val[:p]}" }
|
94
|
+
if @strict
|
95
|
+
return "<#SpanBar:0x00#{self.object_id.to_s(16)}, #{@strict ? "strict" : "simple"}, :#{@type
|
96
|
+
},\tpath: #{"%g" % self.path}, momentum: #{"%g" % self.momentum
|
97
|
+
}, open: #{pval.(@openval)}, close: #{pval.(@closeval)}>"
|
98
|
+
else
|
99
|
+
return "<#SpanBar:0x00#{self.object_id.to_s(16)}, #{@strict ? "strict" : "simple"}, :#{@type
|
100
|
+
},\tpath: #{"%g" % self.path}, momentum: #{"%g" % self.momentum
|
101
|
+
}, open: #{pval.(@openval)}, high: #{pval.(@highval)
|
102
|
+
}, low: #{ pval.(@lowval)}, close: #{pval.(@closeval)}>"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Return human readable output of instance
|
107
|
+
def to_human
|
108
|
+
if @intraday
|
109
|
+
time = lambda{|t| now = (t / 1000) % 86400; "#{"%02d" % (now/3600)}:#{"%02d" % ((now%3600)/60)}:#{"%02d" % (now%60)}" }
|
110
|
+
else
|
111
|
+
time = lambda{|t| Time.at(t/1000).strftime("%Y %b %d %H:%M:%S")}
|
112
|
+
end
|
113
|
+
pval = lambda {|v| "[#{time.(v[:t])}, #{@format % v[:p]}]" }
|
114
|
+
if @strict
|
115
|
+
return "STRICT, OPEN: #{pval.(@openval)}, CLOSE: #{pval.(@closeval)
|
116
|
+
}, MOM: #{"%g" % (@momentum / @ticksize) },\tDUR: #{@duration
|
117
|
+
},\tEFF: #{((@close - @open) / @ticksize).to_i}, :#{@type.to_s.upcase}"
|
118
|
+
else
|
119
|
+
return "SIMPLE, OPEN: #{pval.(@openval)
|
120
|
+
}, #{ ([:up, :bottom].include? @type) ? "LOW: #{pval.(@lowval)}" : "HIGH #{pval.(@highval)}"
|
121
|
+
}, CLOSE: #{pval.(@closeval)}, MOM: #{"%g" % (@momentum / @ticksize)
|
122
|
+
},\tDUR: #{@duration},\tEFF: #{((@close - @open) / @ticksize).to_i}, :#{@type.to_s.upcase}"
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns an array containing instance values as needed for CSV output
|
127
|
+
def to_a
|
128
|
+
if @strict
|
129
|
+
return [ "strict",
|
130
|
+
@openval[:t], @openval[ :p].round(8),
|
131
|
+
@closeval[:t], @closeval[:p].round(8),
|
132
|
+
@duration, @path.round(8), @momentum.round(8),
|
133
|
+
((@close - @open) / @ticksize).to_i,
|
134
|
+
@type ]
|
135
|
+
else
|
136
|
+
return [ "simple",
|
137
|
+
@openval[:t], @openval[ :p].round(8),
|
138
|
+
@highval[:t], @highval[ :p].round(8),
|
139
|
+
@lowval[:t], @lowval[ :p].round(8),
|
140
|
+
@closeval[:t], @closeval[:p].round(8),
|
141
|
+
@duration, @path.round(8), @momentum.round(8),
|
142
|
+
((@close - @open) / @ticksize).to_i,
|
143
|
+
@type ]
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'slop'
|
2
|
+
require 'csv'
|
3
|
+
require 'colorize'
|
4
|
+
|
5
|
+
|
6
|
+
# SpanBarHelpers includes some little helpers for convenient usage in SpanBarProcessor
|
7
|
+
module SpanBarHelpers
|
8
|
+
|
9
|
+
# creates a new upfollowing tick that has a minimum higher value than the preceeding one
|
10
|
+
#
|
11
|
+
# @param a [Float]
|
12
|
+
# @param t [Integer]
|
13
|
+
def tickup(a,t=1)
|
14
|
+
{ p: a[:p] + 0.000000001, t: a[:t] + t }
|
15
|
+
end
|
16
|
+
|
17
|
+
# creates a new upfollowing tick that has a minimum lower value than the preceeding one
|
18
|
+
#
|
19
|
+
# @param a [Float]
|
20
|
+
# @param t [Integer]
|
21
|
+
def tickdown(a,t=1)
|
22
|
+
{ p: a[:p] - 0.000000001, t: a[:t] + t }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# The main working class
|
27
|
+
class SpanBarProcessor
|
28
|
+
include SpanBarHelpers
|
29
|
+
|
30
|
+
# Convenient generator for testing purposes
|
31
|
+
#
|
32
|
+
# @!visibility private
|
33
|
+
def self.generate_random
|
34
|
+
p = self.new(5,1)
|
35
|
+
i = 5
|
36
|
+
t = 1
|
37
|
+
s = true
|
38
|
+
while s == true
|
39
|
+
s = p.add(t,i)
|
40
|
+
t += 1 + (Random.rand * 10 ).to_i
|
41
|
+
i += Random.rand > 0.5 ? 1 : -1
|
42
|
+
end
|
43
|
+
s
|
44
|
+
end
|
45
|
+
|
46
|
+
attr_reader :simpleBar, :simpleBars, :spanBars
|
47
|
+
|
48
|
+
# Creates a new instance of SpanBarProcessor
|
49
|
+
#
|
50
|
+
# @param opts [Hash]
|
51
|
+
# @option opts [Integer] :span The span to filter for (defaults to 10)
|
52
|
+
# @option opts [Float] :ticksize The ticksize to apply on timeseries (defaults to 1.0)
|
53
|
+
# @option opts [Boolean] :simple Whether to only create simple bars. (defaults to false)
|
54
|
+
# @option opts [Boolean] :both Whether to output simple AND strict bars. (defaults to false, overrides :simple)
|
55
|
+
|
56
|
+
def initialize(opts = {})
|
57
|
+
@span = opts[:span].nil? ? 10 : opts[:span]
|
58
|
+
raise ArgumentError, "Span must by of type Integer and > 1" unless @span.is_a? Integer and @span > 1
|
59
|
+
@ts = opts[:ticksize].nil? ? 1.0 : opts[:ticksize]
|
60
|
+
raise ArgumentError, "Ticksize must be Numeric, i.e. Integer, Float, ..." unless @ts.is_a? Numeric and @ts > 0
|
61
|
+
@simple = opts[:simple].nil? ? false : opts[:simple]
|
62
|
+
if opts[:both] == true
|
63
|
+
@simple = false
|
64
|
+
@both = true
|
65
|
+
else
|
66
|
+
@both = false
|
67
|
+
end
|
68
|
+
@limit = @ts * @span
|
69
|
+
@simpleMax, @simpleMin = 0, Float::INFINITY
|
70
|
+
@simpleBar = []
|
71
|
+
@simpleBars = []
|
72
|
+
@spanBars = []
|
73
|
+
@ticks = []
|
74
|
+
end
|
75
|
+
|
76
|
+
# Sends a new items of the timeseries
|
77
|
+
#
|
78
|
+
# @option t [Integer] The timestamp (preferrably in JS format, i.e. Milliseconds since 1970-01-01)
|
79
|
+
# @option p [Float] The value
|
80
|
+
def add(t, p)
|
81
|
+
raise ArgumentError, "SpanBar#add requires either an Integer (Timestamp) or a Time object as first argument" unless [Integer, Time].include?(t.class)
|
82
|
+
raise ArgumentError, "SpanBar#add requires either a Numeric or NilClass as second argument" unless p.is_a? Numeric or p.nil?
|
83
|
+
return nil if p.nil?
|
84
|
+
tick = {t: (t.class == Integer ? t : t.to_i), p: p.to_f}
|
85
|
+
@simpleBar << tick
|
86
|
+
@simpleMax = [tick[:p],@simpleMax].max
|
87
|
+
@simpleMin = [tick[:p],@simpleMin].min
|
88
|
+
if @simpleMax - @simpleMin > @limit
|
89
|
+
simple = SpanBar.new(@simpleBar, @ts, false)
|
90
|
+
unless @simple
|
91
|
+
result = self.create_strict_from(simple)
|
92
|
+
end
|
93
|
+
@simpleBars << simple
|
94
|
+
@simpleMax, @simpleMin = 0, Float::INFINITY
|
95
|
+
@simpleBar = []
|
96
|
+
if @simple
|
97
|
+
return [ simple ] # we need an Array from caller
|
98
|
+
else
|
99
|
+
begin
|
100
|
+
result << simple if @both and simple
|
101
|
+
rescue
|
102
|
+
return [ simple ]
|
103
|
+
end
|
104
|
+
return result
|
105
|
+
end
|
106
|
+
end
|
107
|
+
return false
|
108
|
+
end
|
109
|
+
|
110
|
+
# Private method to further process simple bars to strict bars
|
111
|
+
#
|
112
|
+
# @option simple [SpanBar]
|
113
|
+
def create_strict_from(simple)
|
114
|
+
elem0 = @currentBar
|
115
|
+
elem1 = simple
|
116
|
+
|
117
|
+
res = [ ]
|
118
|
+
if elem0.nil? # means this is the very first chunk working on
|
119
|
+
case elem1.type
|
120
|
+
when :bottom
|
121
|
+
tmp0, tmp1 = elem1.split_for :low
|
122
|
+
@currentBar = SpanBar.new([tmp0.last, tmp1], @ts)
|
123
|
+
when :top
|
124
|
+
tmp0, tmp1 = elem1.split_for :high
|
125
|
+
@currentBar = SpanBar.new([tmp0.last, tmp1], @ts)
|
126
|
+
when *[:up,:down]
|
127
|
+
@currentBar = elem1
|
128
|
+
else
|
129
|
+
raise "Invalid type for initial simple SpanBar #{elem0}"
|
130
|
+
end
|
131
|
+
else # otherwise there is already a preceding element
|
132
|
+
case elem0.type
|
133
|
+
when :up
|
134
|
+
case elem1.type
|
135
|
+
when *[:bottom, :up]
|
136
|
+
if elem0.close - elem1.low > @limit
|
137
|
+
res << elem0
|
138
|
+
tmp0, tmp1 = elem1.split_for :low
|
139
|
+
res << SpanBar.new([ tickup(elem0.resources.last), tmp0 ], @ts)
|
140
|
+
@currentBar = SpanBar.new([ tickup(tmp0.last),tmp1], @ts)
|
141
|
+
elsif elem0.close - elem1.low <= @limit and elem0.close <= elem1.close
|
142
|
+
@currentBar = SpanBar.new([ elem0.resources, elem1.resources], @ts)
|
143
|
+
else
|
144
|
+
# silently dropping unneeded fragment
|
145
|
+
end
|
146
|
+
when *[:top, :down]
|
147
|
+
if elem1.high >= elem0.close
|
148
|
+
tmp0, tmp1 = elem1.split_for :high
|
149
|
+
res << SpanBar.new([ elem0.resources, tmp0 ], @ts)
|
150
|
+
@currentBar = SpanBar.new([tickdown(tmp0.last),tmp1], @ts)
|
151
|
+
else
|
152
|
+
res << elem0
|
153
|
+
@currentBar = SpanBar.new([ tickup(elem0.resources.last), elem1.resources], @ts)
|
154
|
+
end
|
155
|
+
else
|
156
|
+
raise "Unknown type for secondary simple SpanBar #{elem1}"
|
157
|
+
end
|
158
|
+
when :down
|
159
|
+
case elem1.type
|
160
|
+
when *[:top, :down]
|
161
|
+
if elem1.high - elem0.close > @limit # only for percentage !?: or elem1.low <= elem0.low
|
162
|
+
res << elem0
|
163
|
+
tmp0, tmp1 = elem1.split_for :high
|
164
|
+
res << SpanBar.new([ tickup(elem0.resources.last), tmp0 ], @ts)
|
165
|
+
@currentBar = SpanBar.new([tickdown(tmp0.last),tmp1], @ts)
|
166
|
+
elsif elem1.high - elem0.close <= @limit and elem0.close >= elem1.close
|
167
|
+
@currentBar = SpanBar.new([elem0.resources, elem1.resources], @ts)
|
168
|
+
else
|
169
|
+
# silently dropping unneeded fragment
|
170
|
+
end
|
171
|
+
when *[:bottom, :up]
|
172
|
+
if elem1.low <= elem0.close
|
173
|
+
tmp0, tmp1 = elem1.split_for :low
|
174
|
+
res << SpanBar.new([ elem0.resources, tmp0 ], @ts)
|
175
|
+
@currentBar = SpanBar.new([tickup(tmp0.last),tmp1], @ts)
|
176
|
+
else
|
177
|
+
res << elem0
|
178
|
+
@currentBar = SpanBar.new([ tickup(elem0.resources.last), elem1.resources], @ts)
|
179
|
+
end
|
180
|
+
else
|
181
|
+
raise "Unknown or invalid type for secondary simple SpanBar #{elem1}"
|
182
|
+
end
|
183
|
+
else
|
184
|
+
raise "Unknown or invalid type for primary simple SpanBar #{elem0}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
res.each {|x| @spanBars << x }
|
189
|
+
return res.empty? ? false : res
|
190
|
+
end
|
191
|
+
|
192
|
+
#def set_intraday
|
193
|
+
# @spanBars.each{|bar| bar.set_intraday}
|
194
|
+
#end
|
195
|
+
|
196
|
+
end
|
metadata
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: spanbars
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2beta
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Benjamin L. Tischendorf
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-04-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: slop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.6'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '4.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: csv
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: colorize
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.8'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.8'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.6'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.6'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: cucumber
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.1'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yard
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.9'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.9'
|
97
|
+
description: 'Tiny tool to process input CSV data as timeseries to span bars '
|
98
|
+
email: donkeybridge@jtown.eu
|
99
|
+
executables:
|
100
|
+
- spanbars
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- README.md
|
105
|
+
- bin/spanbars
|
106
|
+
- features/01_spanbarprocessor_initialization.feature
|
107
|
+
- features/02_spanbarprocessor_add.feature
|
108
|
+
- features/03_spanbar_initialization.feature
|
109
|
+
- features/04_spanbars_commandline.feature
|
110
|
+
- features/step_definitions/01_spanbar_processor_initialization_steps.rb
|
111
|
+
- features/step_definitions/02_spanbarprocessor_add_steps.rb
|
112
|
+
- features/step_definitions/03_spanbar_initialization_steps.rb
|
113
|
+
- features/step_definitions/04_spanbars_commandline_steps.rb
|
114
|
+
- features/support/env.rb
|
115
|
+
- features/support/ref1.csv
|
116
|
+
- features/support/ref1_out_0.25_25.csv
|
117
|
+
- features/support/ref2.csv
|
118
|
+
- features/support/ref2_out_1_25.csv
|
119
|
+
- features/support/ref3.csv
|
120
|
+
- features/support/ref3_out_0.0000005_10.csv
|
121
|
+
- lib/spanbar.rb
|
122
|
+
- lib/spanbarprocessor.rb
|
123
|
+
homepage: https://github.com/donkeybridge/spanbars
|
124
|
+
licenses:
|
125
|
+
- BSD-4-Clause
|
126
|
+
metadata: {}
|
127
|
+
post_install_message:
|
128
|
+
rdoc_options: []
|
129
|
+
require_paths:
|
130
|
+
- lib
|
131
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
132
|
+
requirements:
|
133
|
+
- - "~>"
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '2.0'
|
136
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">"
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: 1.3.1
|
141
|
+
requirements: []
|
142
|
+
rubyforge_project:
|
143
|
+
rubygems_version: 2.7.8
|
144
|
+
signing_key:
|
145
|
+
specification_version: 4
|
146
|
+
summary: Tiny tool to process input CSV data as timeseries to span bars
|
147
|
+
test_files:
|
148
|
+
- features/01_spanbarprocessor_initialization.feature
|
149
|
+
- features/support/ref3.csv
|
150
|
+
- features/support/ref3_out_0.0000005_10.csv
|
151
|
+
- features/support/ref1.csv
|
152
|
+
- features/support/ref2_out_1_25.csv
|
153
|
+
- features/support/env.rb
|
154
|
+
- features/support/ref2.csv
|
155
|
+
- features/support/ref1_out_0.25_25.csv
|
156
|
+
- features/02_spanbarprocessor_add.feature
|
157
|
+
- features/04_spanbars_commandline.feature
|
158
|
+
- features/step_definitions/01_spanbar_processor_initialization_steps.rb
|
159
|
+
- features/step_definitions/02_spanbarprocessor_add_steps.rb
|
160
|
+
- features/step_definitions/04_spanbars_commandline_steps.rb
|
161
|
+
- features/step_definitions/03_spanbar_initialization_steps.rb
|
162
|
+
- features/03_spanbar_initialization.feature
|