## 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