spanbars 0.1.2beta
Sign up to get free protection for your applications and to get access to all the features.
- 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
|