# frozen_string_literal: true module Cryptum # Cryptum::UI Module used for Presenting the # Cryptum Curses Interface module UI # Update the Ticker section of the UI module Ticker public_class_method def self.refresh(opts = {}) start_time = opts[:start_time] ticker_win = opts[:ticker_win] event_history = opts[:event_history] event = opts[:event] order_book = event_history.order_book this_product = order_book[:this_product] quote_increment = this_product[:quote_increment] fiat_smallest_decimal = quote_increment.to_s.split('.')[-1].length symbol_out = this_product[:id] fiat = this_product[:quote_currency].to_sym fiat_symbol = '?' fiat_symbol = '$' if fiat == :USD fiat_symbol = "\u20ac" if fiat == :EUR last_ticker_price = order_book[:ticker_price].to_f second_to_last_ticker_price = order_book[:ticker_price_second_to_last].to_f sequence = event[:sequence].to_i last_sequence = order_book[:sequence].to_i order_book[:sequence] = sequence return unless sequence >= last_sequence # Useful for detecting dropped messages but it's usually a lot. # if last_sequence + 1 < sequence # sequence_diff = sequence - last_sequence # File.open('/tmp/cryptum-errors.txt', 'a') do |f| # f.puts Time.now.strftime('%Y-%m-%d %H:%M:%S.%N%z') # f.puts "Module: #{self}" # f.puts 'Messages likely dropped:' # f.puts "This Sequence: #{sequence}" # f.puts "Last Sequence: #{last_sequence}" # f.puts "Sequence Diff: #{sequence_diff}\n\n\n" # end # end open_24h = event[:open_24h].to_f order_book[:open_24h] = open_24h open_24h_out = "#{Cryptum.open_symbol} #{fiat_symbol}#{Cryptum.beautify_large_number(value: format("%0.#{fiat_smallest_decimal}f", open_24h))}" beautify_ticker = Cryptum.beautify_large_number( value: format("%0.#{fiat_smallest_decimal}f", event[:price].to_f) ) ticker_fmt = "#{fiat_symbol}#{beautify_ticker}" if last_ticker_price.zero? ticker_price_color = :white ticker_price_out = "#{Cryptum.flat_arrow} #{ticker_fmt}" elsif last_ticker_price < event[:price].to_f ticker_price_color = :green ticker_price_out = "#{Cryptum.up_arrow} #{ticker_fmt}" elsif last_ticker_price > event[:price].to_f ticker_price_color = :red ticker_price_out = "#{Cryptum.down_arrow} #{ticker_fmt}" else ticker_price_color = :yellow ticker_price_out = "#{Cryptum.flat_arrow} #{ticker_fmt}" end order_book[:ticker_price_third_to_last] = format("%0.#{fiat_smallest_decimal}f", second_to_last_ticker_price) order_book[:ticker_price_second_to_last] = format("%0.#{fiat_smallest_decimal}f", last_ticker_price) order_book[:ticker_price] = format("%0.#{fiat_smallest_decimal}f", event[:price].to_f) volume_24h = format('%0.7f', event[:volume_24h]) volume_24h_out = Cryptum.beautify_large_number( value: volume_24h ) order_book[:volume_24h] = volume_24h volume_30d = format('%0.7f', event[:volume_30d]) volume_30d_out = Cryptum.beautify_large_number( value: volume_30d ) high_24h = format( "%0.#{fiat_smallest_decimal}f", event[:high_24h] ) high_24h_out = Cryptum.beautify_large_number( value: high_24h ) order_book[:high_24h] = high_24h low_24h = format( "%0.#{fiat_smallest_decimal}f", event[:low_24h] ) low_24h_out = Cryptum.beautify_large_number( value: low_24h ) order_book[:low_24h] = low_24h margin_percent_open_24h = (1 - (open_24h / order_book[:ticker_price].to_f)) * 100 beautify_margin_percent_open_24h = Cryptum.beautify_large_number( value: format('%0.4f', margin_percent_open_24h) ) if margin_percent_open_24h.positive? margin_percent_open_24h_color = :green trend = 'BULL' margin_percent_open_24h_out = "#{Cryptum.up_arrow} #{beautify_margin_percent_open_24h}% (#{trend})" elsif margin_percent_open_24h.negative? # Space removed to account for negative number. margin_percent_open_24h_color = :red trend = 'BEAR' margin_percent_open_24h_out = "#{Cryptum.down_arrow}#{beautify_margin_percent_open_24h}% (#{trend})" else trend = 'FLAT' margin_percent_open_24h_color = :yellow margin_percent_open_24h_out = "#{Cryptum.flat_arrow} #{beautify_margin_percent_open_24h}% (#{trend})" end order_history = order_book[:order_history] open_sell_orders = order_history.select do |order| order[:status] == 'open' && order[:side] == 'sell' end sorted_open_sell_orders = open_sell_orders.sort_by do |order| order[:price].to_f end lowest_selling_price = event_history.lowest_selling_price lowest_selling_price = sorted_open_sell_orders.first[:price] unless sorted_open_sell_orders.empty? event_history.lowest_selling_price = lowest_selling_price.to_f highest_selling_price = event_history.highest_selling_price highest_selling_price = sorted_open_sell_orders.last[:price] unless sorted_open_sell_orders.empty? event_history.highest_selling_price = highest_selling_price.to_f lowest_selling_price_out = Cryptum.beautify_large_number( value: format( "%0.#{fiat_smallest_decimal}f", lowest_selling_price ) ) highest_selling_price_out = Cryptum.beautify_large_number( value: format( "%0.#{fiat_smallest_decimal}f", highest_selling_price ) ) # event_history.order_book = order_book # TODO: Everything Above this Line Needs to be Indicators ^ # UI col_just1 = 15 col_just2 = 14 col_just3 = 21 col_just3_alt = (Curses.cols - Cryptum::UI.col_third) - 1 col_just4 = (Curses.cols - Cryptum::UI.col_fourth) - 1 # ROW 1 out_line_no = 0 Cryptum::UI.line( ui_win: ticker_win, out_line_no: out_line_no ) out_line_no += 1 ticker_win.setpos(out_line_no, Cryptum::UI.col_first) ticker_win.clrtoeol Cryptum::UI.colorize( ui_win: ticker_win, color: :yellow, style: :bold, string: symbol_out.ljust(col_just1) ) ticker_win.setpos(out_line_no, Cryptum::UI.col_second) Cryptum::UI.colorize( ui_win: ticker_win, color: margin_percent_open_24h_color, style: :bold, string: margin_percent_open_24h_out.ljust(col_just2) ) ticker_win.setpos(out_line_no, Cryptum::UI.col_third) Cryptum::UI.colorize( ui_win: ticker_win, color: :blue, style: :bold, string: open_24h_out.ljust(col_just3) ) ticker_win.setpos(out_line_no, Cryptum::UI.col_fourth) Cryptum::UI.colorize( ui_win: ticker_win, color: ticker_price_color, style: :bold, string: ticker_price_out.rjust(col_just4) ) # ROW 2 out_line_no += 1 ticker_win.setpos(out_line_no, Cryptum::UI.col_first) ticker_win.clrtoeol Cryptum::UI.colorize( ui_win: ticker_win, color: :white, style: :bold, string: 'High | Low Limit Sell Prices:' ) ticker_win.setpos(out_line_no, Cryptum::UI.col_third) Cryptum::UI.colorize( ui_win: ticker_win, color: :white, style: :bold, string: "$#{highest_selling_price_out} | $#{lowest_selling_price_out}".rjust( col_just3_alt, '.' ) ) # ROW 2 out_line_no += 1 ticker_win.setpos(out_line_no, Cryptum::UI.col_first) ticker_win.clrtoeol Cryptum::UI.colorize( ui_win: ticker_win, color: :green, style: :bold, string: '24 Hr High:' ) ticker_win.setpos(out_line_no, Cryptum::UI.col_third) Cryptum::UI.colorize( ui_win: ticker_win, color: :green, string: "#{Cryptum.up_arrow} #{fiat_symbol}#{high_24h_out}".rjust(col_just3_alt, '.') ) # ROW 3 out_line_no += 1 ticker_win.setpos(out_line_no, Cryptum::UI.col_first) ticker_win.clrtoeol Cryptum::UI.colorize( ui_win: ticker_win, color: :red, string: '24 Hr Low:' ) ticker_win.setpos(out_line_no, Cryptum::UI.col_third) Cryptum::UI.colorize( ui_win: ticker_win, color: :red, string: "#{Cryptum.down_arrow} #{fiat_symbol}#{low_24h_out}".rjust(col_just3_alt, '.') ) # ROW 4 out_line_no += 1 ticker_win.setpos(out_line_no, Cryptum::UI.col_first) ticker_win.clrtoeol Cryptum::UI.colorize( ui_win: ticker_win, color: :blue, style: :bold, string: '24 Hr | 30 Day Market Volume:' ) ticker_win.setpos(out_line_no, Cryptum::UI.col_third) Cryptum::UI.colorize( ui_win: ticker_win, color: :blue, string: "#{volume_24h_out} | #{volume_30d_out}".rjust(col_just3_alt, '.') ) # ROW 5 out_line_no += 1 ticker_win.setpos(out_line_no, Cryptum::UI.col_first) ticker_win.clrtoeol Cryptum::UI.colorize( ui_win: ticker_win, color: :cyan, style: :bold, string: 'Start Time:' ) ticker_win.setpos(out_line_no, Cryptum::UI.col_third) Cryptum::UI.colorize( ui_win: ticker_win, color: :cyan, string: start_time.rjust(col_just3_alt, '.') ) ticker_win.refresh event_history rescue Interrupt, StandardError => e Cryptum::Log.append(level: :error, msg: e, which_self: self, event_history: event_history) end # Display Usage for this Module public_class_method def self.help puts "USAGE: #{self}.refresh( symbol: 'required - Symbol for this Session (e.g. btc-usd)', order_book: 'required - Order Book Data Structure', event: 'required - Event from Coinbase Web Socket' ) " end end end end