class BitexBot::ClosingFlow
Close buy/sell positions.
Public Class Methods
close_open_positions()
click to toggle source
Start a new CloseBuy
that closes existing OpenBuy's by selling on another exchange what was just bought on bitex. rubocop:disable Metrics/AbcSize
# File lib/bitex_bot/models/closing_flow.rb, line 12 def self.close_open_positions return unless open_positions.any? positions = open_positions quantity = positions.sum(&:quantity) amount = positions.sum(&:amount) / fx_rate price = suggested_amount(positions) / quantity unless Robot.taker.enough_order_size?(quantity, price) Robot.log( :info, "Closing: #{Robot.taker.name} - enough order size for #{Robot.taker.base.upcase} #{quantity}"\ " @ #{Robot.taker.quote.upcase} #{price}" ) return end create_closing_flow!(price, quantity, amount, positions) end
create_closing_flow!(price, quantity, amount, open_positions)
click to toggle source
# File lib/bitex_bot/models/closing_flow.rb, line 41 def self.create_closing_flow!(price, quantity, amount, open_positions) flow = create!(desired_price: price, quantity: quantity, amount: amount, open_positions: open_positions) Robot.log( :info, "Closing: created #{self}##{flow.id}, desired price: #{flow.desired_price}, quantity: #{flow.quantity}, "\ "amount: #{flow.amount}." ) flow.create_initial_order_and_close_position! nil end
open_positions()
click to toggle source
rubocop:enable Metrics/AbcSize
# File lib/bitex_bot/models/closing_flow.rb, line 32 def self.open_positions open_position_class.open end
suggested_amount(positions)
click to toggle source
close_open_positions
helpers
# File lib/bitex_bot/models/closing_flow.rb, line 37 def self.suggested_amount(positions) positions.map { |p| p.quantity * p.opening_flow.suggested_closing_price }.sum end
Public Instance Methods
create_initial_order_and_close_position!()
click to toggle source
end: close_open_positions
helpers
# File lib/bitex_bot/models/closing_flow.rb, line 53 def create_initial_order_and_close_position! create_order_and_close_position(quantity, desired_price) end
estimate_fiat_profit()
click to toggle source
# File lib/bitex_bot/models/closing_flow.rb, line 63 def estimate_fiat_profit raise 'self subclass responsibility' end
positions_balance_amount()
click to toggle source
# File lib/bitex_bot/models/closing_flow.rb, line 67 def positions_balance_amount close_positions.sum(:amount) * fx_rate end
sync_closed_positions()
click to toggle source
TODO: should receive a order_ids and user_transaccions array, then each Wrapper should know how to search for them.
# File lib/bitex_bot/models/closing_flow.rb, line 58 def sync_closed_positions # Maybe we couldn't create the bitstamp order when this flow was created, so we try again when syncing. latest_close.nil? ? create_initial_order_and_close_position! : create_or_cancel! end
Private Instance Methods
cancel!(order)
click to toggle source
create_or_cancel! helpers
# File lib/bitex_bot/models/closing_flow.rb, line 96 def cancel!(order) Robot.with_cooldown do Robot.log(:debug, "Finalising #{order.raw.class}##{order.id}") order.cancel! Robot.log(:debug, "Finalised #{order.raw.class}##{order.id}") end rescue StandardError => error Robot.log(:debug, error) nil # just pass, we'll keep on trying until it's not in orders anymore. end
create_next_position!()
click to toggle source
This use hooks methods, these must be defined in the subclass:
estimate_crypto_profit amount_positions_balance next_price_and_quantity
rubocop:disable Metrics/AbcSize
# File lib/bitex_bot/models/closing_flow.rb, line 112 def create_next_position! next_price, next_quantity = next_price_and_quantity if Robot.taker.enough_order_size?(next_quantity, next_price) create_order_and_close_position(next_quantity, next_price) else update!(crypto_profit: estimate_crypto_profit, fiat_profit: estimate_fiat_profit, fx_rate: fx_rate, done: true) Robot.log( :info, "Closing: Finished #{self.class} ##{id} earned"\ " #{Robot.maker.quote.upcase} #{fiat_profit} and #{Robot.maker.base.upcase} #{crypto_profit}." ) end end
create_or_cancel!()
click to toggle source
sync_closed_positions
helpers rubocop:disable Metrics/AbcSize
# File lib/bitex_bot/models/closing_flow.rb, line 75 def create_or_cancel! order_id = latest_close.order_id.to_s order = Robot.with_cooldown { Robot.taker.orders.find { |o| o.id.to_s == order_id } } # When order is nil it means the other exchange is done executing it so we can now have a look of all the sales that were # spawned from it. if order.nil? sync_position(order_id) create_next_position! elsif latest_close.created_at < close_time_to_live.seconds.ago cancel!(order) end end
create_order_and_close_position(quantity, price)
click to toggle source
This use hooks methods, these must be defined in the subclass:
order_type
rubocop:disable Metrics/AbcSize
# File lib/bitex_bot/models/closing_flow.rb, line 143 def create_order_and_close_position(quantity, price) # TODO: investigate how to generate an ID to insert in the fields of goals where possible. Robot.log( :info, "Closing: Going to place #{order_type} order for #{self.class} ##{id}"\ " #{Robot.taker.base.upcase} #{quantity} @ #{Robot.taker.quote.upcase} #{price}" ) order = Robot.taker.place_order(order_type, price, quantity) Robot.log( :info, "Closing: #{Robot.taker.name} placed #{order.type} with price: #{order.price} @ quantity #{order.amount}.\n"\ "Closing: Going to create Close#{order.type.to_s.capitalize} position.\n" ) close_positions.create!(order_id: order.id) end
latest_close()
click to toggle source
rubocop:enable Metrics/AbcSize
# File lib/bitex_bot/models/closing_flow.rb, line 90 def latest_close close_positions.last end
price_variation(closes_count)
click to toggle source
next_price_and_quantity helpers
# File lib/bitex_bot/models/closing_flow.rb, line 135 def price_variation(closes_count) closes_count**2 * 0.03 end
sync_position(order_id)
click to toggle source
rubocop:enable Metrics/AbcSize
# File lib/bitex_bot/models/closing_flow.rb, line 127 def sync_position(order_id) latest = latest_close latest.amount, latest.quantity = Robot.taker.amount_and_quantity(order_id) latest.save! end