trade-o-matic 0.2.1 → 0.3.0
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/lib/trade-o-matic/adapters/bitstamp_backend.rb +16 -12
- data/lib/trade-o-matic/adapters/itbit_backend.rb +3 -3
- data/lib/trade-o-matic/adapters/surbtc_backend.rb +7 -7
- data/lib/trade-o-matic/converters/compound_converter.rb +6 -2
- data/lib/trade-o-matic/converters/fixed_converter.rb +14 -1
- data/lib/trade-o-matic/converters/inverse_converter.rb +10 -5
- data/lib/trade-o-matic/converters/json_api_converter.rb +1 -1
- data/lib/trade-o-matic/converters/sync_converter.rb +2 -2
- data/lib/trade-o-matic/standard.rb +13 -0
- data/lib/trade-o-matic/structs/converter.rb +7 -2
- data/lib/trade-o-matic/structs/currency.rb +18 -6
- data/lib/trade-o-matic/structs/price.rb +1 -2
- data/lib/trade-o-matic/support/converter_configurator.rb +2 -2
- data/lib/trade-o-matic/version.rb +1 -1
- data/lib/trade-o-matic.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 69c3f0ffd768200acac1e0ccd836c5daaac08e59
|
|
4
|
+
data.tar.gz: 7e41570aa4c2a894861134cb50a670787384fe40
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3dc8f24f61ba90595a9e5a39dfdd66f753762f3b32fb749e873f299f57ff6156bab77780180811446d5ae576ee1a45fc8e1f2efec4e9d9660c3b96ec5f0687e4
|
|
7
|
+
data.tar.gz: 470ce3b882cd7f45fee5330ccbd258c382e494be8836bf5392c70aaf0736f965de6f0741877ae820748002d55bb80ca5ab580944df440aa9f742d38a11e75d0d
|
|
@@ -21,8 +21,8 @@ module Trader
|
|
|
21
21
|
class BitstampOrder < RawAccountOrder
|
|
22
22
|
attr_mapped(:id, 'raw') # use original order information as id
|
|
23
23
|
attr_mapped(:pair) { |r| MAIN_MARKET }
|
|
24
|
-
attr_mapped(:price) { |r| r['raw']['price']
|
|
25
|
-
attr_mapped(:volume) { |r| r['raw']['amount']
|
|
24
|
+
attr_mapped(:price) { |r| r['raw']['price'] }
|
|
25
|
+
attr_mapped(:volume) { |r| r['raw']['amount'] }
|
|
26
26
|
attr_mapped(:executed_volume)
|
|
27
27
|
attr_mapped(:instruction) { |r| r['raw']['type'] == 0 ? Order::BID : Order::ASK }
|
|
28
28
|
|
|
@@ -31,7 +31,7 @@ module Trader
|
|
|
31
31
|
when 'Open'
|
|
32
32
|
AccountOrder::OPEN
|
|
33
33
|
when 'Finished'
|
|
34
|
-
r['executed_volume'] < r['raw']['amount']
|
|
34
|
+
r['executed_volume'] < big(r['raw']['amount']) ? AccountOrder::CANCELED : AccountOrder::CLOSED
|
|
35
35
|
else
|
|
36
36
|
AccountOrder::PENDING
|
|
37
37
|
end
|
|
@@ -56,12 +56,12 @@ module Trader
|
|
|
56
56
|
_book.prepare Time.now
|
|
57
57
|
|
|
58
58
|
ob = execute_request(nil, 'order_book')
|
|
59
|
-
ob['bids'].each { |o| _book.add_bid(o[0]
|
|
60
|
-
ob['asks'].each { |o| _book.add_ask(o[0]
|
|
59
|
+
ob['bids'].each { |o| _book.add_bid(o[0], o[1]) }
|
|
60
|
+
ob['asks'].each { |o| _book.add_ask(o[0], o[1]) }
|
|
61
61
|
|
|
62
62
|
tx = execute_request(nil, 'transactions')
|
|
63
63
|
tx.each do |t|
|
|
64
|
-
_book.add_transaction t['price']
|
|
64
|
+
_book.add_transaction t['price'], t['amount'], Time.at(t['date'].to_i)
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
|
|
@@ -75,9 +75,9 @@ module Trader
|
|
|
75
75
|
raw = execute_request(_session || session, 'balance')
|
|
76
76
|
|
|
77
77
|
if _currency == BASE_CUR
|
|
78
|
-
return BackendBalance.new raw['btc_balance']
|
|
78
|
+
return BackendBalance.new raw['btc_balance'], raw['btc_available']
|
|
79
79
|
else
|
|
80
|
-
return BackendBalance.new raw['usd_balance']
|
|
80
|
+
return BackendBalance.new raw['usd_balance'], raw['usd_available']
|
|
81
81
|
end
|
|
82
82
|
end
|
|
83
83
|
|
|
@@ -95,7 +95,7 @@ module Trader
|
|
|
95
95
|
normalize_raw_order execute_request(
|
|
96
96
|
_session || session,
|
|
97
97
|
_type == Order::BID ? 'buy' : 'sell',
|
|
98
|
-
{ amount: _volume, price: _price }
|
|
98
|
+
{ amount: _volume.to_f, price: _price.to_f }
|
|
99
99
|
)
|
|
100
100
|
end
|
|
101
101
|
|
|
@@ -146,14 +146,14 @@ module Trader
|
|
|
146
146
|
def normalize_raw_order(_order)
|
|
147
147
|
BitstampOrder.new({
|
|
148
148
|
'raw' => _order,
|
|
149
|
-
'executed_volume' => 0
|
|
149
|
+
'executed_volume' => big(0),
|
|
150
150
|
'status' => 'In Queue'
|
|
151
151
|
})
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
def normalize_raw_order_status(_id, _status)
|
|
155
|
-
executed_volume = _status['transactions'].inject(0
|
|
156
|
-
executed_price = _status['transactions'].inject(0
|
|
155
|
+
executed_volume = _status['transactions'].inject(big(0)) { |r, t| r + big(t['btc']) }
|
|
156
|
+
executed_price = _status['transactions'].inject(big(0)) { |r, t| r + (big(t['price']) * big(t['btc'])) }
|
|
157
157
|
|
|
158
158
|
BitstampOrder.new({
|
|
159
159
|
'raw' => _id,
|
|
@@ -162,5 +162,9 @@ module Trader
|
|
|
162
162
|
'status' => _status['status']
|
|
163
163
|
})
|
|
164
164
|
end
|
|
165
|
+
|
|
166
|
+
def big(_string)
|
|
167
|
+
BigDecimal.new _string
|
|
168
|
+
end
|
|
165
169
|
end
|
|
166
170
|
end
|
|
@@ -10,12 +10,12 @@ module Trader
|
|
|
10
10
|
_book.prepare Time.now
|
|
11
11
|
|
|
12
12
|
ob = fetch_raw_order_book _book.pair
|
|
13
|
-
ob['bids'].each { |o| _book.add_bid(o[0]
|
|
14
|
-
ob['asks'].each { |o| _book.add_ask(o[0]
|
|
13
|
+
ob['bids'].each { |o| _book.add_bid(o[0], o[1]) }
|
|
14
|
+
ob['asks'].each { |o| _book.add_ask(o[0], o[1]) }
|
|
15
15
|
|
|
16
16
|
tx = fetch_raw_transactions _book.pair
|
|
17
17
|
tx['recentTrades'].each do |t|
|
|
18
|
-
_book.add_transaction t['price']
|
|
18
|
+
_book.add_transaction t['price'], t['amount'], Time.parse(t['timestamp'])
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -28,16 +28,16 @@ module Trader
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
class SurbtcBalanceBTC < RawBalance
|
|
31
|
-
attr_mapped(:amount) { |r| r['amount']
|
|
32
|
-
attr_mapped(:available_amount) { |r| r['available_amount']
|
|
31
|
+
attr_mapped(:amount) { |r| r['amount'] }
|
|
32
|
+
attr_mapped(:available_amount) { |r| r['available_amount'] }
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
class SurbtcOrder < RawAccountOrder
|
|
36
36
|
attr_mapped(:id)
|
|
37
37
|
attr_mapped(:pair) { |r| MAIN_MARKET }
|
|
38
38
|
attr_mapped(:price) { |r| r['limit'] }
|
|
39
|
-
attr_mapped(:volume) { |r| r['original_amount']
|
|
40
|
-
attr_mapped(:executed_volume) { |r| r['total_exchanged']
|
|
39
|
+
attr_mapped(:volume) { |r| r['original_amount'] }
|
|
40
|
+
attr_mapped(:executed_volume) { |r| r['total_exchanged'] }
|
|
41
41
|
attr_mapped(:instruction) { |r| TYPE_MAP[r['type'].downcase] }
|
|
42
42
|
attr_mapped(:status) { |r| STATUS_MAP[r['state']] }
|
|
43
43
|
attr_mapped(:limit?) { |r| r['price_type'] == 'limit' }
|
|
@@ -132,14 +132,14 @@ module Trader
|
|
|
132
132
|
def build_order_json(_price, _volume, _instruction)
|
|
133
133
|
if _price.nil?
|
|
134
134
|
{
|
|
135
|
-
amount: _volume,
|
|
135
|
+
amount: _volume.to_i,
|
|
136
136
|
type: _instruction == Order::BID ? 'bid' : 'ask',
|
|
137
137
|
price_type: 'market'
|
|
138
138
|
}
|
|
139
139
|
else
|
|
140
140
|
{
|
|
141
|
-
limit: _price,
|
|
142
|
-
amount: _volume,
|
|
141
|
+
limit: _price.to_i,
|
|
142
|
+
amount: _volume.to_i,
|
|
143
143
|
type: _instruction == Order::BID ? 'bid' : 'ask',
|
|
144
144
|
price_type: 'limit'
|
|
145
145
|
}
|
|
@@ -6,8 +6,12 @@ module Trader
|
|
|
6
6
|
@converters = _converters
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def
|
|
10
|
-
|
|
9
|
+
def apply(_value, _invert=false)
|
|
10
|
+
unless _invert
|
|
11
|
+
converters.inject(_value) { |r, c| c.apply(r, false) }
|
|
12
|
+
else
|
|
13
|
+
converters.reverse.inject(_value) { |r, c| c.apply(r, true) }
|
|
14
|
+
end
|
|
11
15
|
end
|
|
12
16
|
end
|
|
13
17
|
end
|
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
module Trader
|
|
2
2
|
class FixedConverter < Converter
|
|
3
|
-
|
|
3
|
+
attr_reader :rate
|
|
4
4
|
|
|
5
5
|
def initialize(_rate)
|
|
6
6
|
@rate = _rate
|
|
7
|
+
# TODO: maybe require rate to be a Standard.amount
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def current_rate
|
|
11
|
+
rate
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def apply(_value, _invert=false)
|
|
15
|
+
if _invert
|
|
16
|
+
_value / rate
|
|
17
|
+
else
|
|
18
|
+
_value * rate
|
|
19
|
+
end
|
|
7
20
|
end
|
|
8
21
|
end
|
|
9
22
|
end
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
module Trader
|
|
2
2
|
class InverseConverter < Converter
|
|
3
|
-
attr_reader :
|
|
3
|
+
attr_reader :other
|
|
4
4
|
|
|
5
|
-
def initialize(
|
|
6
|
-
@
|
|
5
|
+
def initialize(_other)
|
|
6
|
+
@other = _other
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
def
|
|
10
|
-
|
|
9
|
+
def current_rate
|
|
10
|
+
return nil if other.current_rate.nil?
|
|
11
|
+
1.0 / other.current_rate
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def apply(_value, _invert=false)
|
|
15
|
+
@other.apply(_value, !_invert)
|
|
11
16
|
end
|
|
12
17
|
end
|
|
13
18
|
end
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
module Trader
|
|
2
|
-
class SyncConverter <
|
|
2
|
+
class SyncConverter < FixedConverter
|
|
3
3
|
attr_reader :ttl
|
|
4
4
|
|
|
5
5
|
def initialize(_ttl, &_block)
|
|
6
|
+
super nil
|
|
6
7
|
@ttl = _ttl
|
|
7
8
|
@block = _block
|
|
8
9
|
end
|
|
@@ -16,7 +17,6 @@ module Trader
|
|
|
16
17
|
@rate = @block.call
|
|
17
18
|
@last_sync = Time.now
|
|
18
19
|
end
|
|
19
|
-
|
|
20
20
|
@rate
|
|
21
21
|
end
|
|
22
22
|
end
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
module Trader
|
|
2
2
|
class Converter
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
|
|
4
|
+
def current_rate
|
|
5
|
+
nil # current rate not available
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def apply(_value, _invert=false)
|
|
9
|
+
raise NotImplementedError, 'apply method not implemented'
|
|
5
10
|
end
|
|
6
11
|
end
|
|
7
12
|
end
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
module Trader
|
|
2
2
|
class Currency
|
|
3
|
-
def self.register_conversion(_from, _to, _converter=nil, &_block)
|
|
3
|
+
def self.register_conversion(_from, _to, _converter=nil, _options={}, &_block)
|
|
4
4
|
if !_block.nil?
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
_options = _converter || {}
|
|
6
|
+
_converter = SyncConverter.new(_options.fetch(:interval, 60.0), &_block)
|
|
7
|
+
elsif _converter.is_a? Numeric
|
|
7
8
|
_converter = FixedConverter.new(_converter)
|
|
8
9
|
end
|
|
9
10
|
|
|
11
|
+
_converter = inverse(_converter) if _options[:inverse]
|
|
12
|
+
|
|
10
13
|
converters[_from.to_sym][_to.to_sym] = _converter
|
|
11
14
|
reset_comp_cache
|
|
12
15
|
end
|
|
@@ -78,7 +81,8 @@ module Trader
|
|
|
78
81
|
end
|
|
79
82
|
|
|
80
83
|
def convert(_value, _to)
|
|
81
|
-
klass.converter_for!(code, _to.to_sym)
|
|
84
|
+
converter = klass.converter_for!(code, _to.to_sym)
|
|
85
|
+
converter.apply _value
|
|
82
86
|
end
|
|
83
87
|
|
|
84
88
|
def pack(_value)
|
|
@@ -100,11 +104,11 @@ module Trader
|
|
|
100
104
|
_value.amount
|
|
101
105
|
end
|
|
102
106
|
elsif _value.nil?
|
|
103
|
-
_options[:default]
|
|
107
|
+
Standard.amount _options[:default]
|
|
104
108
|
elsif _options.fetch(:strict, true)
|
|
105
109
|
raise ArgumentError, "Must provide a currency bound price"
|
|
106
110
|
else
|
|
107
|
-
_value
|
|
111
|
+
Standard.amount _value
|
|
108
112
|
end
|
|
109
113
|
end
|
|
110
114
|
|
|
@@ -161,6 +165,14 @@ module Trader
|
|
|
161
165
|
end)
|
|
162
166
|
end
|
|
163
167
|
|
|
168
|
+
def self.inverse(_converter)
|
|
169
|
+
if _converter.is_a? InverseConverter
|
|
170
|
+
_converter.other
|
|
171
|
+
else
|
|
172
|
+
InverseConverter.new _converter
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
164
176
|
def klass
|
|
165
177
|
self.class
|
|
166
178
|
end
|
|
@@ -4,7 +4,7 @@ module Trader
|
|
|
4
4
|
|
|
5
5
|
def initialize(_currency, _amount)
|
|
6
6
|
@currency = Currency.for_code _currency
|
|
7
|
-
@amount = _amount
|
|
7
|
+
@amount = Standard.amount _amount
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def pack(_amount)
|
|
@@ -37,6 +37,5 @@ module Trader
|
|
|
37
37
|
Price.new currency, amount.public_send(op, _other)
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
|
-
|
|
41
40
|
end
|
|
42
41
|
end
|
|
@@ -7,8 +7,8 @@ module Trader
|
|
|
7
7
|
type = conv['type'] || detect_type(conv)
|
|
8
8
|
converter = send "configure_yaml_#{type}", conv
|
|
9
9
|
|
|
10
|
-
Currency.register_conversion conv['from'], conv['to'], converter
|
|
11
|
-
Currency.register_conversion conv['to'], conv['from'],
|
|
10
|
+
Currency.register_conversion conv['from'], conv['to'], converter, inverse: !!conv['inverse']
|
|
11
|
+
Currency.register_conversion conv['to'], conv['from'], converter, inverse: !conv['inverse'] if conv['symetric']
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
data/lib/trade-o-matic.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: trade-o-matic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ignacio Baixas
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-03-
|
|
11
|
+
date: 2016-03-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rest-client
|
|
@@ -257,6 +257,7 @@ files:
|
|
|
257
257
|
- lib/trade-o-matic/core/market.rb
|
|
258
258
|
- lib/trade-o-matic/core/market_loader.rb
|
|
259
259
|
- lib/trade-o-matic/services/backend_factory.rb
|
|
260
|
+
- lib/trade-o-matic/standard.rb
|
|
260
261
|
- lib/trade-o-matic/structs/ask_slope.rb
|
|
261
262
|
- lib/trade-o-matic/structs/bid_slope.rb
|
|
262
263
|
- lib/trade-o-matic/structs/book.rb
|