mexbt 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 604151fdb300fb326b4d2a366c034c6206a31bf6
4
+ data.tar.gz: 7d51e7ad2280adbf0278676b21a65e7f4327161e
5
+ SHA512:
6
+ metadata.gz: 07d0a969677141a08628aa1dd8d7882781732cb1a40a1647cfb7ca7fef5971537793b124cc7c75eef605e39e4d070f9139380f8f38def1d3b86c5c4fde4980a1
7
+ data.tar.gz: ac7c77ca0b95104da901b6ee3031f5fc81acc7b18b9de67397925f796ac2cf52e4ec7b478e23a95ae7089067f32b1d8c98822f2e2629274751b906153c65114d
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+ gem "activesupport"
5
+ gem "rest_client"
6
+
7
+ group :test do
8
+ gem "rspec"
9
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,48 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ mexbt (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activesupport (4.1.8)
10
+ i18n (~> 0.6, >= 0.6.9)
11
+ json (~> 1.7, >= 1.7.7)
12
+ minitest (~> 5.1)
13
+ thread_safe (~> 0.1)
14
+ tzinfo (~> 1.1)
15
+ diff-lcs (1.2.5)
16
+ i18n (0.6.11)
17
+ json (1.8.1)
18
+ minitest (5.4.3)
19
+ netrc (0.7.9)
20
+ rake (10.3.2)
21
+ rest_client (1.8.2)
22
+ netrc (~> 0.7.7)
23
+ rspec (3.1.0)
24
+ rspec-core (~> 3.1.0)
25
+ rspec-expectations (~> 3.1.0)
26
+ rspec-mocks (~> 3.1.0)
27
+ rspec-core (3.1.7)
28
+ rspec-support (~> 3.1.0)
29
+ rspec-expectations (3.1.2)
30
+ diff-lcs (>= 1.2.0, < 2.0)
31
+ rspec-support (~> 3.1.0)
32
+ rspec-mocks (3.1.3)
33
+ rspec-support (~> 3.1.0)
34
+ rspec-support (3.1.2)
35
+ thread_safe (0.3.4)
36
+ tzinfo (1.2.2)
37
+ thread_safe (~> 0.1)
38
+
39
+ PLATFORMS
40
+ ruby
41
+
42
+ DEPENDENCIES
43
+ activesupport
44
+ bundler (~> 1.6)
45
+ mexbt!
46
+ rake
47
+ rest_client
48
+ rspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 williamcoates
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # Mexbt ruby API client
2
+
3
+ This is a lightweight ruby client for the Mexbt exchange API. It doesn't try and do anything clever with the JSON response from the API, it simply
4
+ returns it as-is.
5
+
6
+ # Install
7
+
8
+ If using bundler simply this to your Gemfile:
9
+
10
+ gem 'bitstamp'
11
+
12
+ And run `bundle install` of course.
13
+
14
+ # Ruby version
15
+
16
+ You need to be using Ruby 2.1 or higher.
17
+
18
+ # Public API
19
+
20
+ You can access all the Public API functions with zero configuration. By default they will use the 'BTCMXN' currency pair.
21
+
22
+ Mexbt.ticker
23
+ Mexbt.order_book
24
+ Mexbt.trades(start_index: -1, count: 20)
25
+ Mexbt.trades_by_date(from: Date.civil(2014, 11, 1).to_time.to_i, to: Date.today.to_time.to_i)
26
+
27
+ If you want to choose another currency pair, you can configure it for all calls:
28
+
29
+ Mexbt.configure { |c| c.currency_pair: 'BTCUSD' }
30
+
31
+ Or alternatively you can set it per call:
32
+
33
+ Mexbt.ticker(currency_pair: 'BTCUSD')
34
+
35
+ # Private API
36
+
37
+
38
+ ## Configuration
39
+
40
+ You need to generate an API key pair at https://mexbt.com/api/keys. However if you want to get started quickly we recommend having a play in the sandbox first, see the 'Sandbox' section below.
41
+
42
+ Mexbt.configure do |c|
43
+ mexbt.public_key = "xxx"
44
+ mexbt.private_key = "yyy"
45
+ mexbt.user_id = "email@test.com" # Your registered email address
46
+ mexbt.sandbox = true # Set this to true to use the sandbox
47
+ end
48
+
49
+ ## Order functions
50
+
51
+ Mexbt::Orders.create(amount: 0.1, currency_pair: 'btcmxn') # Create a market buy order for 0.1 BTC for Pesos
52
+ Mexbt::Orders.create(amount: 2, side: :sell, currency_pair: 'btcusd') # Create a market order to sell 2 BTC for USD
53
+ Mexbt::Orders.create(amount: 2, price: 1, side: :buy, type: :limit, currency_pair: 'ltcmxn') # Create a limit order to buy 2 LTC for 1 peso
54
+ Mexbt::Orders.cancel(id: 123, currency_pair: 'btcmxn')
55
+ Mexbt::Orders.cancel_all() # Cancel all orders for the default currency pair
56
+
57
+ ## Account functions
58
+
59
+ Mexbt::Account.balance
60
+ Mexbt::Account.trades
61
+ Mexbt::Account.orders
62
+ Mexbt::Account.deposit_addresses
63
+ Mexbt::Account.withdraw(amount: 1, currency: :btc, address: 'xxx') Mexbt::Account.info # Fetches your user info
64
+
65
+ ## Sandbox
66
+
67
+ It's a good idea to first play with the API in the sandbox, that way you don't need any real money to start trading with the API. Just make sure you configure `sandbox = true`.
68
+
69
+ You can register a sandbox account at https://sandbox.mexbt.com/en/register. It will ask you to validate your email but there is no need, you can login right away at https://sandbox.mexbt.com/en/login. Now you can setup your API keys at https://sandbox.mexbt.com/en/api/keys.
70
+
71
+ Your sandbox account will automatically have a bunch of cash to play with.
72
+
73
+ # API documentation
74
+
75
+ You can find API docs for the Public API at http://docs.mexbtpublicapi.apiary.io
76
+
77
+ API docs for the Private API are at http://docs.mexbtprivateapi.apiary.io
78
+
79
+ There are also docs for the Private API sandbox at http://docs.mexbtprivateapisandbox.apiary.io
80
+
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ begin
2
+ require 'rspec/core/rake_task'
3
+ RSpec::Core::RakeTask.new(:spec)
4
+ rescue LoadError
5
+ end
@@ -0,0 +1,19 @@
1
+ require 'mexbt/private'
2
+ require 'mexbt/common'
3
+
4
+ module Mexbt
5
+ module Account
6
+ include Mexbt::Private
7
+ include Mexbt::Common
8
+
9
+ %w{info balance orders deposit_addresses}.each do |m|
10
+ define_method(m) do
11
+ call(m == 'info' ? 'me' : m.dasherize)
12
+ end
13
+ end
14
+
15
+ def withdraw(amount:, address:, currency: :btc)
16
+ call("withdraw", { ins: currency, amount: amount, sentToAddress: address })
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ require 'rest_client'
2
+
3
+ module Mexbt
4
+ module Client
5
+ include RestClient
6
+ SSL_VERSION = :TLSv1_2
7
+
8
+ def url(path)
9
+ "#{endpoint()}/v1/#{path}"
10
+ end
11
+
12
+ def auth_params
13
+ nonce = (Time.now.to_f*10000).to_i
14
+ {
15
+ apiKey: Mexbt.public_key,
16
+ apiNonce: nonce,
17
+ apiSig: OpenSSL::HMAC.hexdigest('sha256', Mexbt.private_key, "#{nonce}#{Mexbt.user_id}#{Mexbt.public_key}").upcase
18
+ }
19
+ end
20
+
21
+ def call(path, params={})
22
+ payload = params
23
+ params.merge!(auth_params) if self.respond_to?(:private?)
24
+ res = Request.execute(method: :post, url: url(path), payload: payload.to_json, ssl_version: SSL_VERSION)
25
+ if res.length === 0
26
+ raise "Empty response from API"
27
+ end
28
+ json_response = JSON.parse(res)
29
+ if json_response["isAccepted"]
30
+ json_response
31
+ else
32
+ raise json_response["rejectReason"]
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,7 @@
1
+ module Mexbt
2
+ module Common
3
+ def trades(currency_pair: Mexbt.currency_pair, start_index: -1, count: 10)
4
+ call("trades", { ins: currency_pair, startIndex: start_index, count: count })
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,49 @@
1
+ require 'mexbt/private'
2
+
3
+ module Mexbt
4
+ module Orders
5
+ include Mexbt::Private
6
+
7
+ def create(amount:, price: nil, currency_pair: Mexbt.currency_pair, side: :buy, type: :market)
8
+ type =
9
+ case type
10
+ when :market, 1
11
+ 1
12
+ when :limit, 0
13
+ 0
14
+ else
15
+ raise "Unknown order type '#{type}'"
16
+ end
17
+ params = {
18
+ ins: currency_pair,
19
+ side: side,
20
+ orderType: type,
21
+ qty: amount,
22
+ sessionToken: "c545f765-ce47-4ea5-b206-a9ac0db55fc3"
23
+ }
24
+ params[:px] = price if price
25
+ call("orders/create", params)
26
+ end
27
+
28
+ def cancel(id:, currency_pair: Mexbt.currency_pair)
29
+ call("orders/cancel", { ins: currency_pair, serverOrderId: id })
30
+ end
31
+
32
+ def cancel_all(currency_pair: Mexbt.currency_pair)
33
+ call("orders/cancel-all", { ins: currency_pair } )
34
+ end
35
+
36
+ def modify(id:, action:, currency_pair: Mexbt.currency_pair)
37
+ action =
38
+ case action
39
+ when :move_to_top, 0
40
+ 0
41
+ when :execute_now, 1
42
+ 1
43
+ else
44
+ raise "Action must be one of: :move_to_top, :execute_now"
45
+ end
46
+ call("orders/modify", { ins: currency_pair, serverOrderId: id, modifyAction: action } )
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,16 @@
1
+ require 'mexbt/client'
2
+
3
+
4
+ module Mexbt
5
+ module Private
6
+ include Mexbt::Client
7
+
8
+ def private?
9
+ true
10
+ end
11
+
12
+ def endpoint
13
+ "https://private-api#{Mexbt.sandbox ? '-sandbox' : nil}.mexbt.com"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,33 @@
1
+ require 'mexbt/client'
2
+ require 'mexbt/common'
3
+
4
+ module Mexbt
5
+ module Public
6
+ include Mexbt::Client
7
+ include Mexbt::Common
8
+
9
+ def endpoint
10
+ "https://public-api.mexbt.com"
11
+ end
12
+
13
+ def ticker(currency_pair: Mexbt.currency_pair)
14
+ call("ticker", { productPair: currency_pair })
15
+ end
16
+
17
+ def order_book(currency_pair: Mexbt.currency_pair)
18
+ call("order-book", { productPair: currency_pair })
19
+ end
20
+
21
+ alias :orders :order_book
22
+
23
+ def currency_pairs
24
+ call("product-pairs")
25
+ end
26
+
27
+ alias :product_pairs :currency_pairs
28
+
29
+ def trades_by_date(currency_pair: Mexbt.currency_pair, from:, to:)
30
+ call("trades-by-date", { ins: currency_pair, startDate: from, endDate: to })
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module Mexbt
2
+ VERSION = "0.0.1"
3
+ end
data/lib/mexbt.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'active_support/core_ext'
2
+ require 'active_support/inflector'
3
+ require 'mexbt/public'
4
+ require 'mexbt/account'
5
+ require 'mexbt/orders'
6
+
7
+ module Mexbt
8
+ mattr_accessor :public_key
9
+ mattr_accessor :private_key
10
+ mattr_accessor :user_id
11
+ mattr_accessor :currency_pair
12
+ mattr_accessor :sandbox
13
+
14
+ @@currency_pair = :btcmxn
15
+
16
+ def self.configure
17
+ yield self
18
+ end
19
+
20
+ extend Mexbt::Public
21
+
22
+ module Account
23
+ extend Mexbt::Account
24
+ end
25
+
26
+ module Orders
27
+ extend Mexbt::Orders
28
+ end
29
+
30
+ end
data/mexbt.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mexbt/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mexbt"
8
+ spec.version = Mexbt::VERSION
9
+ spec.authors = ["williamcoates"]
10
+ spec.email = ["william@mexbt.com"]
11
+ spec.summary = %q{meXBT API client}
12
+ spec.homepage = "https://github.com/meXBT/mexbt-ruby"
13
+ spec.license = "MIT"
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_development_dependency "bundler", "~> 1.6"
20
+ spec.add_development_dependency "rake"
21
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mexbt::Private do
4
+
5
+ before do
6
+ Mexbt.configure do | mexbt |
7
+ mexbt.public_key = "1d039abd0e667a4e03767ddef11cb8d5"
8
+ mexbt.private_key = "0e5a8d04838fc43f0f4335c8a380f200"
9
+ mexbt.user_id = "test@mexbt.com"
10
+ mexbt.sandbox = true
11
+ end
12
+ end
13
+
14
+ context Mexbt::Account do
15
+
16
+ it "gives a valid response to all public api functions that require no args" do
17
+ %w{info balance orders deposit_addresses trades}.each do |f|
18
+ res = Mexbt::Account.send(f)
19
+ expect(res["isAccepted"]).to be true
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ context Mexbt::Orders do
26
+
27
+ it "allows creating market orders" do
28
+ res = Mexbt::Orders.create(amount: 0.1, currency_pair: "BTCUSD")
29
+ expect(res["isAccepted"]).to be true
30
+ expect(res["serverOrderId"]).to be_a(Fixnum)
31
+ end
32
+
33
+ it "allows creating limit orders" do
34
+ res = Mexbt::Orders.create(type: :limit, price: 100, amount: 0.1234, currency_pair: "BTCUSD")
35
+ expect(res["isAccepted"]).to be true
36
+ expect(res["serverOrderId"]).to be_a(Fixnum)
37
+ end
38
+
39
+ it "raises an exception if order type not recognised" do
40
+ expect { Mexbt::Orders.create(type: :boom, amount: 0.2) }.to raise_error("Unknown order type 'boom'")
41
+ end
42
+
43
+ context "modifying and cancelling orders" do
44
+
45
+ let(:order_id) {Mexbt::Orders.create(type: :limit, price: 100, amount: 0.1, currency_pair: "BTCUSD")["serverOrderId"]}
46
+
47
+ it "allows converting limit orders to market orders" do
48
+ res = Mexbt::Orders.modify(id: order_id, currency_pair: "BTCUSD", action: :execute_now)
49
+ expect(res["isAccepted"]).to be true
50
+ end
51
+
52
+ it "allows moving orders to the top of the book" do
53
+ res = Mexbt::Orders.modify(id: order_id, currency_pair: "BTCUSD", action: :move_to_top)
54
+ expect(res["isAccepted"]).to be true
55
+ end
56
+
57
+ it "allows cancelling individual orders" do
58
+ res = Mexbt::Orders.cancel(id: order_id, currency_pair: "BTCUSD")
59
+ expect(res["isAccepted"]).to be true
60
+ orders = Mexbt::Account.orders["openOrdersInfo"]
61
+ orders.each do |open_orders|
62
+ if open_orders["ins"] === "BTCUSD"
63
+ open_orders["openOrders"].each do |usd_order|
64
+ if usd_order["ServerOrderId"] === order_id
65
+ fail("Order was cancelled but still open")
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ it "allows cancelling all orders" do
73
+ res = Mexbt::Orders.cancel_all(currency_pair: "BTCUSD")
74
+ expect(res["isAccepted"]).to be true
75
+ orders = Mexbt::Account.orders["openOrdersInfo"]
76
+ orders.each do |open_orders|
77
+ if open_orders["ins"] === "BTCUSD"
78
+ expect(open_orders["openOrders"]).to eql([])
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mexbt do
4
+
5
+ it "gives a valid response to all public api functions that require no args" do
6
+ %w{ticker trades currency_pairs product_pairs orders order_book}.each do |f|
7
+ res = Mexbt.send(f)
8
+ expect(res["isAccepted"]).to be true
9
+ end
10
+ end
11
+
12
+ it "allows passing a custom currency pair to functions that accept it" do
13
+ %w{ticker trades orders order_book}.each do |f|
14
+ res = Mexbt.send(f, currency_pair: 'BTCUSD')
15
+ expect(res["isAccepted"]).to be true
16
+ end
17
+ end
18
+
19
+ it "allows you to fetch trades by date range" do
20
+ res = Mexbt.trades_by_date(from: Time.now.to_i, to: Time.now.to_i)
21
+ expect(res["isAccepted"]).to be true
22
+ expect(res["trades"]).to eql([])
23
+ end
24
+
25
+ end
@@ -0,0 +1,14 @@
1
+ require 'mexbt'
2
+
3
+ RSpec.configure do |config|
4
+ config.expect_with :rspec do |expectations|
5
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
6
+ end
7
+ config.mock_with :rspec do |mocks|
8
+ # Prevents you from mocking or stubbing a method that does not exist on
9
+ # a real object. This is generally recommended, and will default to
10
+ # `true` in RSpec 4.
11
+ mocks.verify_partial_doubles = true
12
+ end
13
+ config.order = :random
14
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mexbt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - williamcoates
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ - william@mexbt.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".rspec"
49
+ - Gemfile
50
+ - Gemfile.lock
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - lib/mexbt.rb
55
+ - lib/mexbt/account.rb
56
+ - lib/mexbt/client.rb
57
+ - lib/mexbt/common.rb
58
+ - lib/mexbt/orders.rb
59
+ - lib/mexbt/private.rb
60
+ - lib/mexbt/public.rb
61
+ - lib/mexbt/version.rb
62
+ - mexbt.gemspec
63
+ - spec/private_api_spec.rb
64
+ - spec/public_api_spec.rb
65
+ - spec/spec_helper.rb
66
+ homepage: https://github.com/meXBT/mexbt-ruby
67
+ licenses:
68
+ - MIT
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.2.2
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: meXBT API client
90
+ test_files:
91
+ - spec/private_api_spec.rb
92
+ - spec/public_api_spec.rb
93
+ - spec/spec_helper.rb