vexapion 0.3.1 → 0.4.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/vexapion/base_exchanges.rb +16 -29
- data/lib/vexapion/bitflyer.rb +11 -4
- data/lib/vexapion/coincheck.rb +9 -1
- data/lib/vexapion/connect/http_client.rb +58 -93
- data/lib/vexapion/errors/http_errors.rb +3 -41
- data/lib/vexapion/errors/vexapion_errors.rb +10 -13
- data/lib/vexapion/poloniex.rb +9 -1
- data/lib/vexapion/template.rb +3 -0
- data/lib/vexapion/version.rb +1 -1
- data/lib/vexapion/zaif.rb +9 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97edc5835e99e3259f41a7c369d4ec44c4810b63
|
4
|
+
data.tar.gz: 2035a6f3a8abc9cf5648d238a3394c6f1fec7991
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4455d9ade97335a2b9ea1c634311c586dabc6366e7913227731705fec52db37256c24972d72c59dff6cfa74b1be25f9da2a2d909ed3ed80f8147efc1b97f06ce
|
7
|
+
data.tar.gz: 27371b2d387fe28501bd5c6a75b36f40a0e370fb8c084b8fcba4fe82fe90315af1b740a48116ae1ea3dd1275a5cb975f427168f6771ab0da360725d0ead08b75
|
@@ -5,7 +5,7 @@ module Vexapion
|
|
5
5
|
# Virtual (crypto) Currency Exchanges API wrapper class
|
6
6
|
|
7
7
|
class BaseExchanges
|
8
|
-
|
8
|
+
# :stopdoc:
|
9
9
|
def initialize(key = nil, secret = nil)
|
10
10
|
@key = key
|
11
11
|
@secret = secret
|
@@ -16,6 +16,11 @@ module Vexapion
|
|
16
16
|
set_min_interval(0.5)
|
17
17
|
end
|
18
18
|
|
19
|
+
def disconnect
|
20
|
+
@conn.terminate
|
21
|
+
end
|
22
|
+
# :startdoc:
|
23
|
+
|
19
24
|
def set_min_interval(sec)
|
20
25
|
@conn.min_interval = sec
|
21
26
|
end
|
@@ -24,42 +29,24 @@ module Vexapion
|
|
24
29
|
@verify_mode = mode
|
25
30
|
end
|
26
31
|
|
32
|
+
# :stopdoc:
|
27
33
|
def do_command(uri, request)
|
28
|
-
response = nil
|
29
|
-
begin
|
34
|
+
#response = nil
|
35
|
+
#begin
|
30
36
|
response = @conn.http_request(uri, request, @verify_mode)
|
31
|
-
rescue VexapionRuntimeError => e
|
32
|
-
|
33
|
-
rescue HTTPError => e
|
34
|
-
|
35
|
-
end
|
37
|
+
#rescue VexapionRuntimeError => e
|
38
|
+
# raise e
|
39
|
+
#rescue HTTPError => e
|
40
|
+
# raise e
|
41
|
+
#end
|
36
42
|
|
37
43
|
response == '' ? '' : JSON.parse(response)
|
38
44
|
end
|
39
|
-
|
45
|
+
|
40
46
|
def get_nonce
|
41
47
|
@nonce += 1
|
42
48
|
end
|
43
|
-
|
44
|
-
def error_check(res)
|
45
|
-
if res != nil && res != '' && res.kind_of?(Hash)
|
46
|
-
|
47
|
-
if res['success'] == 0 || res['success'] == 'false'
|
48
|
-
#polo
|
49
|
-
fail RequestFailed.new(
|
50
|
-
false, false, res)
|
51
|
-
elsif res.has_key?('error')
|
52
|
-
#zaif, polo
|
53
|
-
fail RequestFailed.new(
|
54
|
-
false, res['error'], res)
|
55
|
-
elsif res.has_key?('error_message')
|
56
|
-
#bitflyer
|
57
|
-
fail RequestFailed.new(
|
58
|
-
false, "#{res['status']} #{res['error_message']}", res)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
49
|
+
# :startdoc:
|
63
50
|
|
64
51
|
end #of class
|
65
52
|
|
data/lib/vexapion/bitflyer.rb
CHANGED
@@ -9,7 +9,7 @@ module Vexapion
|
|
9
9
|
# @see https://lightning.bitflyer.jp/docs?lang=ja&_ga=1.264432847.170149243.1463313992
|
10
10
|
|
11
11
|
class Bitflyer < BaseExchanges
|
12
|
-
|
12
|
+
# :stopdoc:
|
13
13
|
def initialize(key = nil, secret = nil)
|
14
14
|
super(key, secret)
|
15
15
|
|
@@ -20,6 +20,7 @@ module Vexapion
|
|
20
20
|
|
21
21
|
@available_pair = ['BTC_JPY', 'FX_BTC_JPY', 'ETH_BTC']
|
22
22
|
end
|
23
|
+
# :startdoc:
|
23
24
|
|
24
25
|
# Public API
|
25
26
|
#板情報
|
@@ -460,7 +461,7 @@ module Vexapion
|
|
460
461
|
'ACCESS-SIGN' => sign
|
461
462
|
}
|
462
463
|
|
463
|
-
request = Net::HTTP::Get.new(uri.request_uri,
|
464
|
+
request = Net::HTTP::Get.new(uri.request_uri, header)
|
464
465
|
|
465
466
|
do_command(uri, request)
|
466
467
|
end
|
@@ -474,7 +475,7 @@ module Vexapion
|
|
474
475
|
text = "#{timestamp}#{method}#{uri.request_uri}#{body}"
|
475
476
|
sign = signature(text)
|
476
477
|
header = headers(sign, timestamp)
|
477
|
-
request = Net::HTTP::Post.new(uri.request_uri,
|
478
|
+
request = Net::HTTP::Post.new(uri.request_uri, header)
|
478
479
|
request.body = body
|
479
480
|
|
480
481
|
res = do_command(uri, request)
|
@@ -488,7 +489,7 @@ module Vexapion
|
|
488
489
|
end
|
489
490
|
|
490
491
|
def headers(sign, timestamp)
|
491
|
-
|
492
|
+
{
|
492
493
|
'ACCESS-KEY' => @key,
|
493
494
|
'ACCESS-TIMESTAMP' => timestamp,
|
494
495
|
'ACCESS-SIGN' => sign,
|
@@ -496,5 +497,11 @@ module Vexapion
|
|
496
497
|
}
|
497
498
|
end
|
498
499
|
|
500
|
+
def error_check(res)
|
501
|
+
if !res.nil? && res['success'] == 0 && res.has_key?('error')
|
502
|
+
fail Warning.new(0, res['error'])
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
499
506
|
end #of class
|
500
507
|
end #of module
|
data/lib/vexapion/coincheck.rb
CHANGED
@@ -10,6 +10,7 @@ module Vexapion
|
|
10
10
|
|
11
11
|
class Coincheck < BaseExchanges
|
12
12
|
|
13
|
+
# :stopdoc:
|
13
14
|
def initialize(key = nil, secret = nil)
|
14
15
|
super(key, secret)
|
15
16
|
|
@@ -17,6 +18,7 @@ module Vexapion
|
|
17
18
|
@private_url = "https://coincheck.com/api/"
|
18
19
|
set_verify_mode(OpenSSL::SSL::VERIFY_NONE)
|
19
20
|
end
|
21
|
+
# :startdoc:
|
20
22
|
|
21
23
|
# Public API
|
22
24
|
|
@@ -443,7 +445,7 @@ module Vexapion
|
|
443
445
|
message = "#{nonce}#{uri.to_s}#{params}"
|
444
446
|
sig = signature(message)
|
445
447
|
headers = header(nonce, sig)
|
446
|
-
request = Net::HTTP::Post.new(uri.request_uri,
|
448
|
+
request = Net::HTTP::Post.new(uri.request_uri, headers)
|
447
449
|
request.body = params if params != ''
|
448
450
|
|
449
451
|
res = do_command(uri, request)
|
@@ -478,5 +480,11 @@ module Vexapion
|
|
478
480
|
}
|
479
481
|
end
|
480
482
|
|
483
|
+
def error_check(res)
|
484
|
+
if !res.nil? && res['success'] == 0 && res.has_key?('error')
|
485
|
+
fail Warning.new(0, res['error'])
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
481
489
|
end #of class
|
482
490
|
end #of VirturalCurrencyExchanger module
|
@@ -1,12 +1,15 @@
|
|
1
|
+
# :stopdoc:
|
1
2
|
# coding: utf-8
|
2
3
|
|
3
4
|
require 'vexapion'
|
5
|
+
require 'bigdecimal'
|
4
6
|
|
5
7
|
module Vexapion
|
6
8
|
|
7
9
|
class HTTPClient
|
8
10
|
|
9
|
-
attr_writer
|
11
|
+
attr_writer :timeout, :timeout_keepalive, :min_interval
|
12
|
+
attr_reader :response_time
|
10
13
|
|
11
14
|
def initialize(i_sec=0.5, i_num=1)
|
12
15
|
@connections = {}
|
@@ -18,10 +21,16 @@ module Vexapion
|
|
18
21
|
@num_of_retry = i_num
|
19
22
|
@last_access_time = Time.now.to_f
|
20
23
|
end
|
24
|
+
|
25
|
+
def disconnect
|
26
|
+
@connections.values.each do |connection|
|
27
|
+
connection.finish
|
28
|
+
end
|
29
|
+
end
|
21
30
|
|
22
31
|
def terminate
|
23
32
|
@connections.values.each do |connection|
|
24
|
-
connection
|
33
|
+
connection = nil
|
25
34
|
end
|
26
35
|
end
|
27
36
|
|
@@ -58,103 +67,53 @@ module Vexapion
|
|
58
67
|
# @raise Fatal APIラッパーの修正が必要になると思われるエラー
|
59
68
|
# @return [String] request.bodyを返す
|
60
69
|
def http_request(uri, request, verify_mode=nil)
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# puts warning message
|
91
|
-
#t = Time.now.strftime("%d %H:%M:%S.%3N")
|
92
|
-
#str = "[response is void]\nurl=%s\nstatus=%d: %s\n"%[
|
93
|
-
# uri.to_s, response.code, response.message]
|
94
|
-
#STDERR.puts "#{t} #{str}"
|
95
|
-
#end
|
96
|
-
|
97
|
-
return response.body
|
98
|
-
|
99
|
-
#3.server error
|
100
|
-
when Net::ReadTimeout, Net::HTTPServerError
|
101
|
-
# retryするつもりだったけど、アプリに任せる
|
102
|
-
#retry_wait = wait_fb(prev_wait, retry_wait)
|
103
|
-
handle_api_error(response)
|
104
|
-
#raise
|
105
|
-
|
106
|
-
#4.client error
|
107
|
-
when Net::HTTPClientError
|
108
|
-
# raise exception
|
109
|
-
#print_error_message(uri, response.message)
|
110
|
-
#raise Vexapion::HTTPClientException
|
111
|
-
handle_api_error(response)
|
112
|
-
#raise
|
113
|
-
|
114
|
-
#5. other
|
115
|
-
else
|
116
|
-
fail Fatal.new(http_status_code, message)
|
117
|
-
#raise
|
118
|
-
end #of case
|
119
|
-
|
120
|
-
end #of retry
|
121
|
-
# error
|
122
|
-
raise VexapionServerError
|
123
|
-
end #of response
|
70
|
+
#最低接続間隔の保証
|
71
|
+
now = Time.now.to_f
|
72
|
+
elapse = f_minus(now, @last_access_time)
|
73
|
+
if elapse < @min_interval
|
74
|
+
s = f_minus(@min_interval, elapse)
|
75
|
+
sleep s
|
76
|
+
end
|
77
|
+
@last_access_time = Time.now.to_f
|
78
|
+
#puts (f_minus(@last_access_time, now) + elapse).round(4)*1000
|
79
|
+
|
80
|
+
response = nil
|
81
|
+
begin
|
82
|
+
t1 = Time.now.to_f
|
83
|
+
http = connection(uri, verify_mode)
|
84
|
+
response = http.request(request)
|
85
|
+
t2 = Time.now.to_f
|
86
|
+
@response_time = f_minus(t2, t1).round(4)*1000
|
87
|
+
#STDERR.puts "\nAPI response time: #{@response_time}ms"
|
88
|
+
|
89
|
+
rescue SocketError, Net::OpenTimeout => e
|
90
|
+
fail RetryException.new('0', e.body)
|
91
|
+
|
92
|
+
rescue Net::ReadTimeout => e
|
93
|
+
http_status_code = 408
|
94
|
+
#message = "Timeout"
|
95
|
+
fail RetryException.new(http_status_code, e.body)
|
96
|
+
end
|
97
|
+
|
98
|
+
handle_http_error(response) if response.code.to_i != 200
|
124
99
|
|
125
|
-
|
126
|
-
|
127
|
-
retry_wait + prev_wait
|
128
|
-
end
|
100
|
+
return response.body
|
101
|
+
end #of response
|
129
102
|
|
130
|
-
def
|
103
|
+
def handle_http_error(response)
|
131
104
|
http_status_code = response.code.to_i
|
132
105
|
message = "#{response.message} #{response.body}"
|
133
106
|
|
134
|
-
|
135
|
-
|
107
|
+
#2.server error
|
136
108
|
case http_status_code
|
137
|
-
when
|
138
|
-
fail
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
when 404
|
147
|
-
fail NotFoundError.new(http_status_code, message)
|
148
|
-
|
149
|
-
when 408
|
150
|
-
fail RequestTimeout.new(http_status_code, message)
|
151
|
-
|
152
|
-
when 500
|
153
|
-
fail ServiceUnavailableError.new(http_status_code, message)
|
154
|
-
|
155
|
-
when 509
|
156
|
-
fail LimitExceededError.new(http_status_code, message)
|
157
|
-
|
109
|
+
when 500,502-504
|
110
|
+
fail RetryException.new(http_status_code, message)
|
111
|
+
|
112
|
+
#3.client error
|
113
|
+
when 400,401,403,404
|
114
|
+
fail Error.new(http_status_code, message)
|
115
|
+
|
116
|
+
#4. other
|
158
117
|
else
|
159
118
|
#puts "http_client.rb: Error: #{http_status_code} #{message}"
|
160
119
|
fail Fatal.new(http_status_code, message)
|
@@ -162,6 +121,12 @@ module Vexapion
|
|
162
121
|
end #of case
|
163
122
|
end #of handle_api_error
|
164
123
|
|
124
|
+
def f_minus(a, b)
|
125
|
+
(BigDecimal(a.to_s) - BigDecimal(b.to_s)).to_f
|
126
|
+
end
|
127
|
+
|
165
128
|
end #of class
|
166
129
|
|
167
130
|
end #of module Vexapion
|
131
|
+
# :startdoc:
|
132
|
+
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# :stopdoc:
|
1
2
|
# coding: utf-8
|
2
3
|
|
3
4
|
# based off of quandl gem: https://github.com/quandl/quandl-ruby
|
@@ -22,10 +23,6 @@ module Vexapion
|
|
22
23
|
class RetryException < HTTPError
|
23
24
|
end
|
24
25
|
|
25
|
-
#場合によってはアプリ側で無視できるエラー
|
26
|
-
class Warning < HTTPError
|
27
|
-
end
|
28
|
-
|
29
26
|
#アプリ側で止めて書き直しが必要なエラー
|
30
27
|
class Error < HTTPError
|
31
28
|
end
|
@@ -34,41 +31,6 @@ module Vexapion
|
|
34
31
|
class Fatal < HTTPError
|
35
32
|
end
|
36
33
|
|
37
|
-
|
38
|
-
#408 Request Timeout
|
39
|
-
class RequestTimeout < RetryException
|
40
|
-
end
|
41
|
-
|
42
|
-
#500
|
43
|
-
class InternalServerError < RetryException
|
44
|
-
end
|
45
|
-
|
46
|
-
#503
|
47
|
-
class ServiceUnavailableError < RetryException
|
48
|
-
end
|
49
|
-
|
50
|
-
#Request Success but response.body == nil
|
51
|
-
class ResponseDataError < Warning
|
52
|
-
end
|
53
|
-
|
54
|
-
#509, and API Limit?
|
55
|
-
class LimitExceededError < Warning
|
56
|
-
end
|
57
|
-
|
58
|
-
#400
|
59
|
-
class InvalidRequestError < Error
|
60
|
-
end
|
61
|
-
|
62
|
-
#401
|
63
|
-
class AuthenticationError < Error
|
64
|
-
end
|
65
|
-
|
66
|
-
#403
|
67
|
-
class ForbiddenError < Error
|
68
|
-
end
|
69
|
-
|
70
|
-
#404
|
71
|
-
class NotFoundError < Error
|
72
|
-
end
|
73
|
-
|
74
34
|
end #of Vexapion module
|
35
|
+
# :startdoc:
|
36
|
+
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# :stopdoc:
|
1
2
|
# coding: utf-8
|
2
3
|
|
3
4
|
# based off of quandl gem: https://github.com/quandl/quandl-ruby
|
@@ -5,27 +6,23 @@
|
|
5
6
|
module Vexapion
|
6
7
|
|
7
8
|
class VexapionRuntimeError < StandardError
|
8
|
-
attr_reader :
|
9
|
-
attr_reader :
|
10
|
-
attr_reader :response
|
9
|
+
attr_reader :code
|
10
|
+
attr_reader :message
|
11
11
|
|
12
|
-
def initialize(
|
13
|
-
@
|
12
|
+
def initialize(i_code, i_msg = nil)
|
13
|
+
@code = i_code
|
14
14
|
@message = i_msg
|
15
|
-
@response = i_response
|
16
15
|
end
|
17
16
|
|
18
17
|
def to_s
|
19
|
-
|
18
|
+
@message
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
23
|
-
#
|
24
|
-
class
|
25
|
-
end
|
26
|
-
|
27
|
-
#Socket Error
|
28
|
-
class SocketError < VexapionRuntimeError
|
22
|
+
#API level error
|
23
|
+
class Warning < VexapionRuntimeError
|
29
24
|
end
|
30
25
|
|
31
26
|
end #of Vexapion module
|
27
|
+
# :startdoc:
|
28
|
+
|
data/lib/vexapion/poloniex.rb
CHANGED
@@ -5,6 +5,7 @@ require 'vexapion'
|
|
5
5
|
module Vexapion
|
6
6
|
|
7
7
|
class Poloniex < BaseExchanges
|
8
|
+
# :stopdoc:
|
8
9
|
def initialize(key = nil, secret = nil)
|
9
10
|
super(key, secret)
|
10
11
|
|
@@ -12,6 +13,7 @@ module Vexapion
|
|
12
13
|
@private_url = 'https://poloniex.com/tradingApi'
|
13
14
|
set_min_interval(0.5)
|
14
15
|
end
|
16
|
+
# :startdoc:
|
15
17
|
|
16
18
|
def set_min_interval(sec)
|
17
19
|
@conn.min_interval = sec
|
@@ -149,7 +151,7 @@ module Vexapion
|
|
149
151
|
header = headers(signature(post_data))
|
150
152
|
|
151
153
|
uri = URI.parse @private_url
|
152
|
-
request = Net::HTTP::Post.new(uri.request_uri,
|
154
|
+
request = Net::HTTP::Post.new(uri.request_uri, header)
|
153
155
|
request.body = post_data
|
154
156
|
|
155
157
|
res = do_command(uri, request)
|
@@ -169,5 +171,11 @@ module Vexapion
|
|
169
171
|
}
|
170
172
|
end
|
171
173
|
|
174
|
+
def error_check(res)
|
175
|
+
if !res.nil? && res['success'] == 0 && res.has_key?('errors')
|
176
|
+
fail Warning(0, res['errors'])
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
172
180
|
end #of class
|
173
181
|
end #of Vexapion module
|
data/lib/vexapion/template.rb
CHANGED
data/lib/vexapion/version.rb
CHANGED
data/lib/vexapion/zaif.rb
CHANGED
@@ -12,7 +12,7 @@ module Vexapion
|
|
12
12
|
# @see https://corp.zaif.jp/api-docs/
|
13
13
|
|
14
14
|
class Zaif < BaseExchanges
|
15
|
-
|
15
|
+
# :stopdoc:
|
16
16
|
def initialize(key = nil, secret = nil)
|
17
17
|
super(key,secret)
|
18
18
|
|
@@ -25,6 +25,7 @@ module Vexapion
|
|
25
25
|
['btc_jpy', 'xem_jpy', 'xem_btc',
|
26
26
|
'mona_jpy', 'mona_btc', 'zaif_jpy', 'zaif_btc']
|
27
27
|
end
|
28
|
+
# :startdoc:
|
28
29
|
|
29
30
|
# Public API
|
30
31
|
|
@@ -244,7 +245,7 @@ module Vexapion
|
|
244
245
|
request['Sign'] = signature(request)
|
245
246
|
|
246
247
|
res = do_command(uri, request)
|
247
|
-
|
248
|
+
error_check(res)
|
248
249
|
res
|
249
250
|
end
|
250
251
|
|
@@ -253,5 +254,11 @@ module Vexapion
|
|
253
254
|
OpenSSL::HMAC.hexdigest(algo, @secret, req.body)
|
254
255
|
end
|
255
256
|
|
257
|
+
def error_check(res)
|
258
|
+
if !res.nil? && res['success'] == 0 && res.has_key?('error')
|
259
|
+
fail Warning.new('0', res['error'])
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
256
263
|
end #of class
|
257
264
|
end #of Vexapion module
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vexapion
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- fuyuton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|