Travis Build Status

CryptoArbitrer

Provides currency conversions across several fiat currencies and crypto currencies. Exchange rates are fetched (and in some cases scraped) from Bitex.la, BTC-E, Open Exchange Rates, Bitstamp, Valor Dolar Blue, eldolarblue.net and Dolar Paralelo.

Given some particular situations in both Venezuela and Argentina, an unofficial but de-facto exchange rate is used for each country's currency (from dolarparalelo.org and eldolarblue.net respectively).

The supported fiat currencies are: usd ars uyu brl clp sgd eur vef

The supported crypto currencies are: btc ltc nmc nvc trc ppc ftc cnc

If you're just looking to use these rates quickly, they are available as a JSON api at conectabitcoin.com

Installation

Add this line to your application's Gemfile:

gem 'crypto_arbitrer'

And then execute:

$ bundle

Or install it yourself as:

$ gem install crypto_arbitrer

Usage

To get the exchange rate from United States Dollars to Argentine Pesos, caching it if possible:

irb > CryptoArbitrer::Base.fetch('usd', 'ars')
=> {'sell' => 7.9, 'buy' => 8.0}

To get the exchange rate from Bitcoin to Argentine Pesos, forcing a new request (ignored cached value if any):

irb > CryptoArbitrer::Base.fetch('usd', 'ars', true)
=> {'sell' => ..., 'buy' => ...}

To get the exchange rate from Bitcoin to Argentine Pesos, using BTC-E instead of BitcoinAverage as the provider for BTC/USD prices:

irb > CryptoArbitrer::Base.fetch('usd', 'ars', false, btc: :btce)
=> {'sell' => ..., 'buy' => ...}

Prices are returned as 'sell' and 'buy' hashes, where 'sell' is the price at which you can sell the given currency (highest bid price) and 'buy' is the price at which is being offered to you by others (lowest ask price).

If you were to buy 10 Bitcoin paying with US Dollars, this is how much you would spend in US Dollars.

irb > 10 * CryptoArbitrer::Base.fetch('btc', 'usd')['buy']
=> 1107.7001 # USD

Caching and Rails

There is basic support for plugging in your own caching mechanism. Caching in Rails is as easy as creating an initializer with the following code:

CryptoArbitrer::Base.cache_backend = lambda do |from, to, block|
  Rails.cache.fetch([from, to], &block)
end

Essentially, you just make a lambda that would receive the currencies to convert from and to, and a block that would return the exchange rate when called.

Keeping an updated cache is also rather simple, I have this short rake task running every 10 minutes:

namespace :exchange_rates do
  desc "Recaches the exchange rates"
  task recache: :environment do
    CryptoArbitrer::Base.supported_conversions.each do |from, to|
      # Notice the third argument to 'fetch', it forces the lookup, ignoring the existing cache.
      rate = CryptoArbitrer::Base.fetch(from, to, true) rescue next
      Rails.cache.delete([from, to])
      Rails.cache.write([from, to], rate)
    end
  end
end

Open Exchange Rates APP ID

Some rates are retrieved from Open Exchange Rates, so in order to make full use of this gem you will need to get an APP ID and set it before attempting to fetch any rate.

CryptoArbitrer::Base.open_exchange_rates_app_id = 'your_app_id'

Mocking web requests when testing your integration.

When testing your integration I highly reccommend mocking all the web requests performed by this gem. There's a simple way to mock all possible crypto arbitrer requests, but you'll need to install webmock.

If you're using rspec you should require webmock/rspec like this:

require 'webmock/rspec'

then on a global before hook:

config.before(:each) do
  mock_crypto_arbitrer_requests!
end

Notice there is no 'unmock' method, but you should never need to worry about testing with actual requests. I have a scheduled travis build that will notify me if the price scrapping starts failing.

Docs available at: http://rubydoc.info/github/nubis/crypto_arbitrer/master/frames

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request