mexbt 0.0.5 → 0.0.6
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/CHANGELOG.md +5 -0
- data/Gemfile.lock +5 -5
- data/README.md +57 -27
- data/lib/mexbt/account.rb +67 -3
- data/lib/mexbt/client.rb +16 -4
- data/lib/mexbt/version.rb +1 -1
- data/lib/mexbt.rb +2 -8
- data/spec/private_api_spec.rb +68 -62
- data/spec/public_api_spec.rb +28 -28
- metadata +3 -4
- data/lib/mexbt/orders.rb +0 -53
- data/lib/mexbt/private.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cc4cf3db2a64b534ef332ab4838e09ed1b8be033
|
4
|
+
data.tar.gz: 30035ad68d18845431c9341c32b202f66dae5fe6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b56b257027bcddb33b227df3a2be160235d970a37560744516a3eae29e494ac3abaa9678d47ad8be60f511da715936d2cdfca2c5d7797b437077d188a51a3eaa
|
7
|
+
data.tar.gz: 9f88151bbb4e0e432c0051886daf2cc82397c91a02dde0cacd0973bde0eb60bebcb734d916ca360344c88d7ee5b6fd278fe147d395adf3ab6c48ce901fe6b8b0
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
mexbt (0.0.
|
4
|
+
mexbt (0.0.6)
|
5
5
|
activesupport (>= 4.1.8)
|
6
6
|
rest_client (= 1.8.2)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: http://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activesupport (4.
|
12
|
-
i18n (~> 0.
|
11
|
+
activesupport (4.2.0)
|
12
|
+
i18n (~> 0.7)
|
13
13
|
json (~> 1.7, >= 1.7.7)
|
14
14
|
minitest (~> 5.1)
|
15
|
-
thread_safe (~> 0.
|
15
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
16
16
|
tzinfo (~> 1.1)
|
17
17
|
diff-lcs (1.2.5)
|
18
|
-
i18n (0.
|
18
|
+
i18n (0.7.0)
|
19
19
|
json (1.8.1)
|
20
20
|
minitest (5.5.0)
|
21
21
|
netrc (0.7.9)
|
data/README.md
CHANGED
@@ -19,50 +19,81 @@ You need to be using Ruby 2.1 or higher.
|
|
19
19
|
|
20
20
|
You can access all the Public API functions with zero configuration. By default they will use the 'BTCMXN' currency pair.
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
```ruby
|
23
|
+
Mexbt.ticker
|
24
|
+
Mexbt.order_book
|
25
|
+
Mexbt.trades(start_index: -1, count: 20)
|
26
|
+
Mexbt.trades_by_date(from: Date.civil(2014, 11, 1).to_time.to_i, to: Date.today.to_time.to_i)
|
27
|
+
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
|
28
|
+
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
|
29
|
+
```
|
28
30
|
|
29
31
|
If you want to choose another currency pair, you can configure it for all calls:
|
30
32
|
|
31
|
-
|
33
|
+
```ruby
|
34
|
+
Mexbt.configure { |c| c.currency_pair: 'BTCUSD' }
|
35
|
+
```
|
32
36
|
|
33
37
|
Or alternatively you can set it per call:
|
34
38
|
|
35
|
-
|
39
|
+
```ruby
|
40
|
+
Mexbt.ticker(currency_pair: 'BTCUSD')
|
41
|
+
```
|
36
42
|
|
37
43
|
## Private API
|
38
44
|
|
39
|
-
|
40
|
-
### Configuration
|
45
|
+
### API Keys
|
41
46
|
|
42
47
|
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.
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
49
|
+
### Static configuration
|
50
|
+
|
51
|
+
If you will only be using one account in your application, it's easier to configure statically:
|
52
|
+
|
53
|
+
```ruby
|
54
|
+
Mexbt.configure do |c|
|
55
|
+
mexbt.public_key = "xxx"
|
56
|
+
mexbt.private_key = "yyy"
|
57
|
+
mexbt.user_id = "email@test.com" # Your registered email address
|
58
|
+
mexbt.sandbox = true # Set this to true to use the sandbox
|
59
|
+
end
|
60
|
+
```
|
61
|
+
|
62
|
+
Then to access private functions just instantiate an instance of Mexbt::Account:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
Mexbt::Account.new.info
|
66
|
+
```
|
67
|
+
|
68
|
+
### Per-instance configuration
|
69
|
+
|
70
|
+
If you need to manage multiple meXBT accounts you should configure per each instance of Mexbt::Account:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
account = Mexbt::Account.new(public_key: 'xxx', private_key: 'yyy', user_id: 'email@test.com', sandbox: true)
|
74
|
+
account.balance
|
75
|
+
```
|
50
76
|
|
51
77
|
## Order functions
|
52
78
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
79
|
+
```ruby
|
80
|
+
account.create_order(amount: 0.1, currency_pair: 'btcmxn') # Create a market buy order for 0.1 BTC for Pesos
|
81
|
+
account.create_order(amount: 2, side: :sell, currency_pair: 'btcusd') # Create a market order to sell 2 BTC for USD
|
82
|
+
account.create_order(amount: 2, price: 1, side: :buy, type: :limit, currency_pair: 'ltcmxn') # Create a limit order to buy 2 LTC for 1 peso
|
83
|
+
account.cancel_order(id: 123, currency_pair: 'btcmxn')
|
84
|
+
account.cancel_all_orders() # Cancel all orders for the default currency pair
|
85
|
+
```
|
58
86
|
|
59
87
|
### Account functions
|
60
88
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
89
|
+
```ruby
|
90
|
+
account.balance
|
91
|
+
account.trades
|
92
|
+
account.orders
|
93
|
+
account.deposit_addresses
|
94
|
+
account.withdraw(amount: 1, currency: :btc, address: 'xxx')
|
95
|
+
account.info # Fetches your user info
|
96
|
+
```
|
66
97
|
|
67
98
|
### Sandbox
|
68
99
|
|
@@ -80,7 +111,6 @@ API docs for the Private API are at http://docs.mexbtprivateapi.apiary.io
|
|
80
111
|
|
81
112
|
There are also docs for the Private API sandbox at http://docs.mexbtprivateapisandbox.apiary.io
|
82
113
|
|
83
|
-
|
84
114
|
## TODO
|
85
115
|
|
86
116
|
Mock out web calls with WebMock so that specs don't break everytime sandbox db is cleaned.
|
data/lib/mexbt/account.rb
CHANGED
@@ -1,10 +1,29 @@
|
|
1
|
-
require 'mexbt/private'
|
2
1
|
require 'mexbt/common'
|
3
2
|
|
4
3
|
module Mexbt
|
5
|
-
|
6
|
-
include Mexbt::Private
|
4
|
+
class Account
|
7
5
|
include Mexbt::Common
|
6
|
+
include Mexbt::Client
|
7
|
+
|
8
|
+
def initialize(credentials={})
|
9
|
+
recognized_credentials = [:public_key, :private_key, :user_id, :currency_pair, :sandbox]
|
10
|
+
recognized_credentials.each do |k|
|
11
|
+
credential = credentials[k] || Mexbt.send(k)
|
12
|
+
instance_variable_set(:"@#{k}", credentials[k])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def private?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def sandbox
|
21
|
+
@sandbox || Mexbt.sandbox
|
22
|
+
end
|
23
|
+
|
24
|
+
def endpoint
|
25
|
+
"https://private-api#{sandbox ? '-sandbox' : nil}.mexbt.com"
|
26
|
+
end
|
8
27
|
|
9
28
|
%w{info balance orders deposit_addresses}.each do |m|
|
10
29
|
define_method(m) do
|
@@ -15,5 +34,50 @@ module Mexbt
|
|
15
34
|
def withdraw(amount:, address:, currency: :btc)
|
16
35
|
call("withdraw", { ins: currency, amount: amount, sentToAddress: address })
|
17
36
|
end
|
37
|
+
|
38
|
+
def create_order(amount:, price: nil, currency_pair: Mexbt.currency_pair, side: :buy, type: :market)
|
39
|
+
# Horribly hack because sandbox only accepts 6 decimal places thanks to AP
|
40
|
+
if Mexbt.sandbox
|
41
|
+
amount = BigDecimal.new(amount, 15).round(6).to_f
|
42
|
+
end
|
43
|
+
type =
|
44
|
+
case type
|
45
|
+
when :market, 1
|
46
|
+
1
|
47
|
+
when :limit, 0
|
48
|
+
0
|
49
|
+
else
|
50
|
+
raise "Unknown order type '#{type}'"
|
51
|
+
end
|
52
|
+
params = {
|
53
|
+
ins: currency_pair,
|
54
|
+
side: side,
|
55
|
+
orderType: type,
|
56
|
+
qty: amount
|
57
|
+
}
|
58
|
+
params[:px] = price if price
|
59
|
+
call("orders/create", params)
|
60
|
+
end
|
61
|
+
|
62
|
+
def cancel_order(id:, currency_pair: Mexbt.currency_pair)
|
63
|
+
call("orders/cancel", { ins: currency_pair, serverOrderId: id })
|
64
|
+
end
|
65
|
+
|
66
|
+
def cancel_all_orders(currency_pair: Mexbt.currency_pair)
|
67
|
+
call("orders/cancel-all", { ins: currency_pair } )
|
68
|
+
end
|
69
|
+
|
70
|
+
def modify_order(id:, action:, currency_pair: Mexbt.currency_pair)
|
71
|
+
action =
|
72
|
+
case action
|
73
|
+
when :move_to_top, 0
|
74
|
+
0
|
75
|
+
when :execute_now, 1
|
76
|
+
1
|
77
|
+
else
|
78
|
+
raise "Action must be one of: :move_to_top, :execute_now"
|
79
|
+
end
|
80
|
+
call("orders/modify", { ins: currency_pair, serverOrderId: id, modifyAction: action } )
|
81
|
+
end
|
18
82
|
end
|
19
83
|
end
|
data/lib/mexbt/client.rb
CHANGED
@@ -10,18 +10,30 @@ module Mexbt
|
|
10
10
|
"#{endpoint()}/v1/#{path}"
|
11
11
|
end
|
12
12
|
|
13
|
+
def public_key
|
14
|
+
@public_key || Mexbt.public_key
|
15
|
+
end
|
16
|
+
|
17
|
+
def private_key
|
18
|
+
@private_key || Mexbt.private_key
|
19
|
+
end
|
20
|
+
|
21
|
+
def user_id
|
22
|
+
@user_id || Mexbt.user_id
|
23
|
+
end
|
24
|
+
|
13
25
|
def auth_params
|
14
|
-
if
|
26
|
+
if public_key.nil? || private_key.nil?
|
15
27
|
raise "You must configure your API keys!"
|
16
28
|
end
|
17
|
-
if
|
29
|
+
if user_id.nil?
|
18
30
|
raise "You must configure your user_id!"
|
19
31
|
end
|
20
32
|
nonce = (Time.now.to_f*10000).to_i
|
21
33
|
{
|
22
|
-
apiKey:
|
34
|
+
apiKey: public_key,
|
23
35
|
apiNonce: nonce,
|
24
|
-
apiSig: OpenSSL::HMAC.hexdigest('sha256',
|
36
|
+
apiSig: OpenSSL::HMAC.hexdigest('sha256', private_key, "#{nonce}#{user_id}#{public_key}").upcase
|
25
37
|
}
|
26
38
|
end
|
27
39
|
|
data/lib/mexbt/version.rb
CHANGED
data/lib/mexbt.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
+
require 'active_support'
|
1
2
|
require 'active_support/core_ext'
|
2
3
|
require 'active_support/inflector'
|
3
4
|
require 'mexbt/public'
|
4
5
|
require 'mexbt/account'
|
5
|
-
require 'mexbt/orders'
|
6
6
|
|
7
7
|
module Mexbt
|
8
8
|
mattr_accessor :public_key
|
@@ -19,12 +19,6 @@ module Mexbt
|
|
19
19
|
|
20
20
|
extend Mexbt::Public
|
21
21
|
|
22
|
-
|
23
|
-
extend Mexbt::Account
|
24
|
-
end
|
22
|
+
end
|
25
23
|
|
26
|
-
module Orders
|
27
|
-
extend Mexbt::Orders
|
28
|
-
end
|
29
24
|
|
30
|
-
end
|
data/spec/private_api_spec.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Mexbt::
|
3
|
+
describe Mexbt::Account do
|
4
4
|
|
5
5
|
context "without authentication" do
|
6
6
|
|
7
|
+
subject(:account) { Mexbt::Account.new }
|
8
|
+
|
7
9
|
after do
|
8
10
|
Mexbt.configure do |c|
|
9
11
|
c.public_key = nil
|
@@ -12,7 +14,7 @@ describe Mexbt::Private do
|
|
12
14
|
end
|
13
15
|
|
14
16
|
it "should raise a friendly error if no keys are configured" do
|
15
|
-
expect {
|
17
|
+
expect { account.balance }.to raise_error("You must configure your API keys!")
|
16
18
|
end
|
17
19
|
|
18
20
|
it "should raise a friendly error if no user_id is configured" do
|
@@ -20,17 +22,29 @@ describe Mexbt::Private do
|
|
20
22
|
c.public_key = "foo"
|
21
23
|
c.private_key = "bar"
|
22
24
|
end
|
23
|
-
expect {
|
25
|
+
expect { account.balance }.to raise_error("You must configure your user_id!")
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context "with per-instance authentication" do
|
31
|
+
|
32
|
+
subject(:account) { Mexbt::Account.new(public_key: "fa4ed1ce8040f66b1bf8708aedff3c16", private_key: "09c4aa0a971eb453378768e7d2d4147e", user_id: "test@mexbt.com", sandbox: true) }
|
33
|
+
|
34
|
+
it "still works" do
|
35
|
+
expect(account.info[:isAccepted]).to be true
|
24
36
|
end
|
25
37
|
|
26
38
|
end
|
27
39
|
|
28
40
|
context "with authentication" do
|
29
41
|
|
42
|
+
subject(:account) { Mexbt::Account.new }
|
43
|
+
|
30
44
|
before do
|
31
45
|
Mexbt.configure do |c|
|
32
|
-
c.public_key = "
|
33
|
-
c.private_key = "
|
46
|
+
c.public_key = "fa4ed1ce8040f66b1bf8708aedff3c16"
|
47
|
+
c.private_key = "09c4aa0a971eb453378768e7d2d4147e"
|
34
48
|
c.user_id = "test@mexbt.com"
|
35
49
|
c.sandbox = true
|
36
50
|
end
|
@@ -43,82 +57,74 @@ describe Mexbt::Private do
|
|
43
57
|
end
|
44
58
|
end
|
45
59
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
res = Mexbt::Account.send(f)
|
51
|
-
expect(res["isAccepted"]).to be true
|
52
|
-
end
|
60
|
+
it "gives a valid response to all api functions that require no args" do
|
61
|
+
%w{info balance orders deposit_addresses trades}.each do |f|
|
62
|
+
res = account.send(f)
|
63
|
+
expect(res[:isAccepted]).to be true
|
53
64
|
end
|
54
|
-
|
55
65
|
end
|
56
66
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
expect(res["serverOrderId"]).to be_a(Fixnum)
|
63
|
-
end
|
67
|
+
it "allows creating market orders" do
|
68
|
+
res = account.create_order(amount: 0.1, currency_pair: "BTCUSD")
|
69
|
+
expect(res[:isAccepted]).to be true
|
70
|
+
expect(res[:serverOrderId]).to be_a(Fixnum)
|
71
|
+
end
|
64
72
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
73
|
+
it "allows creating orders with 8 decimal places" do
|
74
|
+
res = account.create_order(amount: 0.12345678, currency_pair: "BTCUSD")
|
75
|
+
expect(res[:isAccepted]).to be true
|
76
|
+
expect(res[:serverOrderId]).to be_a(Fixnum)
|
77
|
+
end
|
70
78
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
79
|
+
it "allows creating limit orders" do
|
80
|
+
res = account.create_order(type: :limit, price: 100, amount: 0.1234, currency_pair: "BTCUSD")
|
81
|
+
expect(res[:isAccepted]).to be true
|
82
|
+
expect(res[:serverOrderId]).to be_a(Fixnum)
|
83
|
+
end
|
76
84
|
|
77
|
-
|
78
|
-
|
79
|
-
|
85
|
+
it "raises an exception if order type not recognised" do
|
86
|
+
expect { account.create_order(type: :boom, amount: 0.2) }.to raise_error("Unknown order type 'boom'")
|
87
|
+
end
|
80
88
|
|
81
|
-
|
89
|
+
context "modifying and cancelling orders" do
|
82
90
|
|
83
|
-
|
91
|
+
let(:order_id) {account.create_order(type: :limit, price: 100, amount: 0.1, currency_pair: "BTCUSD")[:serverOrderId]}
|
84
92
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
93
|
+
it "allows converting limit orders to market orders" do
|
94
|
+
res = account.modify_order(id: order_id, currency_pair: "BTCUSD", action: :execute_now)
|
95
|
+
expect(res[:isAccepted]).to be true
|
96
|
+
end
|
89
97
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
98
|
+
it "allows moving orders to the top of the book" do
|
99
|
+
res = account.modify_order(id: order_id, currency_pair: "BTCUSD", action: :move_to_top)
|
100
|
+
expect(res[:isAccepted]).to be true
|
101
|
+
end
|
94
102
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
end
|
103
|
+
it "allows cancelling individual orders" do
|
104
|
+
res = account.cancel_order(id: order_id, currency_pair: "BTCUSD")
|
105
|
+
expect(res[:isAccepted]).to be true
|
106
|
+
orders = account.orders[:openOrdersInfo]
|
107
|
+
orders.each do |open_orders|
|
108
|
+
if open_orders[:ins] === "BTCUSD"
|
109
|
+
open_orders[:openOrders].each do |usd_order|
|
110
|
+
if usd_order[:ServerOrderId] === order_id
|
111
|
+
fail("Order was cancelled but still open")
|
105
112
|
end
|
106
113
|
end
|
107
114
|
end
|
108
115
|
end
|
116
|
+
end
|
109
117
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
end
|
118
|
+
it "allows cancelling all orders" do
|
119
|
+
res = account.cancel_all_orders(currency_pair: "BTCUSD")
|
120
|
+
expect(res[:isAccepted]).to be true
|
121
|
+
orders = account.orders[:openOrdersInfo]
|
122
|
+
orders.each do |open_orders|
|
123
|
+
if open_orders[:ins] === "BTCUSD"
|
124
|
+
expect(open_orders[:openOrders]).to eql([])
|
118
125
|
end
|
119
126
|
end
|
120
127
|
end
|
121
|
-
|
122
128
|
end
|
123
129
|
|
124
130
|
end
|
data/spec/public_api_spec.rb
CHANGED
@@ -5,35 +5,35 @@ describe Mexbt do
|
|
5
5
|
it "gives a valid response to all public api functions that require no args" do
|
6
6
|
%w{ticker trades currency_pairs product_pairs orders order_book}.each do |f|
|
7
7
|
res = Mexbt.send(f)
|
8
|
-
expect(res[
|
8
|
+
expect(res[:isAccepted]).to be true
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
it "allows passing a custom currency pair to functions that accept it" do
|
13
13
|
%w{ticker trades orders order_book}.each do |f|
|
14
14
|
res = Mexbt.send(f, currency_pair: 'BTCUSD')
|
15
|
-
expect(res[
|
15
|
+
expect(res[:isAccepted]).to be true
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
it "allows you to fetch trades by date range" do
|
20
20
|
res = Mexbt.trades_by_date(from: Time.now.to_i, to: Time.now.to_i)
|
21
|
-
expect(res[
|
22
|
-
expect(res[
|
21
|
+
expect(res[:isAccepted]).to be true
|
22
|
+
expect(res[:trades]).to eql([])
|
23
23
|
end
|
24
24
|
|
25
25
|
it "fetches btcmxn order book data from data API if AP API down" do
|
26
|
-
expect(Mexbt).to receive(:call).with("order-book", { productPair: :btcmxn }).and_raise(
|
26
|
+
expect(Mexbt).to receive(:call).with("order-book", { productPair: :btcmxn }).and_raise(RestClient::RequestFailed)
|
27
27
|
order_book = Mexbt.order_book
|
28
|
-
expect(order_book[
|
29
|
-
expect(order_book[
|
30
|
-
expect(order_book[
|
31
|
-
expect(order_book[
|
28
|
+
expect(order_book[:asks].first[:px]).to be_a_kind_of(Numeric)
|
29
|
+
expect(order_book[:asks].first[:qty]).to be_a_kind_of(Numeric)
|
30
|
+
expect(order_book[:bids].first[:px]).to be_a_kind_of(Numeric)
|
31
|
+
expect(order_book[:bids].first[:qty]).to be_a_kind_of(Numeric)
|
32
32
|
end
|
33
33
|
|
34
34
|
it "simulates market order using data api data if AP API down" do
|
35
|
-
expect(Mexbt).to receive(:call).with("order-book", { productPair: :btcmxn }).and_raise(
|
36
|
-
expect(Mexbt.simulate_market_order(second_currency: 100)[
|
35
|
+
expect(Mexbt).to receive(:call).with("order-book", { productPair: :btcmxn }).and_raise(RestClient::RequestFailed)
|
36
|
+
expect(Mexbt.simulate_market_order(second_currency: 100)[:first_amount]).to be_a_kind_of(Numeric)
|
37
37
|
end
|
38
38
|
|
39
39
|
context "simulating market orders" do
|
@@ -48,33 +48,33 @@ describe Mexbt do
|
|
48
48
|
end
|
49
49
|
|
50
50
|
it "calculates correctly buy orders with second_currency as the target currency" do
|
51
|
-
expect(Mexbt.simulate_market_order(second_currency: 100)[
|
52
|
-
expect(Mexbt.simulate_market_order(second_currency: 500)[
|
53
|
-
expect(Mexbt.simulate_market_order(second_currency: 600)[
|
54
|
-
expect(Mexbt.simulate_market_order(second_currency: 1500)[
|
55
|
-
expect(Mexbt.simulate_market_order(second_currency: 2500)[
|
51
|
+
expect(Mexbt.simulate_market_order(second_currency: 100)[:first_amount]).to eql(0.1)
|
52
|
+
expect(Mexbt.simulate_market_order(second_currency: 500)[:first_amount]).to eql(0.5)
|
53
|
+
expect(Mexbt.simulate_market_order(second_currency: 600)[:first_amount]).to eql(0.55)
|
54
|
+
expect(Mexbt.simulate_market_order(second_currency: 1500)[:first_amount]).to eql(1.0)
|
55
|
+
expect(Mexbt.simulate_market_order(second_currency: 2500)[:first_amount]).to eql(1.5)
|
56
56
|
expect { Mexbt.simulate_market_order(second_currency: 2501)}.to raise_error("Order book does not contain enough orders to satify simulated order!")
|
57
57
|
end
|
58
58
|
|
59
59
|
it "calculates correctly buy orders with first_currency as the target currency" do
|
60
|
-
expect(Mexbt.simulate_market_order(first_currency: 0.5)[
|
61
|
-
expect(Mexbt.simulate_market_order(first_currency: 1.5)[
|
62
|
-
expect(Mexbt.simulate_market_order(first_currency: 0.1)[
|
63
|
-
expect(Mexbt.simulate_market_order(first_currency: 0.6)[
|
60
|
+
expect(Mexbt.simulate_market_order(first_currency: 0.5)[:second_amount]).to eql(500.0)
|
61
|
+
expect(Mexbt.simulate_market_order(first_currency: 1.5)[:second_amount]).to eql(2500.0)
|
62
|
+
expect(Mexbt.simulate_market_order(first_currency: 0.1)[:second_amount]).to eql(100.0)
|
63
|
+
expect(Mexbt.simulate_market_order(first_currency: 0.6)[:second_amount]).to eql(700.0)
|
64
64
|
end
|
65
65
|
|
66
66
|
it "calculates correctly sell orders with first_currency as the target currency" do
|
67
|
-
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 0.01)[
|
68
|
-
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 0.1)[
|
69
|
-
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 1)[
|
70
|
-
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 1.1)[
|
71
|
-
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 1.4)[
|
67
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 0.01)[:second_amount]).to eql(20.0)
|
68
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 0.1)[:second_amount]).to eql(200.0)
|
69
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 1)[:second_amount]).to eql(2000.0)
|
70
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 1.1)[:second_amount]).to eql(2100.0)
|
71
|
+
expect(Mexbt.simulate_market_order(side: :sell, first_currency: 1.4)[:second_amount]).to eql(2400.0)
|
72
72
|
end
|
73
73
|
|
74
74
|
it "calculates correctly sell orders with second_currency as the target currency" do
|
75
|
-
expect(Mexbt.simulate_market_order(side: :sell, second_currency: 1000)[
|
76
|
-
expect(Mexbt.simulate_market_order(side: :sell, second_currency: 2001)[
|
77
|
-
expect(Mexbt.simulate_market_order(side: :sell, second_currency: 2500)[
|
75
|
+
expect(Mexbt.simulate_market_order(side: :sell, second_currency: 1000)[:first_amount]).to eql(0.5)
|
76
|
+
expect(Mexbt.simulate_market_order(side: :sell, second_currency: 2001)[:first_amount]).to eql(1.001)
|
77
|
+
expect(Mexbt.simulate_market_order(side: :sell, second_currency: 2500)[:first_amount]).to eql(1.5)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- williamcoates
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -89,6 +89,7 @@ extra_rdoc_files: []
|
|
89
89
|
files:
|
90
90
|
- ".gitignore"
|
91
91
|
- ".rspec"
|
92
|
+
- CHANGELOG.md
|
92
93
|
- Gemfile
|
93
94
|
- Gemfile.lock
|
94
95
|
- LICENSE.txt
|
@@ -98,8 +99,6 @@ files:
|
|
98
99
|
- lib/mexbt/account.rb
|
99
100
|
- lib/mexbt/client.rb
|
100
101
|
- lib/mexbt/common.rb
|
101
|
-
- lib/mexbt/orders.rb
|
102
|
-
- lib/mexbt/private.rb
|
103
102
|
- lib/mexbt/public.rb
|
104
103
|
- lib/mexbt/version.rb
|
105
104
|
- mexbt.gemspec
|
data/lib/mexbt/orders.rb
DELETED
@@ -1,53 +0,0 @@
|
|
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
|
-
# Horribly hack because sandbox only accepts 6 decimal places thanks to AP
|
9
|
-
if Mexbt.sandbox
|
10
|
-
amount = BigDecimal.new(amount, 15).round(6).to_f
|
11
|
-
end
|
12
|
-
type =
|
13
|
-
case type
|
14
|
-
when :market, 1
|
15
|
-
1
|
16
|
-
when :limit, 0
|
17
|
-
0
|
18
|
-
else
|
19
|
-
raise "Unknown order type '#{type}'"
|
20
|
-
end
|
21
|
-
params = {
|
22
|
-
ins: currency_pair,
|
23
|
-
side: side,
|
24
|
-
orderType: type,
|
25
|
-
qty: amount
|
26
|
-
}
|
27
|
-
params[:px] = price if price
|
28
|
-
call("orders/create", params)
|
29
|
-
end
|
30
|
-
|
31
|
-
def cancel(id:, currency_pair: Mexbt.currency_pair)
|
32
|
-
call("orders/cancel", { ins: currency_pair, serverOrderId: id })
|
33
|
-
end
|
34
|
-
|
35
|
-
def cancel_all(currency_pair: Mexbt.currency_pair)
|
36
|
-
call("orders/cancel-all", { ins: currency_pair } )
|
37
|
-
end
|
38
|
-
|
39
|
-
def modify(id:, action:, currency_pair: Mexbt.currency_pair)
|
40
|
-
action =
|
41
|
-
case action
|
42
|
-
when :move_to_top, 0
|
43
|
-
0
|
44
|
-
when :execute_now, 1
|
45
|
-
1
|
46
|
-
else
|
47
|
-
raise "Action must be one of: :move_to_top, :execute_now"
|
48
|
-
end
|
49
|
-
call("orders/modify", { ins: currency_pair, serverOrderId: id, modifyAction: action } )
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
end
|
data/lib/mexbt/private.rb
DELETED