stockcruncher 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c1fe544c0ab3e0bb05c2cca11cb4363bce698cf88b565d897098420b3b8206ac
4
- data.tar.gz: bc0de76838cf286f9c5400ddc368da33ee2bd748f0a5a29ebed653010e183d8a
3
+ metadata.gz: 51887b6440cf8d3958f52c05d5daa9e77c0bada0e385445ec6bcb6553fe9c16d
4
+ data.tar.gz: 66ade1c3623130c5e5588ceca005bddb201b176d1d81ffbb0cabd41568b1692c
5
5
  SHA512:
6
- metadata.gz: b69c6d91c2160e1e70a339ea68616b27012839b105dcfd0cef5ccf7a9643e3a08fb88738d794cf98e3d4de03e505c32db4a827d45a296d734f7e10d2334eb287
7
- data.tar.gz: 44ecc54323e85117c04bb0aa8b9c2ab54421020a2614b01356988700f610264e1e82a07e88d5fd62f62945c1469c508699b3a78c2dad52a73b988e508ce2264d
6
+ metadata.gz: 0bbdd83e653eadf37c57b6cf5e2bf3234c94ccf74d59ffcd21f995d74260a7673da8a79564f37b4b69715fb5f295d0e1bcf2465fee119a84965cbcc333d0f0bc
7
+ data.tar.gz: 979223a1ee0cba78f9d482d22f3025c17fb0506c487d237b94b5855a7843ef3eca610fd89fcbd0a41c66325a1f9e86786e0b56703d666fbca8d5417dd3906321
data/CHANGELOG CHANGED
@@ -5,3 +5,9 @@ Changelog
5
5
  -----
6
6
 
7
7
  - Initial version
8
+
9
+ 1.1.0
10
+ -----
11
+
12
+ - Add InfluxDB as database.
13
+ - WIP for daily time serie.
data/README.md CHANGED
@@ -25,29 +25,38 @@ to write the data in a database for later calculation and use.
25
25
 
26
26
  $ gem install stockcruncher
27
27
  $ mkdir /etc/stockcruncher && cd /etc/stockcruncher
28
- $ echo $'AlphaVantage:\n apikey: CHANGEME' > stockcruncher.yml
28
+ $ echo 'AlphaVantage:' > stockcruncher.yml
29
+ $ echo ' apikey: CHANGEME' >> stockcruncher.yml
30
+ $ echo 'InfluxDB:' >> stockcruncher.yml
31
+ $ echo ' scheme: http' >> stockcruncher.yml
32
+ $ echo ' host: localhost' >> stockcruncher.yml
33
+ $ echo ' port: 8086' >> stockcruncher.yml
34
+ $ echo ' user: CHANGEMEAGAIN' >> stockcruncher.yml
35
+ $ echo ' password: CHANGEMETOO' >> stockcruncher.yml
36
+ $ echo ' dbname: stock' >> stockcruncher.yml
29
37
 
30
38
  ## Usage
31
39
 
32
40
  An interactive help is available with:
33
41
 
34
- $ stockcruncher help
42
+ $ stockcruncher help [subcommand]
35
43
 
36
44
  ## Examples
37
45
 
38
46
  To get daily time serie data of a symbol:
39
47
 
40
- $ stockcruncher crunch AAPL daily
48
+ $ stockcruncher daily AAPL
41
49
 
42
50
  To get last day endpoint data of a symbol:
43
51
 
44
- $ stockcruncher crunch AAPL quote_endpoint
52
+ $ stockcruncher quote AAPL
45
53
 
46
54
  ## Limitations
47
55
 
48
56
  Data are currently scraped from AlphaVantage API.
49
57
  More source could be great especially because AlphaVantage doesn't provide EU
50
58
  intraday data.
59
+ InfluxDB is used as database to keep time series data.
51
60
 
52
61
  ## Development
53
62
 
@@ -9,28 +9,19 @@ module StockCruncher
9
9
  API_URL = 'https://www.alphavantage.co/query?'
10
10
 
11
11
  # Main method to crunch data.
