Buying in cash or coins
In my opinion, "buying" should be encapsulated in it's own method that needs to know the symbol, cash and coin amounts.

Since buying is transactional and both actions need to happen or be rolled back, I think it's a good candidate for it's own method and shouldn't be mixed with converting currencies whioch in my opinion is a pre-requisite to buying. If, for example, there is an error with converting the currencies, buy shouldn't be called at all.

Moreover, there may be side effects to buying like managing stock and dispatching the goods so that makes it an even better candidate for it's own method.

Maybe like this:

def buy(symbol, cash_amt, coin_amt)
  # Both coin and cash amount need to be passed
  raise ArgumentError unless coin_amt &amp;&amp; cash_amt

  withdraw_cash(cash_amt)
  @transactions &lt;&lt; Transaction.new(symbol, coin_amt, market_price)
end

def market_price(symbol)
  @exchange.price_by_symbol(symbol)
end

def buy_in_cash(symbol, cash_amt)
  coin_amt = cash_to_coin(cash_amt, market_price(symbol))
  buy(symbol, cash_amt, coin_amt)
end

def buy_in_coin(symbol, coin_amt)
  cash_amt = coin_to_cash(coin_amt, market_price(symbol))
  buy(symbol, cash_amt, coin_amt)
end