tickseries 0.1.1alpha
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/.gitignore +50 -0
- data/LICENSE +29 -0
- data/README.md +19 -0
- data/features/01-ticks-init.feature +13 -0
- data/features/02-tickseries-init.feature +0 -0
- data/features/step_definitions/01-ticks-init_steps.rb +12 -0
- data/features/support/env.rb +6 -0
- data/lib/tickseries.rb +212 -0
- metadata +111 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d71caec6e9a6de66e0d18b58a6dba5ef5d021d6ebf2c6b6b71fad151344676f3
|
4
|
+
data.tar.gz: ad25827c08d77046112df71758f920635d0ecb572ab8f8ca1e88eb3167257b14
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 175441d690488c3e66bf3682a03220bada56eed28fe3319450be662129aae245054fd85a6246a35ef871bd29de566de2c0d6a8b678c3cb4a9e10cb9386a5658d
|
7
|
+
data.tar.gz: bede548c0567dc07643538e3a905bd36e144854c82b3b3d56c99ff88d3123dc5a60e0bbe7c63db62c020acd74b9d6f9b94082f89f8fe29639167076006d839b8
|
data/.gitignore
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
|
13
|
+
# Used by dotenv library to load environment variables.
|
14
|
+
# .env
|
15
|
+
|
16
|
+
## Specific to RubyMotion:
|
17
|
+
.dat*
|
18
|
+
.repl_history
|
19
|
+
build/
|
20
|
+
*.bridgesupport
|
21
|
+
build-iPhoneOS/
|
22
|
+
build-iPhoneSimulator/
|
23
|
+
|
24
|
+
## Specific to RubyMotion (use of CocoaPods):
|
25
|
+
#
|
26
|
+
# We recommend against adding the Pods directory to your .gitignore. However
|
27
|
+
# you should judge for yourself, the pros and cons are mentioned at:
|
28
|
+
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
29
|
+
#
|
30
|
+
# vendor/Pods/
|
31
|
+
|
32
|
+
## Documentation cache and generated files:
|
33
|
+
/.yardoc/
|
34
|
+
/_yardoc/
|
35
|
+
/doc/
|
36
|
+
/rdoc/
|
37
|
+
|
38
|
+
## Environment normalization:
|
39
|
+
/.bundle/
|
40
|
+
/vendor/bundle
|
41
|
+
/lib/bundler/man/
|
42
|
+
|
43
|
+
# for a library or gem, you might want to ignore these files since the code is
|
44
|
+
# intended to run in multiple environments; otherwise, check them in:
|
45
|
+
# Gemfile.lock
|
46
|
+
# .ruby-version
|
47
|
+
# .ruby-gemset
|
48
|
+
|
49
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
50
|
+
.rvmrc
|
data/LICENSE
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2019, Donkeybridge
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
8
|
+
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
10
|
+
list of conditions and the following disclaimer.
|
11
|
+
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
14
|
+
and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
17
|
+
contributors may be used to endorse or promote products derived from
|
18
|
+
this software without specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# TickSeries
|
2
|
+
|
3
|
+
TickSeries is a Ruby module including the classes
|
4
|
+
* Tick
|
5
|
+
* Series
|
6
|
+
|
7
|
+
It's purpose is to build a robust layer to working with single-valued timeseries.
|
8
|
+
|
9
|
+
## Description
|
10
|
+
|
11
|
+
Description pending (as are tests).
|
12
|
+
|
13
|
+
## Basic usage
|
14
|
+
|
15
|
+
> series = Series.load(file: "ticks-2019-04-01", symbol: "Voltage")
|
16
|
+
> series.select {|x| x.p > 5.1 }.each {|x| p x}
|
17
|
+
|
18
|
+
|
19
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Initialization of Tick
|
2
|
+
Scenario: Initialization of Tick
|
3
|
+
When creating a tick without parameters it should raise ArgumentError
|
4
|
+
|
5
|
+
Scenario Outline: Initialization of Tick with different valid parameter types
|
6
|
+
When creating a tick with '<params>' it should result in <timestamp> and <price>
|
7
|
+
Examples:
|
8
|
+
| params | timestamp | price |
|
9
|
+
| {s: :foo, t: 1555767235, p: 123 } | 1555767235000 | 123.0 |
|
10
|
+
| {s: "foo", t: 1555767235123, p: 1.21 } | 1555767235123 | 1.21 |
|
11
|
+
| ["foo", "1555767235", "225" ] | 1555767235000 | 225.0 |
|
12
|
+
| :foo, 1555767235, 225 | 1555767235000 | 225.0 |
|
13
|
+
| 1555767235, 225 | 1555767235000 | 225.0 |
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require './lib/tickseries.rb'
|
2
|
+
include TickSeries
|
3
|
+
|
4
|
+
When "creating a tick without parameters it should raise ArgumentError" do
|
5
|
+
expect { Tick.new }.to raise_error(ArgumentError)
|
6
|
+
end
|
7
|
+
|
8
|
+
When /^creating a tick with '([^']*)' it should result in (\S*) and (\S*)$/ do |params, timestamp, price|
|
9
|
+
eval "@tick = Tick.new(#{params})"
|
10
|
+
expect(@tick.t).to eq(Integer(timestamp))
|
11
|
+
expect(@tick.p).to eq(BigDecimal(price,8))
|
12
|
+
end
|
data/lib/tickseries.rb
ADDED
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'date'
|
3
|
+
require 'csv'
|
4
|
+
require 'bigdecimal'
|
5
|
+
|
6
|
+
# The module proveds TickSeries::Tick and TickSeries::Series
|
7
|
+
module TickSeries
|
8
|
+
|
9
|
+
# TickSeries::Series provides a TimeSeries (aka TickSeries) based on single Ticks (aka Measurements)
|
10
|
+
#
|
11
|
+
class Series
|
12
|
+
|
13
|
+
attr_reader :date, :ticks
|
14
|
+
|
15
|
+
# TickSeries::CONFIGFILEPATH
|
16
|
+
CONFIGFILEPATH = "~/.config/ez"
|
17
|
+
# TickSeries::CONFIGFILE basically contains the location of tickfiles as well as the location of symbol / contract information
|
18
|
+
#
|
19
|
+
CONFIGFILE = "#{CONFIGFILEPATH}/tickseries.conf"
|
20
|
+
|
21
|
+
# Helper method the read the config file
|
22
|
+
def self.get_config
|
23
|
+
begin
|
24
|
+
return YAML.load(File.read("#{`echo $HOME`.chomp}/.config/ez/tickseries.yml"))
|
25
|
+
rescue Errno::ENOENT
|
26
|
+
return {}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Helper method the read the symbol config
|
31
|
+
def get_symbol_config
|
32
|
+
begin
|
33
|
+
return YAML.load(File.read("#{@symbolspath}/#{@symbol}.yml"))
|
34
|
+
#rescue Errno::ENOENT
|
35
|
+
# return {}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Creates a new instance of TickSeries::Series. Accepts optionshash.
|
40
|
+
#
|
41
|
+
# @param opts [Hash]
|
42
|
+
def initialize(opts = {})
|
43
|
+
|
44
|
+
# Reading configfile and setting provided instance variables
|
45
|
+
`mkdir -p #{CONFIGFILEPATH} > /dev/null`
|
46
|
+
@config = Series.get_config
|
47
|
+
[:tickfilepath, :symbolspath].each do |param|
|
48
|
+
from_conf = @config[param.to_s] || @config[param]
|
49
|
+
from_opts = opts[param]
|
50
|
+
instance_variable_set("@#{param.to_s}", from_opts || from_conf)
|
51
|
+
end
|
52
|
+
p self.instance_variables
|
53
|
+
|
54
|
+
# Reading symbolconfig and providing instance variables
|
55
|
+
@symbol = opts[:symbol]
|
56
|
+
unless @symbol.nil?
|
57
|
+
@symbol = @symbol.upcase
|
58
|
+
@symbolconfig = self.get_symbol_config
|
59
|
+
p @symbolconfig
|
60
|
+
[:symbol, :ticksize].each do |param|
|
61
|
+
from_conf = @config[param.to_s] || @config[param]
|
62
|
+
from_opts = opts[param]
|
63
|
+
instance_variable_set("@#{param.to_s}", from_opts || from_conf)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
@date ||= Date.today
|
67
|
+
@ticks = []
|
68
|
+
end
|
69
|
+
|
70
|
+
# Receptor from Enumerable#to_series
|
71
|
+
def self.from_enumerable(arr)
|
72
|
+
t = Series.new
|
73
|
+
arr.each{|x| t.add(x)}
|
74
|
+
t
|
75
|
+
end
|
76
|
+
|
77
|
+
# TickSeries::Series.load opens a 'tickfile' containing data saved as CSV.
|
78
|
+
def self.load(opts = {})
|
79
|
+
begin
|
80
|
+
config = Series.get_config
|
81
|
+
rescue Errno::ENOENT
|
82
|
+
config = {}
|
83
|
+
end
|
84
|
+
symbol = opts[:symbol]
|
85
|
+
file = opts[:file]
|
86
|
+
unless file.nil?
|
87
|
+
*path, filename = file.split('/')
|
88
|
+
if path.empty?
|
89
|
+
path = config[:tickfilepath] || config["tickfilepath"]
|
90
|
+
else
|
91
|
+
path = File.absolute_path(path.join('/'))
|
92
|
+
end
|
93
|
+
raise "Cannot guess tickfilepath from #{file}, please provide in #{CONFIGFILE}" if path.nil?
|
94
|
+
|
95
|
+
filetype = opts[:filetype] || filename.split('.').last
|
96
|
+
end
|
97
|
+
raise ArgumentError, "Cannot guess filetype for loading Timeseries from file #{path}/#{filename}" if filetype.nil?
|
98
|
+
raise ArgumentError, "Seems provided file for loading timeseries does not exist #{path}/#{filename}" unless File.file?("#{path}/#{filename}")
|
99
|
+
|
100
|
+
series = Series.new( symbol: opts[:symbol])
|
101
|
+
|
102
|
+
case filetype.downcase
|
103
|
+
when 'csv'
|
104
|
+
CSV.parse(`cat #{path}/#{filename} #{symbol.nil? ? "" : "| grep -i #{symbol}"}`).sort_by{|x| x[1] }.each{|x| series.add x}
|
105
|
+
else
|
106
|
+
raise(ArgumentError, "Unsupported filetype '.#{filetype}'")
|
107
|
+
end
|
108
|
+
series
|
109
|
+
end
|
110
|
+
|
111
|
+
# TickSeries::Series#add adds an element to series.
|
112
|
+
#
|
113
|
+
# element can be provided as TimeSeries::Tick, or as Hash or Array, that sufficises format requirements.
|
114
|
+
def add(element)
|
115
|
+
@ticks << ((element.is_a? Tick) ? element : Tick.new(element))
|
116
|
+
end
|
117
|
+
|
118
|
+
# @!visibility private
|
119
|
+
def map(&block); @ticks.map {|x| block.call(x)} ;end
|
120
|
+
# @!visibility private
|
121
|
+
def each(&block); @ticks.each {|x| block.call(x)} ;end
|
122
|
+
# @!visibility private
|
123
|
+
def each_with_index(&block); @ticks.each_with_index {|x,i| block.call(x,i)} ;end
|
124
|
+
# @!visibility private
|
125
|
+
def select(&block); @ticks.select {|x| block.call(x)} ;end
|
126
|
+
# @!visibility private
|
127
|
+
def reduce(c = 0, &block); @ticks.reduce(c) {|x,i| block.call(x,i)} ;end
|
128
|
+
|
129
|
+
# @!visibility private
|
130
|
+
def inspect
|
131
|
+
"<#TimeSeries::Series:0x#{self.object_id.to_s(16)} ticks: #{@ticks.size}, #{"symbol: #{@symbol}, " if @symbol}ticksize: #{@ticksize}, date: #{@date}>"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
# TimeSeries::Series is the second part of the module. It contains a single measurement ("Messpunkt") of the series.
|
136
|
+
class Tick
|
137
|
+
attr_reader :t, :p, :v, :k
|
138
|
+
|
139
|
+
# The constructor is build as flexible as I was able to. It accepts
|
140
|
+
# * a Hash containing < :t | :time | :timestamp > with an integer or string value required in seconds or milliseconds
|
141
|
+
# containing < :m | :measurement | :price > with a Numeric value (can also be given as string)
|
142
|
+
# arbitrary information like or symbol, volume or peak information.
|
143
|
+
# * an Array that sufficises the expected order: < [ symbol,] timestamp, measure, frequency / volume, peak information >
|
144
|
+
def initialize(*args, &block)
|
145
|
+
raise ArgumentError, "Creating ticks without arguments is not supported" if args.empty?
|
146
|
+
opts = args[0] if args[0].is_a? Hash
|
147
|
+
args = args[0] if args[0].is_a? Array
|
148
|
+
if opts.nil?
|
149
|
+
prefix = 0
|
150
|
+
begin # if symbol is given on args[0], the Integer() will raise
|
151
|
+
timestamp = Integer(args[0])
|
152
|
+
rescue
|
153
|
+
prefix = 1
|
154
|
+
timestamp = Integer(args[1])
|
155
|
+
end
|
156
|
+
opts = {t: timestamp,
|
157
|
+
m: args[prefix + 1],
|
158
|
+
v: args[prefix + 2],
|
159
|
+
p: args[prefix + 3]}
|
160
|
+
end
|
161
|
+
@t = opts[:t] || opts[:time] || opts[:timestamp]
|
162
|
+
case @t
|
163
|
+
when *[Date, DateTime, Time]
|
164
|
+
@t = @t.to_time.to_i
|
165
|
+
when *[Integer, Float, BigDecimal]
|
166
|
+
@t = Integer(@t)
|
167
|
+
when String
|
168
|
+
failed = false
|
169
|
+
begin; @t = DateTime.parse(@t).to_time.to_i * 1000; rescue; failed = true; end
|
170
|
+
if failed; begin; @t = Integer(@t); failed = false; rescue; failed = true; end; end
|
171
|
+
raise ArgumentError, "Could not get Timestamp from given String #{@t}" if failed
|
172
|
+
else
|
173
|
+
raise ArgumentError, "Tick.new cannot continue without timestamp given as t:, time: timestamp: or within array."
|
174
|
+
end
|
175
|
+
if @t < 500000000000 # Tue, 05 Nov 1985 00:53:20 GMT in ms
|
176
|
+
# assume it was provided as second_based timestamp
|
177
|
+
@t *= 1000
|
178
|
+
end
|
179
|
+
raise ArgumentError, "Invalid timestamp, too small: #{@t} < 500000000000" if @t < 500000000000
|
180
|
+
@m = opts[:m] || opts[:measurement]
|
181
|
+
@m = BigDecimal(@m,8) unless @m.nil?
|
182
|
+
@v = opts[:v] || opts[:vol]
|
183
|
+
@v = @v.to_i unless @v.nil?
|
184
|
+
# :peak should only be set for peaks pointing out a deviation > 5 * @ticksize
|
185
|
+
@p = opts[:p] || opts[:peak]
|
186
|
+
@p = @p.to_i unless @p.nil?
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
# Convenient way to create a string representation of tick.
|
191
|
+
def to_s
|
192
|
+
"#{@t},#{@m.to_f},#{@v},#{@p}"
|
193
|
+
end
|
194
|
+
|
195
|
+
# TickSeries::Tick#human_time returns the time converted to a human readable format
|
196
|
+
#
|
197
|
+
# @param with_date [Boolean] whether or not to include Date information (default: false)
|
198
|
+
def human_time(with_date = false)
|
199
|
+
t = Time.at(@t / 1000)
|
200
|
+
t.strftime("#{ "%Y-%m-%d " if with_date }%H:%M:%S")
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# Reopens enumerable to allow retransport into Series
|
206
|
+
# @!visibility private
|
207
|
+
module Enumerable
|
208
|
+
# @!visibility private
|
209
|
+
def to_series
|
210
|
+
TickSeries::Series.from_enumerable(self)
|
211
|
+
end
|
212
|
+
end
|
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tickseries
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1alpha
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Benjamin L. Tischendorf
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-04-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: csv
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: cucumber
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.9'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.9'
|
69
|
+
description: 'Ruby Module providing TickSeries::Tick and TickSeries::Series '
|
70
|
+
email: donkeybridge@jtown.eu
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- ".gitignore"
|
76
|
+
- LICENSE
|
77
|
+
- README.md
|
78
|
+
- features/01-ticks-init.feature
|
79
|
+
- features/02-tickseries-init.feature
|
80
|
+
- features/step_definitions/01-ticks-init_steps.rb
|
81
|
+
- features/support/env.rb
|
82
|
+
- lib/tickseries.rb
|
83
|
+
homepage: https://github.com/donkeybridge/tickseries
|
84
|
+
licenses:
|
85
|
+
- BSD-4-Clause
|
86
|
+
metadata: {}
|
87
|
+
post_install_message:
|
88
|
+
rdoc_options: []
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '2.0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: 1.3.1
|
101
|
+
requirements: []
|
102
|
+
rubyforge_project:
|
103
|
+
rubygems_version: 2.7.8
|
104
|
+
signing_key:
|
105
|
+
specification_version: 4
|
106
|
+
summary: Ruby Module providing TickSeries::Tick and TickSeries::Series
|
107
|
+
test_files:
|
108
|
+
- features/01-ticks-init.feature
|
109
|
+
- features/support/env.rb
|
110
|
+
- features/02-tickseries-init.feature
|
111
|
+
- features/step_definitions/01-ticks-init_steps.rb
|