kucoin 0.1.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.
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