12
- def crunch_daily(symbol, opts)
13
- url = API_URL + parameters(symbol, 'TIME_SERIES_DAILY') + options_d(opts)
12
+ def crunch_daily(symbol, fullsize)
13
+ url = API_URL + parameters(symbol, 'TIME_SERIES_DAILY')
14
+ url += '&datatype=csv&outputsize=' + (fullsize ? 'full' : 'compact')
14
15
  res = request(url)
15
- puts res.body
16
+ res.body
16
17
  end
17
18
 
18
19
  # Main method to crunch data.
19
- def crunch_quote(symbol, opts)
20
- url = API_URL + parameters(symbol, 'GLOBAL_QUOTE') + options_q(opts)
20
+ def crunch_quote(symbol)
21
+ url = API_URL + parameters(symbol, 'GLOBAL_QUOTE')
22
+ url += '&datatype=csv'
21
23
  res = request(url)
22
- puts res.body
23
- end
24
-
25
- def options_d(opts)
26
- o = '&datatype=' + (opts['json'] ? 'json' : 'csv')
27
- o += '&outputsize=' + (opts['full'] ? 'full' : 'compact')
28
- o
29
- end
30
-
31
- def options_q(opts)
32
- o = '&datatype=' + (opts['json'] ? 'json' : 'csv')
33
- o
24
+ res.body
34
25
  end
35
26
 
36
27
  def parameters(symbol, serie)
@@ -2,18 +2,12 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'thor'
5
+ require 'yaml'
5
6
 
6
7
  module StockCruncher
7
8
  # Simple CLI for StockCruncher
8
9
  class CLI < Thor
