Class: StockCruncher::InfluxDB

Inherits:
Object
  • Object
show all
Defined in:
lib/stockcruncher/influxdb.rb

Overview

this is a class to write time series to database

Instance Method Summary collapse

Constructor Details

#initialize(config, insecure = false) ⇒ InfluxDB

Class constructor method



11
12
13
14
# File 'lib/stockcruncher/influxdb.rb', line 11

def initialize(config, insecure = false)
  @cfg = config[self.class.name.split('::').last]
  @insecure = insecure
end

Instance Method Details

#calculate_missing_data(hash) ⇒ Object

Method to calculate missing data (previousClose, change, changePercent)



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/stockcruncher/influxdb.rb', line 17

def calculate_missing_data(hash)
  keys = hash.keys
  hash.each_with_index do |(date, v), index|
    prevday = keys[index + 1]
    next if prevday.nil?

    prevclose = hash[prevday]['close']
    hash[date] = v.merge(generate_missing_data(v['close'], prevclose))
  end
  hash
end

#change(value, base) ⇒ Object

Method to calculate change difference



39
40
41
# File 'lib/stockcruncher/influxdb.rb', line 39

def change(value, base)
  (value - base).round(4).to_s
end

#change_percent(value, base) ⇒ Object

Method to calculate percentage of change



44
45
46
# File 'lib/stockcruncher/influxdb.rb', line 44

def change_percent(value, base)
  ((value / base - 1) * 100).round(4).to_s
end

#create_hash(descriptions, values) ⇒ Object

Method to create a new hash from two arrays of keys and values



49
50
51
# File 'lib/stockcruncher/influxdb.rb', line 49

def create_hash(descriptions, values)
  descriptions.split(',').zip(values.split(',')).to_h
end

#export_history(symbol, raw) ⇒ Object

Method to export historical data to database

Raises:

  • (StandardError)


66
67
68
69
70
71
72
73
74
75
# File 'lib/stockcruncher/influxdb.rb', line 66

def export_history(symbol, raw)
  raise StandardError, 'No data to export' if raw.match?(/Error Message/)

  tags = { 'symbol' => symbol }
  timeseries = prepare_daily_timeserie(raw)
  timeseries = calculate_missing_data(timeseries)
  timeseries.each_pair do |date, values|
    write('daily', tags, values, date)
  end
end

#export_last_day(raw) ⇒ Object

Method to export latest data to database

Raises:

  • (StandardError)


54
55
56
57
58
59
60
61
62
63
# File 'lib/stockcruncher/influxdb.rb', line 54

def export_last_day(raw)
  raise StandardError, 'No data to export' if raw.match?(/{}/)

  values = create_hash(*raw.split("\r\n"))
  values['close'] = values.delete('price')
  values['changePercent'] = values['changePercent'].delete('%')
  tags = { 'symbol' => values.delete('symbol') }
  date = values.delete('latestDay')
  write('daily', tags, values, date)
end

#format_values(values) ⇒ Object

Method to format and array of values into comma separated string



78
79
80
81
82
83
84
85
# File 'lib/stockcruncher/influxdb.rb', line 78

def format_values(values)
  string = ''
  values.each_pair do |k, v|
    string += "#{k}=#{v}"
    string += ',' unless k == values.keys.last
  end
  string
end

#generate_missing_data(current, previous) ⇒ Object

Method to generate missing data



30
31
32
33
34
35
36
# File 'lib/stockcruncher/influxdb.rb', line 30

def generate_missing_data(current, previous)
  {
    'previousClose' => previous,
    'change' => change(current.to_f, previous.to_f),
    'changePercent' => change_percent(current.to_f, previous.to_f)
  }
end

#prepare_daily_timeserie(data) ⇒ Object

Method to transform raw data to constructed hash



88
89
90
91
92
93
94
95
96
97
98
# File 'lib/stockcruncher/influxdb.rb', line 88

def prepare_daily_timeserie(data)
  lines = data.split("\r\n")
  desc = lines.shift.split(',').drop(1)
  hash = {}
  lines.each do |line|
    values = line.split(',')
    date = values.shift
    hash[date] = desc.zip(values).to_h
  end
  hash
end

#request(url, body) ⇒ Object

Method to send http post request



101
102
103
104
105
106
107
108
109
110
# File 'lib/stockcruncher/influxdb.rb', line 101

def request(url, body)
  uri = URI.parse(url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = uri.scheme.eql?('https')
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @insecure
  req = Net::HTTP::Post.new(uri.request_uri)
  req.basic_auth(@cfg['user'], @cfg['password'])
  req.body = body
  http.request(req)
end

#write(name, tags, values, date) ⇒ Object

Method to write data in bucket



113
114
115
116
117
118
119
120
# File 'lib/stockcruncher/influxdb.rb', line 113

def write(name, tags, values, date)
  url = "#{@cfg['scheme']}://#{@cfg['host']}:#{@cfg['port']}/write?" \
        "db=#{@cfg['dbname']}"
  timestamp = DateTime.parse(date + 'T18:00:00').strftime('%s%N')
  body = "#{name},#{format_values(tags)} #{format_values(values)} " \
         "#{timestamp}"
  request(url, body)
end