lib/rbtc_arbitrage/campbx.rb
## Ruby module for working with CampBX API
## May 2013
## based on glenbot's python work @ https://github.com/glenbot/campbx/
require 'json'
require 'net/http'
require 'uri'
module CampBX
API_BASE = 'https://campbx.com/api/'
# { method_name => [ url, auth?, [ parameters ] ] }
# See: https://campbx.com/api.php for specifics.
# Each method returns a Hash with JSON data from the API.
# Some parameters are optional.
CALLS = {
'xdepth' => [ 'xdepth', FALSE, [] ],
'xticker' => [ 'xticker', FALSE, [] ],
'my_funds' => ['myfunds', TRUE, [] ],
'my_orders' => ['myorders', TRUE, [] ],
'my_margins' => ['mymargins', TRUE, [] ],
'send_instant' => ['sendinstant', TRUE, [ 'CBXCode', 'BTCAmt' ] ],
'get_btc_address' => ['getbtcaddr', TRUE, [] ],
'send_btc' => ['sendbtc', TRUE, [ 'BTCTo', 'BTCAmt' ] ],
# 'dwolla' => [ nil, TRUE, [] ], # Coming Soon (TM)
'trade_cancel' => ['tradecancel', TRUE, [ 'Type', 'OrderID' ] ],
'trade_enter' => ['tradeenter', TRUE, [ 'TradeMode', 'Quantity', 'Price' ] ],
'trade_advanced' => ['tradeadv', TRUE, [ 'TradeMode', 'Price', 'Quantity', 'FillType', 'DarkPool', 'Expiry' ] ],
# 'margin_buy' => [ nil, TRUE, [] ], # Coming Soon (TM)
# 'short_sell' => [ nil, TRUE, [] ], # Coming Soon (TM)
}
class API
# CampBX API rate limiting probably per IP address (not account)
# which is why we don't limit per instance
@@last = Time.new(0)
@username = nil
@password = nil
def initialize( username=nil, password=nil )
@username = username
@password = password
# Build meta-methods for each API call
CALLS.each do |name|
define_singleton_method name[0], lambda { |*args|
data = CALLS[name[0]]
api_request( [data[0], data[1]], Hash[data[2].zip( args )] )
}
end
end
def api_request( info, post_data={} )
url, auth = info
uri = URI.parse(API_BASE + url + '.php')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl=TRUE
# CampBX advises latency can be >4 minutes when markets are volatile
http.read_timeout = 300
res = nil
request = Net::HTTP::Get.new(uri.request_uri)
if auth then
post_data.merge!({
'user' => @username,
'pass' => @password,
})
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data( post_data )
end
make_request(http, request)
end
def make_request http, request
# CampBX API: max 1 request per 500ms
delta = Time.now - @@last
#puts delta*1000
if delta*1000 <= 500 then
#puts "sleeping! for #{0.5 - delta}"
sleep(0.5 - delta)
end
res = http.request(request)
@@last = Time.now # Update time after request returns
if res.message == 'OK' then # HTTP OK
JSON.parse( res.body )
else # HTTP ERROR
warn "HTTP Error: + #{res.code}"
end
end
end
end