9
- desc 'version', 'Print stockcruncher current version'
10
- def version
11
- puts "StockCruncher version #{StockCruncher::VERSION}"
12
- end
13
-
14
- desc('daily SYMBOL [options]',
15
- 'Crunch SYMBOL stock market data for daily time series.')
16
- option(
10
+ class_option(
17
11
  :config,
18
12
  aliases: ['-c'],
19
13
  type: :string,
@@ -21,13 +15,28 @@ module StockCruncher
21
15
  desc: 'Yaml formatted config file to load ' \
22
16
  '(default to /etc/stockcruncher/stockcruncher.yml).'
23
17
  )
24
- option(
25
- :json,
26
- aliases: ['-j'],
18
+ class_option(
19
+ :insecure,
20
+ aliases: ['-k'],
21
+ type: :boolean,
22
+ default: false,
23
+ desc: 'Ignore SSL certificate (default to false).'
24
+ )
25
+ class_option(
26
+ :quiet,
27
+ aliases: ['-q'],
27
28
  type: :boolean,
28
29
  default: false,
29
- desc: 'Json format data (default to csv).'
30
+ desc: 'Run silently (default to false).'
30
31
  )
32
+
33
+ desc 'version', 'Print stockcruncher current version'
34
+ def version
35
+ puts "StockCruncher version #{StockCruncher::VERSION}"
36
+ end
37
+
38
+ desc('daily SYMBOL [options]',
39
+ 'Crunch SYMBOL stock market data for daily time series.')
31
40
  option(
32
41
  :full,
33
42
  aliases: ['-f'],
@@ -37,31 +46,22 @@ module StockCruncher
37
46
  )
38
47
  def daily(symbol)
39
48
  opts = options.dup
40
- cruncher = StockCruncher::AlphaVantage.new(opts['config'])
41
- cruncher.crunch_daily(symbol, opts)
49
+ config = YAML.load_file(opts['config'])
50
+ cruncher = StockCruncher::AlphaVantage.new(config, opts['insecure'])
51
+ raw_data = cruncher.crunch_daily(symbol, opts['full'])
52
+ # TODO: export to DB here
53
+ puts raw_data unless opts['quiet']
42
54
  end
43
55
 
44
56
  desc('quote SYMBOL [options]',
45
57
  'Crunch SYMBOL stock market data for last day quote.')
46
- option(
47
- :config,
48
- aliases: ['-c'],
49
- type: :string,
50
- default: '/etc/stockcruncher/stockcruncher.yml',
51
- desc: 'Yaml formatted config file to load ' \
52
- '(default to /etc/stockcruncher/stockcruncher.yml).'
53
- )
54
- option(
55
- :json,
56
- aliases: ['-j'],
57
- type: :boolean,
58
- default: false,
59
- desc: 'Json format data (default to csv).'
60
- )
61
58
  def quote(symbol)
62
59
  opts = options.dup
63
- cruncher = StockCruncher::AlphaVantage.new(opts['config'])
64
- cruncher.crunch_quote(symbol, opts)
60
+ config = YAML.load_file(opts['config'])
61
+ cruncher = StockCruncher::AlphaVantage.new(config, opts['insecure'])
62
+ raw_data = cruncher.crunch_quote(symbol)
63
+ puts raw_data unless opts['quiet']
64
+ StockCruncher::InfluxDB.new(config).export_last_day(raw_data)
65
65
  end
66
66
  end
67
67
  end
@@ -2,27 +2,22 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'net/http'
5
- require 'yaml'
6
5
 
7
6
  module StockCruncher
8
7
  # This is an data cruncher abstract class.
9
8
  class Cruncher
10
9
  # Class constructor method
11
- def initialize(file)
12
- @config = load_conf(file)
13
- end
14
-
15
- # Method to load configurations described in config_file.
16
- def load_conf(file)
17
- YAML.load_file(file)
10
+ def initialize(config, insecure = false)
11
+ @config = config
12
+ @insecure = insecure
18
13
  end
19
14
 
20
15
  # Method to send http get request
21
- def request(url, insecure = false)
16
+ def request(url)
22
17
  uri = URI.parse(url)
23
18
  http = Net::HTTP.new(uri.host, uri.port)
24
19
  http.use_ssl = uri.scheme.eql?('https')
25
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE if insecure
20
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @insecure
26
21
  req = Net::HTTP::Get.new(uri.request_uri)
27
22
  http.request(req)
28
23
  end
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'net/http'
5
+
6
+ module StockCruncher
7
+ # this is a class to write time series to database
8
+ class InfluxDB
9
+ # Class constructor method
10
+ def initialize(config, insecure = false)
11
+ @cfg = config[self.class.name.split('::').last]
12
+ @insecure = insecure
13
+ end
14
+
15
+ # Method to export latest data to database
16
+ def export_last_day(raw)
17
+ (desc, line) = raw.split("\r\n")
18
+ values = desc.split(',').zip(line.split(',')).to_h
19
+ values['close'] = values.delete('price')
20
+ values['changePercent'] = values['changePercent'].delete('%')
21
+ tags = { 'symbol' => values.delete('symbol') }
22
+ date = values.delete('latestDay')
23
+ write('daily', tags, values, date)
24
+ end
25
+
26
+ # Method to export historical data to database
27
+ def export_history(raw)
28
+ # TODO: export whole history and calculated missing values
29
+ end
30
+
31
+ # Method to format and array of values into comma separated string
32
+ def format_values(values)
33
+ string = ''
34
+ values.each_pair do |k, v|
35
+ string += "#{k}=#{v}"
36
+ string += ',' unless k == values.keys.last
37
+ end
38
+ string
39
+ end
40
+
41
+ # Method to send http post request
42
+ def request(url, body)
43
+ uri = URI.parse(url)
44
+ http = Net::HTTP.new(uri.host, uri.port)
45
+ http.use_ssl = uri.scheme.eql?('https')
46
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @insecure
47
+ req = Net::HTTP::Post.new(uri.request_uri)
48
+ req.basic_auth(@cfg['user'], @cfg['password'])
49
+ req.body = body
50
+ http.request(req)
51
+ end
52
+
53
+ # Method to write data in bucket
54
+ def write(name, tags, values, date)
55
+ url = "#{@cfg['scheme']}://#{@cfg['host']}:#{@cfg['port']}/write?" \
56
+ "db=#{@cfg['dbname']}"
57
+ timestamp = DateTime.parse(date + 'T18:00:00').strftime('%s%N')
58
+ body = "#{name},#{format_values(tags)} #{format_values(values)} " \
59
+ "#{timestamp}"
60
+ request(url, body)
61
+ end
62
+ end
63
+ end
@@ -2,5 +2,5 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module StockCruncher
5
- VERSION = '1.0.2'
5
+ VERSION = '1.1.0'
6
6
  end
@@ -1,2 +1,9 @@
1
1
  AlphaVantage:
2
2
  apikey: demo
3
+ InfluxDB:
4
+ scheme: http
5
+ host: localhost
6
+ port: 8086
7
+ user: testuser
8
+ password: testpassword
9
+ dbname: test
@@ -2,6 +2,10 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
+ quote = 'symbol,open,high,low,price,volume,latestDay,previousClose,change,ch' \
6
+ "angePercent\r\nSYM,100.0000,100.1000,99.9000,100.0000,4,2020-07-30," \
7
+ "100.0000,0.0000,0.0000%\r\n"
8
+
5
9
  describe StockCruncher::CLI do
6
10
  context 'version' do
7
11
  it 'prints the version.' do
@@ -18,7 +22,7 @@ describe StockCruncher::CLI do
18
22
 
19
23
  context 'quote SYM -c spec/files/stockcruncher.yml' do
20
24
  it 'Get the quote for SYM.' do
21
- expect { start(self) }.to output("{}\n").to_stdout
25
+ expect { start(self) }.to output(quote).to_stdout
22
26
  end
23
27
  end
24
28
 
@@ -2,15 +2,21 @@
2
2
 
3
3
  require 'spec_helper'
4
4
 
5
+ quote = 'symbol,open,high,low,price,volume,latestDay,previousClose,change,ch' \
6
+ "angePercent\r\nSYM,100.0000,100.1000,99.9000,100.0000,4,2020-07-30," \
7
+ "100.0000,0.0000,0.0000%\r\n"
8
+
5
9
  RSpec.configure do |config|
6
10
  config.before(:each) do
7
11
  # requests an API without extra arguments
8
12
  stub_request(:get, 'https://www.alphavantage.co/query?' \
9
13
  'function=GLOBAL_QUOTE&symbol=SYM&apikey=demo&datatype=csv')
10
- .to_return('status' => 200, 'body' => '{}', 'headers' => {})
14
+ .to_return('status' => 200, 'body' => quote, 'headers' => {})
11
15
  stub_request(:get, 'https://www.alphavantage.co/query?' \
12
16
  'function=TIME_SERIES_DAILY&symbol=SYM&apikey=demo' \
13
17
  '&datatype=csv&outputsize=compact')
14
18
  .to_return('status' => 200, 'body' => '{}', 'headers' => {})
19
+ stub_request(:post, 'http://localhost:8086/write?db=test')
20
+ .to_return('status' => 204, 'body' => '', 'headers' => {})
15
21
  end
16
22
  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.0.2
4
+ version: 1.1.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-07-30 00:00:00.000000000 Z
11
+ date: 2020-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -130,10 +130,10 @@ files:
130
130
  - lib/stockcruncher/alphavantage.rb
131
131
  - lib/stockcruncher/cli.rb
132
132
  - lib/stockcruncher/cruncher.rb
133
+ - lib/stockcruncher/influxdb.rb
133
134
  - lib/stockcruncher/version.rb
134
135
  - spec/files/stockcruncher.yml
135
136
  - spec/spec_helper.rb
136
- - spec/stockcruncher/alphavantage_spec.rb
137
137
  - spec/stockcruncher/cli_spec.rb
138
138
  - spec/stockcruncher/stubs/servers_stubs.rb
139
139
  - spec/stockcruncher_spec.rb
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'spec_helper'
4
-
5
- describe StockCruncher::AlphaVantage do
6
- context 'daily SYM -c spec/files/stockcruncher.yml' do
7
- it 'requests a daily time serie.' do
8
- expect { start(self) }.to output("{}\n").to_stdout
9
- end
10
- end
11
- context 'quote SYM -c spec/files/stockcruncher.yml' do
12
- it 'requests a quote endpoint.' do
13
- expect { start(self) }.to output("{}\n").to_stdout
14
- end
15
- end
16
- end