mexbt 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +8 -1
- data/Rakefile +3 -1
- data/lib/mexbt/client.rb +4 -3
- data/lib/mexbt/orders.rb +3 -3
- data/lib/mexbt/public.rb +66 -0
- data/lib/mexbt/version.rb +1 -1
- data/mexbt.gemspec +2 -1
- data/spec/public_api_spec.rb +42 -0
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5d3d42c18c0d316d920d381e853d2e2767cb141
|
4
|
+
data.tar.gz: a0508b7182b66874add7b2af78c764014cdcb5d5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1da58e0313428224f94604448d3af8d4a7488c2048ee101c141ecd92c17998afa2a1304275213675772e4fcef2ff5d7a5a136b0a7afc52b86eb75e50486c6b28
|
7
|
+
data.tar.gz: c9a6c57a86e57f64b2037482350a72688f5dc60fcb40387acf2ec1070c4e2b266c30741a7b5aeaa34db797178157fea289247f2b921b29d5f946efd47cbb47cd
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mexbt (0.0.
|
4
|
+
mexbt (0.0.3)
|
5
|
+
activesupport (>= 4.1.8)
|
6
|
+
rest_client (= 1.8.2)
|
5
7
|
|
6
8
|
GEM
|
7
9
|
remote: http://rubygems.org/
|
@@ -40,9 +42,7 @@ PLATFORMS
|
|
40
42
|
ruby
|
41
43
|
|
42
44
|
DEPENDENCIES
|
43
|
-
activesupport
|
44
45
|
bundler (~> 1.6)
|
45
46
|
mexbt!
|
46
47
|
rake
|
47
|
-
rest_client
|
48
48
|
rspec
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Mexbt ruby API client
|
2
2
|
|
3
|
-
This is a lightweight ruby client for the
|
3
|
+
This is a lightweight ruby client for the [meXBT](https://mexbt.com) exchange API. It doesn't try and do anything clever with the JSON response from the API, it simply
|
4
4
|
returns it as-is.
|
5
5
|
|
6
6
|
# Install
|
@@ -23,6 +23,8 @@ You can access all the Public API functions with zero configuration. By default
|
|
23
23
|
Mexbt.order_book
|
24
24
|
Mexbt.trades(start_index: -1, count: 20)
|
25
25
|
Mexbt.trades_by_date(from: Date.civil(2014, 11, 1).to_time.to_i, to: Date.today.to_time.to_i)
|
26
|
+
Mexbt.simulate_market_order(side: :buy, second_currency: 1000, currency_pair: 'btcmxn') # Simulates a market order, which will estimate how many btc you will receive for 1000 mxn
|
27
|
+
Mexbt.simulate_market_order(side: :buy, first_currency: 1, currency_pair: 'btcmxn') # Simulates a market order, which will estimate how many mxn you will spend for 1 btc
|
26
28
|
|
27
29
|
If you want to choose another currency pair, you can configure it for all calls:
|
28
30
|
|
@@ -78,3 +80,8 @@ API docs for the Private API are at http://docs.mexbtprivateapi.apiary.io
|
|
78
80
|
|
79
81
|
There are also docs for the Private API sandbox at http://docs.mexbtprivateapisandbox.apiary.io
|
80
82
|
|
83
|
+
|
84
|
+
# TODO
|
85
|
+
|
86
|
+
Mock out web calls with WebMock so that specs don't break everytime sandbox db is cleaned.
|
87
|
+
|
data/Rakefile
CHANGED
data/lib/mexbt/client.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rest_client'
|
2
|
+
require 'active_support'
|
2
3
|
|
3
4
|
module Mexbt
|
4
5
|
module Client
|
@@ -31,11 +32,11 @@ module Mexbt
|
|
31
32
|
if res.length === 0
|
32
33
|
raise "Empty response from API"
|
33
34
|
end
|
34
|
-
json_response = JSON.parse(res)
|
35
|
-
if json_response[
|
35
|
+
json_response = ActiveSupport::HashWithIndifferentAccess.new(JSON.parse(res))
|
36
|
+
if json_response[:isAccepted]
|
36
37
|
json_response
|
37
38
|
else
|
38
|
-
raise json_response[
|
39
|
+
raise json_response[:rejectReason]
|
39
40
|
end
|
40
41
|
end
|
41
42
|
end
|
data/lib/mexbt/orders.rb
CHANGED
@@ -18,8 +18,7 @@ module Mexbt
|
|
18
18
|
ins: currency_pair,
|
19
19
|
side: side,
|
20
20
|
orderType: type,
|
21
|
-
qty: amount
|
22
|
-
sessionToken: "c545f765-ce47-4ea5-b206-a9ac0db55fc3"
|
21
|
+
qty: amount
|
23
22
|
}
|
24
23
|
params[:px] = price if price
|
25
24
|
call("orders/create", params)
|
@@ -45,5 +44,6 @@ module Mexbt
|
|
45
44
|
end
|
46
45
|
call("orders/modify", { ins: currency_pair, serverOrderId: id, modifyAction: action } )
|
47
46
|
end
|
47
|
+
|
48
48
|
end
|
49
|
-
end
|
49
|
+
end
|
data/lib/mexbt/public.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'mexbt/client'
|
2
2
|
require 'mexbt/common'
|
3
|
+
require 'active_support'
|
3
4
|
|
4
5
|
module Mexbt
|
5
6
|
module Public
|
@@ -29,5 +30,70 @@ module Mexbt
|
|
29
30
|
def trades_by_date(currency_pair: Mexbt.currency_pair, from:, to:)
|
30
31
|
call("trades-by-date", { ins: currency_pair, startDate: from, endDate: to })
|
31
32
|
end
|
33
|
+
|
34
|
+
def simulate_market_order(side: :buy, first_currency: 0, second_currency: 0, currency_pair: Mexbt.currency_pair)
|
35
|
+
if first_currency === 0 and second_currency === 0
|
36
|
+
raise "You must specify either 'first_currency' or 'second_currency' (from the currency pair)"
|
37
|
+
end
|
38
|
+
order_book = order_book(currency_pair: currency_pair)
|
39
|
+
orders =
|
40
|
+
if side.to_s === 'buy'
|
41
|
+
order_book["asks"].sort { |a, b| a["px"] <=> b["px"] }
|
42
|
+
else
|
43
|
+
order_book["bids"].sort { |a, b| b["px"] <=> a["px"] }
|
44
|
+
end
|
45
|
+
if second_currency > 0
|
46
|
+
threshold_target = second_currency
|
47
|
+
threshold_symbol = :cost
|
48
|
+
other_symbol = :amount
|
49
|
+
else
|
50
|
+
threshold_target = first_currency
|
51
|
+
threshold_symbol = :amount
|
52
|
+
other_symbol = :cost
|
53
|
+
end
|
54
|
+
sums = {
|
55
|
+
amount: BigDecimal.new(0, 15),
|
56
|
+
cost: BigDecimal.new(0, 15)
|
57
|
+
}
|
58
|
+
orders.each do |order|
|
59
|
+
next_order = {
|
60
|
+
amount: BigDecimal.new(order["qty"], 15),
|
61
|
+
cost: BigDecimal.new(order["px"], 15) * BigDecimal.new(order["qty"], 15)
|
62
|
+
}
|
63
|
+
threshold_check = sums[threshold_symbol] + next_order[threshold_symbol]
|
64
|
+
if threshold_check > threshold_target
|
65
|
+
over = threshold_check - threshold_target
|
66
|
+
percent_needed = (next_order[threshold_symbol] - over) / next_order[threshold_symbol]
|
67
|
+
sums[other_symbol] += next_order[other_symbol] * percent_needed
|
68
|
+
sums[threshold_symbol] = threshold_target
|
69
|
+
break
|
70
|
+
else
|
71
|
+
sums[:amount] += next_order[:amount]
|
72
|
+
sums[:cost] += next_order[:cost]
|
73
|
+
break if sums[threshold_symbol] == threshold_target
|
74
|
+
end
|
75
|
+
end
|
76
|
+
if sums[threshold_symbol] < threshold_target
|
77
|
+
raise "Order book does not contain enough orders to satify simulated order!"
|
78
|
+
end
|
79
|
+
res = {
|
80
|
+
first_amount: round(sums[:amount], currency_pair, :first),
|
81
|
+
second_amount: round(sums[:cost], currency_pair, :second)
|
82
|
+
}
|
83
|
+
ActiveSupport::HashWithIndifferentAccess.new(res)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def round(amount, pair, which)
|
89
|
+
currency = which === :first ? pair.to_s[0,3] : pair.to_s[-3..-1]
|
90
|
+
decimal_places =
|
91
|
+
if ['btc', 'ltc'].include?(currency.downcase)
|
92
|
+
8
|
93
|
+
else
|
94
|
+
2
|
95
|
+
end
|
96
|
+
amount.round(decimal_places).to_f
|
97
|
+
end
|
32
98
|
end
|
33
99
|
end
|
data/lib/mexbt/version.rb
CHANGED
data/mexbt.gemspec
CHANGED
@@ -5,6 +5,7 @@ require 'mexbt/version'
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "mexbt"
|
8
|
+
spec.description = "A lightweight ruby client for the meXBT exchange API"
|
8
9
|
spec.version = Mexbt::VERSION
|
9
10
|
spec.authors = ["williamcoates"]
|
10
11
|
spec.email = ["william@mexbt.com"]
|
@@ -15,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
15
16
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
18
|
spec.require_paths = ["lib"]
|
18
|
-
spec.add_runtime_dependency "activesupport", ["
|
19
|
+
spec.add_runtime_dependency "activesupport", [">= 4.1.8"]
|
19
20
|
spec.add_runtime_dependency "rest_client", ["= 1.8.2"]
|
20
21
|
spec.add_development_dependency "bundler", "~> 1.6"
|
21
22
|
spec.add_development_dependency "rake"
|
data/spec/public_api_spec.rb
CHANGED
@@ -22,4 +22,46 @@ describe Mexbt do
|
|
22
22
|
expect(res["trades"]).to eql([])
|
23
23
|
end
|
24
24
|
|
25
|
+
context "simulating market orders" do
|
26
|
+
|
27
|
+
before do
|
28
|
+
allow(Mexbt).to receive(:order_book) do
|
29
|
+
{
|
30
|
+
"asks" => [{"px" => 1000, "qty" => 0.5}, {"px" => 2000, "qty" => 1}],
|
31
|
+
"bids" => [{"px" => 1000, "qty" => 0.5}, {"px" => 2000, "qty" => 1}]
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "calculates correctly buy orders with second_currency as the target currency" do
|
37
|
+
expect(Mexbt.simulate_market_order(second_currency: 100)["first_amount"]).to eql(0.1)
|
38
|
+
expect(Mexbt.simulate_market_order(second_currency: 500)["first_amount"]).to eql(0.5)
|
39
|
+
expect(Mexbt.simulate_market_order(second_currency: 600)["first_amount"]).to eql(0.55)
|
40
|
+
expect(Mexbt.simulate_market_order(second_currency: 1500)["first_amount"]).to eql(1.0)
|
41
|
+
expect(Mexbt.simulate_market_order(second_currency: 2500)["first_amount"]).to eql(1.5)
|
42
|
+
expect { Mexbt.simulate_market_order(second_currency: 2501)}.to raise_error("Order book does not contain enough orders to satify simulated order!")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "calculates correctly buy orders with first_currency as the target currency" do
|
46
|
+
expect(Mexbt.simulate_market_order(first_currency: 0.5)["second_amount"]).to eql(500.0)
|
47
|
+
expect(Mexbt.simulate_market_order(first_currency: 1.5)["second_amount"]).to eql(2500.0)
|
48
|
+
expect(Mexbt.simulate_market_order(first_currency: 0.1)["second_amount"]).to eql(100.0)
|
49
|
+
expect(Mexbt.simulate_market_order(first_currency: 0.6)["second_amount"]).to eql(700.0)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "calculates correctly sell orders with first_currency as the target currency" do
|
53
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 0.01)["second_amount"]).to eql(20.0)
|
54
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 0.1)["second_amount"]).to eql(200.0)
|
55
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 1)["second_amount"]).to eql(2000.0)
|
56
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 1.1)["second_amount"]).to eql(2100.0)
|
57
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 1.4)["second_amount"]).to eql(2400.0)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "calculates correctly sell orders with second_currency as the target currency" do
|
61
|
+
expect(Mexbt.simulate_market_order(side: :sell, second_currency: 1000)["first_amount"]).to eql(0.5)
|
62
|
+
expect(Mexbt.simulate_market_order(side: :sell, second_currency: 2001)["first_amount"]).to eql(1.001)
|
63
|
+
expect(Mexbt.simulate_market_order(side: :sell, second_currency: 2500)["first_amount"]).to eql(1.5)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
25
67
|
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mexbt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- williamcoates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 4.1.8
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 4.1.8
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -80,7 +80,7 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
description:
|
83
|
+
description: A lightweight ruby client for the meXBT exchange API
|
84
84
|
email:
|
85
85
|
- william@mexbt.com
|
86
86
|
executables: []
|