kucoin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +6 -0
  7. data/Gemfile.lock +59 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +62 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +31 -0
  12. data/bin/setup +8 -0
  13. data/credentials.yml.example +7 -0
  14. data/kucoin.gemspec +34 -0
  15. data/lib/kucoin.rb +77 -0
  16. data/lib/kucoin/configuration.rb +24 -0
  17. data/lib/kucoin/constants.rb +34 -0
  18. data/lib/kucoin/errors.rb +11 -0
  19. data/lib/kucoin/extensions/hash.rb +27 -0
  20. data/lib/kucoin/extensions/string.rb +13 -0
  21. data/lib/kucoin/models/balance.rb +13 -0
  22. data/lib/kucoin/models/base.rb +26 -0
  23. data/lib/kucoin/models/coin.rb +20 -0
  24. data/lib/kucoin/models/coin_address.rb +17 -0
  25. data/lib/kucoin/models/deal.rb +20 -0
  26. data/lib/kucoin/models/ohlcv.rb +35 -0
  27. data/lib/kucoin/models/order_book.rb +53 -0
  28. data/lib/kucoin/models/ticker.rb +24 -0
  29. data/lib/kucoin/models/trade.rb +38 -0
  30. data/lib/kucoin/models/user.rb +31 -0
  31. data/lib/kucoin/rest/authentication.rb +38 -0
  32. data/lib/kucoin/rest/client.rb +99 -0
  33. data/lib/kucoin/rest/errors.rb +30 -0
  34. data/lib/kucoin/rest/private/balances.rb +34 -0
  35. data/lib/kucoin/rest/private/invitations.rb +24 -0
  36. data/lib/kucoin/rest/private/languages.rb +14 -0
  37. data/lib/kucoin/rest/private/trading.rb +113 -0
  38. data/lib/kucoin/rest/private/transfers.rb +25 -0
  39. data/lib/kucoin/rest/private/user.rb +15 -0
  40. data/lib/kucoin/rest/public/currencies.rb +13 -0
  41. data/lib/kucoin/rest/public/klines.rb +85 -0
  42. data/lib/kucoin/rest/public/languages.rb +13 -0
  43. data/lib/kucoin/rest/public/markets.rb +33 -0
  44. data/lib/kucoin/rest/public/orders.rb +39 -0
  45. data/lib/kucoin/rest/public/ticker.rb +14 -0
  46. data/lib/kucoin/rest/public/trades.rb +22 -0
  47. data/lib/kucoin/utilities/encoding.rb +15 -0
  48. data/lib/kucoin/utilities/parsing.rb +70 -0
  49. data/lib/kucoin/version.rb +3 -0
  50. metadata +218 -0
