# frozen_string_literal: true module Cryptum # This plugin is used to Submit a Limit Order # to Buy Crypto Currency module Event module Buy # Supported Method Parameters:: # Cryptum::Event::Buy.crypto( # ) public_class_method def self.crypto(opts = {}) option_choice = opts[:option_choice] env = opts[:env] bot_conf = opts[:bot_conf] event_history = opts[:event_history] order_type = opts[:order_type] fiat_smallest_decimal = opts[:fiat_smallest_decimal] # fiat_portfolio_file = opts[:fiat_portfolio_file] order_history = opts[:order_history] crypto_smallest_decimal = opts[:crypto_smallest_decimal] # base_min_size = opts[:base_min_size] min_market_funds = this_product[:min_market_funds] indicator_status = opts[:indicator_status] # Initialize some bot_conf variables pie_in_sky_buy_percent = bot_conf[:pie_in_sky_buy_percent].to_f autotrade_portfolio_percent = bot_conf[:autotrade_portfolio_percent].to_f # target_profit_margin_percent = bot_conf[:target_profit_margin_percent].to_f crypto_currency = option_choice.symbol.to_s.upcase.split('_').first portfolio = event_history.order_book[:portfolio] symbol_portfolio = portfolio.select do |this_portfolio| this_portfolio if this_portfolio[:currency] == crypto_currency end symbol_balance = format( '%0.8f', symbol_portfolio.first[:balance].to_f ).to_f # 2. Calculate Price, Size, Fees # Get the middle of last 3 ticker prices # to avoid over purcase blips. last_three_prices_arr = [] last_ticker_price = event_history.order_book[:ticker_price].to_f second_to_last_ticker_price = event_history.order_book[:ticker_price_second_to_last].to_f third_to_last_ticker_price = event_history.order_book[:ticker_price_third_to_last].to_f last_three_prices_arr.push(last_ticker_price) last_three_prices_arr.push(second_to_last_ticker_price) last_three_prices_arr.push(third_to_last_ticker_price) case order_type when :pie limit_price = last_three_prices_arr.sort[1] pie_in_sky_buy_percent_cast_as_decimal = format( '%0.2f', pie_in_sky_buy_percent * 0.01 ).to_f limit_price -= (limit_price * pie_in_sky_buy_percent_cast_as_decimal) when :tpm limit_price = last_three_prices_arr.sort[1] when :gtfo # price = format("%0.#{fiat_smallest_decimal}f", limit_price) raise "ERROR: Why is a Buy Submitted for #{order_type}?" else raise "ERROR: Unknown order_type: #{order_type}" end price = format("%0.#{fiat_smallest_decimal}f", limit_price) # TODO: Determine if our N% Autotrade # Threshold has already been met # Buying Crypto w/ Fiat autotrade_portfolio_percent_cast_as_decimal = format( '%0.7f', autotrade_portfolio_percent * 0.01 ).to_f fiat_portfolio = event_history.order_book[:fiat_portfolio] fiat_balance_available = format( "%0.#{fiat_smallest_decimal}f", fiat_portfolio.first[:available] ).to_f # Make sure size is within constraints # of autotrade_portfolio_percent total_limit_buy_orders_open = order_history.select do |orders| orders[:type] == 'limit' && orders[:side] == 'buy' && orders[:status] == 'open' end total_limit_buy_order_open_tot = total_limit_buy_orders_open.length total_limit_buy_orders_open_size = total_limit_buy_orders_open.inject(0) do |sum, hash| sum + hash[:size].to_f end.to_f fiat_to_autotrade = fiat_balance_available * autotrade_portfolio_percent_cast_as_decimal calc_fiat_to_buy = (fiat_to_autotrade / last_ticker_price) - symbol_balance size = format( "%0.#{crypto_smallest_decimal}f", calc_fiat_to_buy - total_limit_buy_orders_open_size ) if min_market_funds.to_i >= 1 size = ( (calc_fiat_to_buy - total_limit_buy_orders_open_size).to_i - min_market_funds.to_i ).to_s end if size.to_f >= min_market_funds.to_f && total_limit_buy_order_open_tot.zero? && price.to_f.positive? # SUBMIT BUY ORDER event_history.order_submitted = true event_history.event_notes = "{ \"event_type\": \"#{event_history.event_type}\", \"cancel\": \"#{event_history.order_canceled}\", \"submitted\": \"#{event_history.order_submitted}\" }" if option_choice.proxy event_history = Cryptum::API.submit_limit_order( option_choice: option_choice, env: env, price: price, size: size, buy_or_sell: :buy, order_type: order_type, event_history: event_history, indicator_status: indicator_status ) end event_history rescue StandardError => e raise e end # Display Usage for this Module public_class_method def self.help puts "USAGE: event_history = #{self}.crypto() " end end end end