stockcruncher 1.1.1 → 1.2.0
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 +11 -0
- data/lib/stockcruncher/cli.rb +1 -1
- data/lib/stockcruncher/influxdb.rb +54 -2
- data/lib/stockcruncher/version.rb +1 -1
- data/spec/stockcruncher/cli_spec.rb +12 -1
- data/spec/stockcruncher/stubs/servers_stubs.rb +13 -2
- 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: 7bd12e5a6e5db6f83f239c1b6da9aca85931048dd427778ffb96f043e7334596
|
4
|
+
data.tar.gz: 48fe8efa593f30fe39c294725d7090c89a4a14413eaa59a1d6741c817fc02d64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad4ed352a8ed30d41edbe9c4bac03ba721c9af42837f9e94f9c14df2175013d4ae7a09e29c7076e034cf375abaf222ce04c251a4b8fde31ce10ae29936c18894
|
7
|
+
data.tar.gz: 06206e1a91e23706c6a83c02357b31064124a21e522f3144d4ec93d4d4e7863e82e38cf4b561eedb662e59ea801120ee05f8cd3fff1b414da5ea5a069dd337ff
|
data/CHANGELOG
CHANGED
@@ -11,3 +11,14 @@ Changelog
|
|
11
11
|
|
12
12
|
- Add InfluxDB as database.
|
13
13
|
- WIP for daily time serie.
|
14
|
+
|
15
|
+
1.1.1
|
16
|
+
-----
|
17
|
+
|
18
|
+
- Rescue error on no data
|
19
|
+
|
20
|
+
1.2.0
|
21
|
+
-----
|
22
|
+
|
23
|
+
- daily subcommand now recalculates missing data
|
24
|
+
- daily subcommand also writes data to database
|
data/lib/stockcruncher/cli.rb
CHANGED
@@ -49,7 +49,7 @@ module StockCruncher
|
|
49
49
|
config = YAML.load_file(opts['config'])
|
50
50
|
cruncher = StockCruncher::AlphaVantage.new(config, opts['insecure'])
|
51
51
|
raw_data = cruncher.crunch_daily(symbol, opts['full'])
|
52
|
-
|
52
|
+
StockCruncher::InfluxDB.new(config).export_history(symbol, raw_data)
|
53
53
|
puts raw_data unless opts['quiet']
|
54
54
|
end
|
55
55
|
|
@@ -13,6 +13,38 @@ module StockCruncher
|
|
13
13
|
@insecure = insecure
|
14
14
|
end
|
15
15
|
|
16
|
+
# Method to calculate missing data (previousClose, change, changePercent)
|
17
|
+
def calculate_missing_data(hash)
|
18
|
+
keys = hash.keys
|
19
|
+
hash.each_with_index do |(date, v), index|
|
20
|
+
prevday = keys[index + 1]
|
21
|
+
next if prevday.nil?
|
22
|
+
|
23
|
+
prevclose = hash[prevday]['close']
|
24
|
+
hash[date] = v.merge(generate_missing_data(v['close'], prevclose))
|
25
|
+
end
|
26
|
+
hash
|
27
|
+
end
|
28
|
+
|
29
|
+
# Method to generate missing data
|
30
|
+
def generate_missing_data(current, previous)
|
31
|
+
{
|
32
|
+
'previousClose' => previous,
|
33
|
+
'change' => change(current.to_f, previous.to_f),
|
34
|
+
'changePercent' => change_percent(current.to_f, previous.to_f)
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
# Method to calculate change difference
|
39
|
+
def change(value, base)
|
40
|
+
(value - base).round(4).to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
# Method to calculate percentage of change
|
44
|
+
def change_percent(value, base)
|
45
|
+
((value / base - 1) * 100).round(4).to_s
|
46
|
+
end
|
47
|
+
|
16
48
|
# Method to create a new hash from two arrays of keys and values
|
17
49
|
def create_hash(descriptions, values)
|
18
50
|
descriptions.split(',').zip(values.split(',')).to_h
|
@@ -31,8 +63,15 @@ module StockCruncher
|
|
31
63
|
end
|
32
64
|
|
33
65
|
# Method to export historical data to database
|
34
|
-
def export_history(raw)
|
35
|
-
|
66
|
+
def export_history(symbol, raw)
|
67
|
+
raise StandardError, 'No data to export' if raw.match?(/Error Message/)
|
68
|
+
|
69
|
+
tags = { 'symbol' => symbol }
|
70
|
+
timeseries = prepare_daily_timeserie(raw)
|
71
|
+
timeseries = calculate_missing_data(timeseries)
|
72
|
+
timeseries.each_pair do |date, values|
|
73
|
+
write('daily', tags, values, date)
|
74
|
+
end
|
36
75
|
end
|
37
76
|
|
38
77
|
# Method to format and array of values into comma separated string
|
@@ -45,6 +84,19 @@ module StockCruncher
|
|
45
84
|
string
|
46
85
|
end
|
47
86
|
|
87
|
+
# Method to transform raw data to constructed hash
|
88
|
+
def prepare_daily_timeserie(data)
|
89
|
+
lines = data.split("\r\n")
|
90
|
+
desc = lines.shift.split(',').drop(1)
|
91
|
+
hash = {}
|
92
|
+
lines.each do |line|
|
93
|
+
values = line.split(',')
|
94
|
+
date = values.shift
|
95
|
+
hash[date] = desc.zip(values).to_h
|
96
|
+
end
|
97
|
+
hash
|
98
|
+
end
|
99
|
+
|
48
100
|
# Method to send http post request
|
49
101
|
def request(url, body)
|
50
102
|
uri = URI.parse(url)
|
@@ -5,6 +5,11 @@ require 'spec_helper'
|
|
5
5
|
quote = 'symbol,open,high,low,price,volume,latestDay,previousClose,change,ch' \
|
6
6
|
"angePercent\r\nSYM,100.0000,100.1000,99.9000,100.0000,4,2020-07-30," \
|
7
7
|
"100.0000,0.0000,0.0000%\r\n"
|
8
|
+
daily = "timestamp,open,high,low,close,volume\r\n2020-08-03,23.8500,24.6500," \
|
9
|
+
"23.7400,24.5500,3112972\r\n2020-07-31,24.0100,24.5100,23.5900,23.81" \
|
10
|
+
"00,5482485\r\n2020-07-30,24.4700,24.6600,23.5200,23.6600,6466738\r" \
|
11
|
+
"\n2020-07-29,24.7500,25.0300,24.0400,24.5600,4605804\r\n2020-07-28," \
|
12
|
+
"25.9900,26.0700,24.5100,24.7500,6904261\r\n"
|
8
13
|
|
9
14
|
describe StockCruncher::CLI do # rubocop:disable Metrics/BlockLength
|
10
15
|
context 'version' do
|
@@ -14,9 +19,15 @@ describe StockCruncher::CLI do # rubocop:disable Metrics/BlockLength
|
|
14
19
|
end
|
15
20
|
end
|
16
21
|
|
22
|
+
context 'daily NODATA -c spec/files/stockcruncher.yml' do
|
23
|
+
it 'Should not get any data and should fail.' do
|
24
|
+
expect { start(self) }.to raise_error(SystemExit)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
17
28
|
context 'daily SYM -c spec/files/stockcruncher.yml' do
|
18
29
|
it 'Get the daily time serie for SYM.' do
|
19
|
-
expect { start(self) }.to output(
|
30
|
+
expect { start(self) }.to output(daily).to_stdout
|
20
31
|
end
|
21
32
|
end
|
22
33
|
|
@@ -5,20 +5,31 @@ require 'spec_helper'
|
|
5
5
|
quote = 'symbol,open,high,low,price,volume,latestDay,previousClose,change,ch' \
|
6
6
|
"angePercent\r\nSYM,100.0000,100.1000,99.9000,100.0000,4,2020-07-30," \
|
7
7
|
"100.0000,0.0000,0.0000%\r\n"
|
8
|
+
q_err = '{}'
|
9
|
+
daily = "timestamp,open,high,low,close,volume\r\n2020-08-03,23.8500,24.6500," \
|
10
|
+
"23.7400,24.5500,3112972\r\n2020-07-31,24.0100,24.5100,23.5900,23.81" \
|
11
|
+
"00,5482485\r\n2020-07-30,24.4700,24.6600,23.5200,23.6600,6466738\r" \
|
12
|
+
"\n2020-07-29,24.7500,25.0300,24.0400,24.5600,4605804\r\n2020-07-28," \
|
13
|
+
"25.9900,26.0700,24.5100,24.7500,6904261\r\n"
|
14
|
+
d_err = "{\n \"Error Message\": \"Invalid API call.\"\n}"
|
8
15
|
|
9
16
|
RSpec.configure do |config|
|
10
17
|
config.before(:each) do
|
11
18
|
# requests an API without extra arguments
|
12
19
|
stub_request(:get, 'https://www.alphavantage.co/query?' \
|
13
20
|
'function=GLOBAL_QUOTE&symbol=NODATA&apikey=demo&datatype=csv')
|
14
|
-
.to_return('status' => 200, 'body' =>
|
21
|
+
.to_return('status' => 200, 'body' => q_err, 'headers' => {})
|
15
22
|
stub_request(:get, 'https://www.alphavantage.co/query?' \
|
16
23
|
'function=GLOBAL_QUOTE&symbol=SYM&apikey=demo&datatype=csv')
|
17
24
|
.to_return('status' => 200, 'body' => quote, 'headers' => {})
|
25
|
+
stub_request(:get, 'https://www.alphavantage.co/query?' \
|
26
|
+
'function=TIME_SERIES_DAILY&symbol=NODATA&apikey=demo' \
|
27
|
+
'&datatype=csv&outputsize=compact')
|
28
|
+
.to_return('status' => 200, 'body' => d_err, 'headers' => {})
|
18
29
|
stub_request(:get, 'https://www.alphavantage.co/query?' \
|
19
30
|
'function=TIME_SERIES_DAILY&symbol=SYM&apikey=demo' \
|
20
31
|
'&datatype=csv&outputsize=compact')
|
21
|
-
.to_return('status' => 200, 'body' =>
|
32
|
+
.to_return('status' => 200, 'body' => daily, 'headers' => {})
|
22
33
|
stub_request(:post, 'http://localhost:8086/write?db=test')
|
23
34
|
.to_return('status' => 204, 'body' => '', 'headers' => {})
|
24
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stockcruncher
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Richard Delaplace
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-08-
|
11
|
+
date: 2020-08-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|