lib/bitcoin/analyzer.rb in bitcoin-api-0.1.0 vs lib/bitcoin/analyzer.rb in bitcoin-api-0.1.1
- old
+ new
@@ -1,28 +1,121 @@
class Bitcoin::Analyzer
+ # input Symbol object, prints results
+ def self.analyze_trades(symbol)
+ trades = Bitcoin::Trade.get_trades_in_range(symbol.id,
+ get_datetimes_from_user)
+ puts ''
+ puts '///// [Analysis Results] /////'
+ puts '|'
+ puts '| Trade with highest price:'
+ puts "| #{get_max(trades).display_details}"
+ puts '| Trade with lowest price:'
+ puts "| #{get_min(trades).display_details}"
+ puts '| Largest trade:'
+ puts "| #{get_max(trades, :quantity).display_details}"
+ end
+
+ def self.analyze_candles(symbol)
+ candles = Bitcoin::Candle.new_from_range(symbol.id, get_datetimes_from_user,
+ interval_from_user)
+ return "No candles found! :(" if !candles
+ puts ''
+ puts '///// [Analysis Results] /////'
+ puts ''
+ puts "Got #{candles.length} candles from #{candles.last.timestamp} - #{candles.first.timestamp}"
+ puts '|'
+ puts '| Period with highest price:'
+ puts "| #{get_max(candles, :max).display_details}"
+ puts '| Period with lowest open:'
+ puts "| #{get_min(candles, :open).display_details}"
+ puts '| Period with lowest volume:'
+ puts "| #{get_min(candles, :volume).display_details}"
+ puts "| Average Volume: #{avg(candles, 'volume')}"
+ puts '| Avg Open, Close, Min and Max:'
+ puts "| #{candle_averages(candles)}"
+ end
+
+ # returns ISO formatted datetime string from user
+ def self.get_datetime
+ d = date_from_user
+ t = time_from_user
+ r = "#{d[0]}-#{d[1]}-#{d[2]}T#{t[0]}:#{t[1]}:#{t[2]}Z"
+ puts "Is this correct? #{d[0]}/#{d[1]}/#{d[2]}, #{t[0]}:#{t[1]}:#{t[2]}"
+ puts 'Y / N'
+ gets.strip.upcase == 'Y' ? r : get_datetime
+ end
+
+ # returns 2-element array with formatted datetimes
+ def self.get_datetimes_from_user
+ puts '*** Enter Start Time *** (2014 or later)'
+ from = get_datetime
+ puts '*** Enter End Time *** (2014 or later)'
+ to = get_datetime
+ [from, to]
+ end
+
+ # calculate moving averages of candles array
+ # return: [ open, close, min, max]
+ def self.candle_averages(candles)
+ result = [0, 0, 0, 0]
+ candles.each do |candle|
+ result[0] += candle.open.to_f
+ result[1] += candle.close.to_f
+ result[2] += candle.min.to_f
+ result[3] += candle.max.to_f
+ end
+ result.map { |e| e / candles.length }
+ end
+
+ # calculate avg of attribute
+ def self.avg(object_array, attribute)
+ num = object_array.length
+ sum = object_array.inject(0) { |memo, e| memo + e.send("#{attribute}").to_i}
+ sum.to_f / num.to_f
+ end
+
+ # returns object with largest attribute
def self.get_max(object_array, attribute = :price)
- object_array.max_by{ |e|
- e.send("#{attribute}")
- }
+ object_array.max_by{ |e| e.send("#{attribute}") }
end
+ # returns object with smallest attribute
def self.get_min(object_array, attribute = :price)
- object_array.min_by{ |e|
- e.send("#{attribute}")
- }
+ object_array.min_by{ |e| e.send("#{attribute}") }
end
- def self.analyze_trades(symbol)
- trades = Bitcoin::Trade.get_trades_in_range(symbol.id)
- puts ""
- puts " ///// [Analysis Results] /////"
- puts "|"
- puts "| Trade with highest price:"
- puts "| #{self.get_max(trades).display_details}"
- puts "| Trade with lowest price:"
- puts "| #{self.get_min(trades).display_details}"
- puts "| Largest trade:"
- puts "| #{self.get_max(trades, :quantity).display_details}"
+ # returns time in array format ['HH', 'MM', 'SS']
+ def self.time_from_user
+ puts 'Enter Time (24-hour format) (hh mm ss)'
+ t = gets.strip.split(' ')
+ if !t[0].to_i.between?(0, 23) || !t[1].to_i.between?(0, 59) || !t[2].to_i.between?(0, 59) || t[0].length != 2 || t[1].length != 2 || t[2].length != 2
+ puts 'Invalid time.'
+ time_from_user
+ end
+ t
+ end
+
+ # returns date in array format ['YYYY', 'MM', 'DD']
+ def self.date_from_user
+ puts 'Enter Year (YYYY MM DD)'
+ d = gets.strip.split(' ')
+ if d[0].to_i < 2014 || !d[1].to_i.between?(1, 12) || !d[2].to_i.between?(1, 31) || d[0].length != 4 || d[1].length != 2 || d[2].length != 2
+ puts 'Invalid Date. Try Again'
+ date_from_user
+ end
+ d
+ end
+
+ def self.interval_from_user
+ puts 'Enter time interval. Accepted values:'
+ puts ' M1 (one minute), M3, M5, M15, M30, '
+ puts ' H1 (one hour), H4, '
+ puts ' D1 (one day), D7, '
+ puts ' 1M (one month)'
+ valid = ['M1', 'M3', 'M5', 'M15', 'M30', 'H1', 'H4', 'D1', 'D7', '1M']
+ input = gets.strip
+ interval_from_user if !valid.any?(input)
+ input
end
end