@@ -0,0 +1,30 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Errors
4
+
5
+ def error?(response)
6
+ if response.is_a?(Hash) && (response.has_key?("error") || response.has_key?("code"))
7
+ status = nil
8
+ message = nil
9
+
10
+ if response.has_key?("error")
11
+ error = response.fetch("error", nil)
12
+ status = response.fetch("status", nil)
13
+ message = response.fetch("message", nil)
14
+ elsif response.has_key?("code") && response.fetch("code", nil).eql?("ERROR")
15
+ message = response.fetch("msg", nil)
16
+ end
17
+
18
+ if !message.to_s.empty?
19
+ if status.nil?
20
+ raise ::Kucoin::Errors::ResponseError.new(message)
21
+ else
22
+ ::Kucoin::Errors::MAPPING.fetch(status, nil)&.call
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Private
4
+ module Balances
5
+
6
+ def wallet_records(coin, type: :deposit, status: :finished, limit: nil, page: nil, options: {})
7
+ options.merge!(authenticate: true)
8
+
9
+ type = type.to_s.upcase
10
+ status = status.to_s.upcase
11
+
12
+ params = {type: type, status: status, limit: limit, page: page}
13
+ params.delete_if { |key, value| value.nil? }
14
+
15
+ parse(get("/account/#{coin}/wallet/records", params: params, options: options))&.fetch("data", {})
16
+ end
17
+
18
+ def coin_balance(coin, options: {})
19
+ options.merge!(authenticate: true)
20
+
21
+ response = parse(get("/account/#{coin}/balance", options: options))&.fetch("data", {})
22
+ ::Kucoin::Models::Balance.new(response) if response
23
+ end
24
+
25
+ def balance(options: {})
26
+ options.merge!(authenticate: true)
27
+ response = parse(get("/account/balance", options: options))&.fetch("data", {})
28
+ ::Kucoin::Models::Balance.parse(response) if response
29
+ end
30
+
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Private
4
+ module Invitations
5
+
6
+ def invitation_count(options: {})
7
+ options.merge!(authenticate: true)
8
+ parse(get("/referrer/descendant/count", options: options))&.fetch("data", {})
9
+ end
10
+
11
+ def promotion_reward(options: {})
12
+ options.merge!(authenticate: true)
13
+ parse(get("/account/promotion/info", options: options))&.fetch("data", {})
14
+ end
15
+
16
+ def promotion_summary(options: {})
17
+ options.merge!(authenticate: true)
18
+ parse(get("/account/promotion/sum", options: options))&.fetch("data", {})
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Private
4
+ module Languages
5
+
6
+ def change_language(language, options: {})
7
+ options.merge!(authenticate: true)
8
+ parse(post("/user/change-lang", data: {lang: language}, options: options))&.fetch("success", false)
9
+ end
10
+
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,113 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Private
4
+ module Trading
5
+
6
+ def create_buy_order(symbol, price:, amount:, options: {})
7
+ create_order(symbol, type: :buy, price: price, amount: amount, options: options)
8
+ end
9
+
10
+ def create_sell_order(symbol, price:, amount:, options: {})
11
+ create_order(symbol, type: :sell, price: price, amount: amount, options: options)
12
+ end
13
+
14
+ def create_order(symbol, type: :buy, price:, amount:, options: {})
15
+ options.merge!(authenticate: true)
16
+
17
+ payload = {
18
+ symbol: symbol.to_s.upcase,
19
+ type: type.to_s.upcase,
20
+ price: price,
21
+ amount: amount
22
+ }
23
+
24
+ parse(post("/order", data: payload, options: options))
25
+ end
26
+
27
+ def cancel_order(symbol, type: :buy, order_id:, options: {})
28
+ options.merge!(authenticate: true)
29
+
30
+ payload = {
31
+ orderOid: order_id,
32
+ type: type.to_s.upcase
33
+ }
34
+
35
+ response = parse(post("/#{symbol}/cancel-order", data: payload, options: options))
36
+ end
37
+
38
+ def cancel_all_orders(symbol, type: :buy, options: {})
39
+ options.merge!(authenticate: true)
40
+
41
+ payload = {
42
+ symbol: symbol.to_s.upcase,
43
+ type: type.to_s.upcase
44
+ }
45
+
46
+ response = parse(post("/order/cancel-all", data: payload, options: options))
47
+ end
48
+
49
+ def active_orders(symbol, type: :buy, options: {})
50
+ options.merge!(authenticate: true)
51
+
52
+ params = {
53
+ symbol: symbol.to_s.upcase,
54
+ type: type.to_s.upcase
55
+ }
56
+
57
+ response = parse(get("/order/active", params: params, options: options))
58
+ end
59
+
60
+ def dealt_orders(symbol: nil, type: nil, before: nil, since: nil, limit: nil, page: nil, options: {})
61
+ options.merge!(authenticate: true)
62
+
63
+ params = {
64
+ symbol: symbol.to_s.upcase,
65
+ type: type.to_s.upcase,
66
+ before: before,
67
+ since: since,
68
+ limit: limit,
69
+ page: page
70
+ }
71
+
72
+ params.delete_if { |key, value| value.nil? }
73
+
74
+ response = parse(get("/order/dealt", params: params, options: options))&.dig("data", "datas")
75
+ ::Kucoin::Models::Deal.parse(response) if response
76
+ end
77
+
78
+ def symbol_dealt_orders(symbol, type: nil, limit: nil, page: nil, options: {})
79
+ options.merge!(authenticate: true)
80
+
81
+ params = {
82
+ symbol: symbol.to_s.upcase,
83
+ type: type.to_s.upcase,
84
+ limit: limit,
85
+ page: page
86
+ }
87
+
88
+ params.delete_if { |key, value| value.nil? }
89
+
90
+ response = parse(get("/deal-orders", params: params, options: options))&.dig("data", "datas")
91
+ ::Kucoin::Models::Deal.parse(response) if response
92
+ end
93
+
94
+ def order_detail(symbol, order_id:, type: :buy, limit: nil, page: nil, options: {})
95
+ options.merge!(authenticate: true)
96
+
97
+ params = {
98
+ symbol: symbol.to_s.upcase,
99
+ orderOid: order_id,
100
+ type: type.to_s.upcase,
101
+ limit: limit,
102
+ page: page
103
+ }
104
+
105
+ params.delete_if { |key, value| value.nil? }
106
+
107
+ response = parse(get("/order/detail", params: params, options: options))&.fetch("data", {})
108
+ end
109
+
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,25 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Private
4
+ module Transfers
5
+
6
+ def get_coin_address(coin, options: {})
7
+ options.merge!(authenticate: true)
8
+ response = parse(get("/account/#{coin}/wallet/address", options: options))&.fetch("data", {})
9
+ ::Kucoin::Models::CoinAddress.new(response) if response
10
+ end
11
+
12
+ def create_withdrawal(coin, amount:, address:, options: {})
13
+ options.merge!(authenticate: true)
14
+ parse(post("/account/#{coin}/withdraw/apply", data: {coin: coin, amount: amount, address: address}, options: options))
15
+ end
16
+
17
+ def cancel_withdrawal(coin, transaction_id:, options: {})
18
+ options.merge!(authenticate: true)
19
+ parse(post("/account/#{coin}/withdraw/cancel", data: {txOid: transaction_id}, options: options))
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Private
4
+ module User
5
+
6
+ def user_info(options: {})
7
+ options.merge!(authenticate: true)
8
+ response = parse(get("/user/info", options: options))&.fetch("data", {})
9
+ ::Kucoin::Models::User.new(response) if response
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Public
4
+ module Currencies
5
+
6
+ def exchange_rates(options: {})
7
+ parse(get("/open/currencies", options: options))&.dig("data", "rates")
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,85 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Public
4
+ module Klines
5
+
6
+ # Not working propely / not implemented?
7
+ def kline_data(symbol, type: :one_hour, from: nil, to: nil, limit: 100, options: {})
8
+ to ||= Time.now.utc
9
+ from ||= default_from_time(type, to)
10
+ from = from.to_i unless from.is_a?(Integer)
11
+ to = to.to_i unless to.is_a?(Integer)
12
+
13
+ type = ::Kucoin::Constants::STANDARD_KLINE_RESOLUTIONS[type]
14
+
15
+ params = {
16
+ symbol: symbol,
17
+ type: type,
18
+ from: from,
19
+ to: to,
20
+ limit: limit
21
+ }
22
+
23
+ params.delete_if { |key, value| value.nil? }
24
+
25
+ response = parse(get("/open/kline", params: params, options: options))&.fetch("data", {})
26
+ end
27
+
28
+ #
29
+ # TradingView related endpoints:
30
+ #
31
+ def kline_config(options: {})
32
+ parse(get("/open/chart/config", options: options))
33
+ end
34
+
35
+ def chart_symbol(symbol, options: {})
36
+ response = parse(get("/open/chart/symbols", params: {symbol: symbol}, options: options))
37
+ end
38
+
39
+ def chart_kline_data(symbol, resolution: :one_hour, from: nil, to: nil, options: {})
40
+ to ||= Time.now.utc
41
+ from ||= default_from_time(resolution, to)
42
+ from = from.to_i unless from.is_a?(Integer)
43
+ to = to.to_i unless to.is_a?(Integer)
44
+
45
+ resolution = ::Kucoin::Constants::TRADING_VIEW_KLINE_RESOLUTIONS[resolution]
46
+
47
+ params = {
48
+ symbol: symbol,
49
+ resolution: resolution,
50
+ from: from,
51
+ to: to
52
+ }
53
+
54
+ params.delete_if { |key, value| value.nil? }
55
+
56
+ response = parse(get("/open/chart/history", params: params, options: options))
57
+ ::Kucoin::Models::OHLCV.parse(response) if response
58
+ end
59
+
60
+ private
61
+ def default_from_time(type, time = Time.now.utc)
62
+ case type
63
+ when :one_minute
64
+ time - (1 * ::Kucoin::Constants::IN_SECONDS[:minute])
65
+ when :five_minutes
66
+ time - (5 * ::Kucoin::Constants::IN_SECONDS[:minute])
67
+ when :fifteen_minutes
68
+ time - (15 * ::Kucoin::Constants::IN_SECONDS[:minute])
69
+ when :thirty_minutes
70
+ time - (30 * ::Kucoin::Constants::IN_SECONDS[:minute])
71
+ when :one_hour
72
+ time - (1 * ::Kucoin::Constants::IN_SECONDS[:hour])
73
+ when :eight_hours
74
+ time - (8 * ::Kucoin::Constants::IN_SECONDS[:hour])
75
+ when :one_day
76
+ time - (1 * ::Kucoin::Constants::IN_SECONDS[:day])
77
+ when :one_week
78
+ time - (1 * ::Kucoin::Constants::IN_SECONDS[:week])
79
+ end
80
+ end
81
+
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,13 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Public
4
+ module Languages
5
+
6
+ def languages(options: {})
7
+ parse(get("/open/lang-list", options: options))&.fetch("data", [])
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Public
4
+ module Markets
5
+
6
+ def markets(options: {})
7
+ parse(get("/open/markets", options: options))&.fetch("data", {})
8
+ end
9
+
10
+ # /market/open/symbols is also available, seems to be the same endpoint
11
+ def market_symbols(market, options: {})
12
+ response = parse(get("/open/symbols", params: {market: market}, options: options))&.fetch("data", {})
13
+ ::Kucoin::Models::Ticker.parse(response) if response
14
+ end
15
+
16
+ def trending_symbols(market, options: {})
17
+ response = parse(get("/market/open/coins-trending", params: {market: market}, options: options))&.fetch("data", {})
18
+ end
19
+
20
+ def coins(options: {})
21
+ response = parse(get("/market/open/coins", options: options))&.fetch("data", {})
22
+ ::Kucoin::Models::Coin.parse(response) if response
23
+ end
24
+
25
+ def coin_info(coin, options: {})
26
+ response = parse(get("/market/open/coin-info", params: {coin: coin}, options: options))&.fetch("data", {})
27
+ ::Kucoin::Models::Coin.new(response) if response
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,39 @@
1
+ module Kucoin
2
+ module Rest
3
+ module Public
4
+ module Orders
5
+
6
+ def orders(symbol, limit: 100, group: nil, options: {})
7
+ get_orders(symbol: symbol, endpoint: "/open/orders", params: order_params(symbol, group, limit), type: nil, options: options)
8
+ end
9
+
10
+ def buy_orders(symbol, limit: 100, group: nil, options: {})
11
+ get_orders(symbol: symbol, endpoint: "/open/orders-buy", params: order_params(symbol, group, limit), type: "BUY", options: options)
12
+ end
13
+
14
+ def sell_orders(symbol, limit: 100, group: nil, options: {})
15
+ get_orders(symbol: symbol, endpoint: "/open/orders-sell", params: order_params(symbol, group, limit), type: "SELL", options: options)
16
+ end
17
+
18
+ private
19
+ def get_orders(symbol:, endpoint:, params: {}, type: nil, options: {})
20
+ response = parse(get(endpoint, params: params, options: options))&.merge("symbol" => symbol)
21
+ ::Kucoin::Models::OrderBook.new(response, type: type) if response
22
+ end
23
+
24
+ def order_params(symbol, group = nil, limit = nil)
25
+ params = {
26
+ symbol: symbol,
27
+ group: group,
28
+ limit: limit
29
+ }
30
+
31
+ params.delete_if { |key, value| value.nil? }
32
+
33
+ return params
34
+ end
35
+
36
+ end
37
+ end
38
+ end
39
+ end