-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
559 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Kucoin | ||
|
||
```@docs | ||
CryptoAPIs.Kucoin.KucoinClient | ||
CryptoAPIs.Kucoin.KucoinAPIError | ||
CryptoAPIs.Kucoin.Data | ||
CryptoAPIs.Kucoin.Page | ||
``` | ||
|
||
## Spot | ||
|
||
```@docs | ||
CryptoAPIs.Kucoin.Spot.public_client | ||
``` | ||
|
||
```@docs | ||
CryptoAPIs.Kucoin.Spot.candle | ||
CryptoAPIs.Kucoin.Spot.deposit | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Kucoin/Spot | ||
# https://docs.kucoin.com/ | ||
|
||
using Dates | ||
using CryptoAPIs | ||
using CryptoAPIs.Kucoin | ||
|
||
CryptoAPIs.Kucoin.Spot.candle(; | ||
symbol = "BTC-USDT", | ||
type = CryptoAPIs.Kucoin.Spot.Candle.m1, | ||
) | ||
|
||
kucoin_client = KucoinClient(; | ||
base_url = "https://api.kucoin.com", | ||
public_key = ENV["KUCOIN_PUBLIC_KEY"], | ||
secret_key = ENV["KUCOIN_SECRET_KEY"], | ||
passphrase = ENV["KUCOIN_PASSPHRASE"], | ||
) | ||
|
||
CryptoAPIs.Kucoin.Spot.deposit( | ||
kucoin_client; | ||
currency = "BTC", | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
# Errors | ||
# https://docs.kucoin.com/#request | ||
|
||
import ..CryptoAPIs: APIsResult, APIsUndefError | ||
import ..CryptoAPIs: isretriable, retry_maxcount, retry_timeout | ||
|
||
# UNDEF | ||
isretriable(e::APIsResult{KucoinAPIError}) = true | ||
|
||
# Order creation for this pair suspended | ||
isretriable(e::APIsResult{KucoinAPIError{200001}}) = false | ||
|
||
# Order cancel for this pair suspended | ||
isretriable(e::APIsResult{KucoinAPIError{200002}}) = false | ||
|
||
# Number of orders breached the limit | ||
isretriable(e::APIsResult{KucoinAPIError{200003}}) = false | ||
|
||
# Please complete the KYC verification before you trade XX | ||
isretriable(e::APIsResult{KucoinAPIError{200009}}) = false | ||
|
||
# Balance insufficient | ||
isretriable(e::APIsResult{KucoinAPIError{200004}}) = false | ||
|
||
# withdraw.disabled -- Currency/Chain withdraw is closed, or user is frozen to withdraw | ||
isretriable(e::APIsResult{KucoinAPIError{260210}}) = false | ||
|
||
# Any of KC-API-KEY, KC-API-SIGN, KC-API-TIMESTAMP, KC-API-PASSPHRASE is missing in your request header | ||
isretriable(e::APIsResult{KucoinAPIError{400001}}) = false | ||
|
||
# KC-API-TIMESTAMP Invalid | ||
isretriable(e::APIsResult{KucoinAPIError{400002}}) = false | ||
|
||
# KC-API-KEY not exists | ||
isretriable(e::APIsResult{KucoinAPIError{400003}}) = false | ||
|
||
# KC-API-PASSPHRASE error | ||
isretriable(e::APIsResult{KucoinAPIError{400004}}) = false | ||
|
||
# Signature error | ||
isretriable(e::APIsResult{KucoinAPIError{400005}}) = false | ||
|
||
# The requested ip address is not in the api whitelist | ||
isretriable(e::APIsResult{KucoinAPIError{400006}}) = false | ||
|
||
# Access Denied | ||
isretriable(e::APIsResult{KucoinAPIError{400007}}) = false | ||
|
||
# Url Not Found | ||
isretriable(e::APIsResult{KucoinAPIError{404000}}) = false | ||
|
||
# Parameter Error | ||
isretriable(e::APIsResult{KucoinAPIError{400100}}) = false | ||
|
||
# Forbidden to place an order | ||
isretriable(e::APIsResult{KucoinAPIError{400200}}) = false | ||
|
||
# Your located country/region is currently not supported for the trading of this token | ||
isretriable(e::APIsResult{KucoinAPIError{400500}}) = false | ||
|
||
# validation.createOrder.symbolNotAvailable -- The trading pair has not yet started trading | ||
isretriable(e::APIsResult{KucoinAPIError{400600}}) = false | ||
|
||
# Transaction restricted, there's a risk problem in your account | ||
isretriable(e::APIsResult{KucoinAPIError{400700}}) = false | ||
|
||
# Leverage order failed | ||
isretriable(e::APIsResult{KucoinAPIError{400800}}) = false | ||
|
||
# User are frozen | ||
isretriable(e::APIsResult{KucoinAPIError{411100}}) = false | ||
|
||
# Unsupported Media Type -- The Content-Type of the request header needs to be set to application/json | ||
isretriable(e::APIsResult{KucoinAPIError{415000}}) = false | ||
|
||
# Too many request | ||
isretriable(e::APIsResult{KucoinAPIError{429000}}) = true | ||
retry_timeout(e::APIsResult{KucoinAPIError{429000}}) = 5 | ||
retry_maxcount(e::APIsResult{KucoinAPIError{429000}}) = 50 | ||
|
||
# Internal Server Error | ||
isretriable(e::APIsResult{KucoinAPIError{500000}}) = true | ||
|
||
# symbol not exists | ||
isretriable(e::APIsResult{KucoinAPIError{900001}}) = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
module Kucoin | ||
|
||
export KucoinCommonQuery, | ||
KucoinPublicQuery, | ||
KucoinAccessQuery, | ||
KucoinPrivateQuery, | ||
KucoinAPIError, | ||
KucoinClient, | ||
KucoinData | ||
|
||
using Serde | ||
using Dates, NanoDates, TimeZones, Base64, Nettle | ||
|
||
using ..CryptoAPIs | ||
import ..CryptoAPIs: Maybe, AbstractAPIsError, AbstractAPIsData, AbstractAPIsQuery, AbstractAPIsClient | ||
|
||
abstract type KucoinData <: AbstractAPIsData end | ||
abstract type KucoinCommonQuery <: AbstractAPIsQuery end | ||
abstract type KucoinPublicQuery <: KucoinCommonQuery end | ||
abstract type KucoinAccessQuery <: KucoinCommonQuery end | ||
abstract type KucoinPrivateQuery <: KucoinCommonQuery end | ||
|
||
""" | ||
Data{D} <: AbstractAPIsData | ||
## Required fields | ||
- `code::Int64`: Result code. | ||
- `data::D`: Result data. | ||
""" | ||
struct Data{D<:Union{A,Vector{A}} where {A<:AbstractAPIsData}} <: AbstractAPIsData | ||
code::Int64 | ||
data::D | ||
end | ||
|
||
""" | ||
Page{D} <: AbstractAPIsData | ||
## Required fields | ||
- `pageSize::Int64`: Number of results per request. | ||
- `totalNum::Int64`: Total number of results. | ||
- `currentPage::Int64`: Current request page. | ||
- `totalPage::Int64`: Total request page. | ||
- `items::Vector{D}`: Result data. | ||
""" | ||
struct Page{D<:AbstractAPIsData} <:AbstractAPIsData | ||
pageSize::Int64 | ||
totalNum::Int64 | ||
currentPage::Int64 | ||
totalPage::Int64 | ||
items::Vector{D} | ||
end | ||
|
||
""" | ||
KucoinClient <: AbstractAPIsClient | ||
Client info. | ||
## Required fields | ||
- `base_url::String`: Base URL for the client. | ||
## Optional fields | ||
- `public_key::String`: Public key for authentication. | ||
- `secret_key::String`: Secret key for authentication. | ||
- `interface::String`: Interface for the client. | ||
- `proxy::String`: Proxy information for the client. | ||
- `account_name::String`: Account name associated with the client. | ||
- `description::String`: Description of the client. | ||
""" | ||
Base.@kwdef struct KucoinClient <: AbstractAPIsClient | ||
base_url::String | ||
public_key::Maybe{String} = nothing | ||
secret_key::Maybe{String} = nothing | ||
passphrase::Maybe{String} = nothing | ||
interface::Maybe{String} = nothing | ||
proxy::Maybe{String} = nothing | ||
account_name::Maybe{String} = nothing | ||
description::Maybe{String} = nothing | ||
end | ||
|
||
""" | ||
KucoinAPIError{T} <: AbstractAPIsError | ||
Exception thrown when an API method fails with code `T`. | ||
## Required fields | ||
- `code::Int64`: Error code. | ||
- `msg::String`: Error message. | ||
""" | ||
struct KucoinAPIError{T} <: AbstractAPIsError | ||
code::Int64 | ||
msg::String | ||
|
||
function KucoinAPIError(code::Int64, x...) | ||
return new{code}(code, x...) | ||
end | ||
end | ||
|
||
CryptoAPIs.error_type(::KucoinClient) = KucoinAPIError | ||
|
||
function Base.show(io::IO, e::KucoinAPIError) | ||
return print(io, "code = ", "\"", e.code, "\"", ", ", "msg = ", "\"", e.msg, "\"") | ||
end | ||
|
||
function CryptoAPIs.request_sign!(::KucoinClient, query::Q, ::String)::Q where {Q<:KucoinPublicQuery} | ||
return query | ||
end | ||
|
||
function CryptoAPIs.request_sign!(client::KucoinClient, query::Q, endpoint::String)::Q where {Q <: KucoinPrivateQuery} | ||
query.timestamp = Dates.now(UTC) | ||
query.signature = nothing | ||
salt = join([string(round(Int64, 1000 * datetime2unix(query.timestamp))), "GET/$endpoint?", Serde.to_query(query)]) | ||
query.passphrase = Base64.base64encode(digest("sha256", client.secret_key, client.passphrase)) | ||
query.signature = Base64.base64encode(digest("sha256", client.secret_key, salt)) | ||
return query | ||
end | ||
|
||
function CryptoAPIs.request_body(::Q)::String where {Q<:KucoinCommonQuery} | ||
return "" | ||
end | ||
|
||
function CryptoAPIs.request_query(query::Q)::String where {Q<:KucoinCommonQuery} | ||
return Serde.to_query(query) | ||
end | ||
|
||
function CryptoAPIs.request_headers(client::KucoinClient, ::KucoinPublicQuery)::Vector{Pair{String,String}} | ||
return Pair{String,String}[ | ||
"Content-Type" => "application/json" | ||
] | ||
end | ||
|
||
function CryptoAPIs.request_headers(client::KucoinClient, query::KucoinPrivateQuery)::Vector{Pair{String,String}} | ||
return Pair{String,String}[ | ||
"KC-API-SIGN" => query.signature, | ||
"KC-API-TIMESTAMP" => string(round(Int64, 1000 * datetime2unix(query.timestamp))), | ||
"KC-API-KEY" => client.public_key, | ||
"KC-API-PASSPHRASE" => query.passphrase, | ||
"Content-Type" => "application/json", | ||
"KC-API-KEY-VERSION" => "2", | ||
] | ||
end | ||
|
||
include("Utils.jl") | ||
include("Errors.jl") | ||
|
||
include("Spot/Spot.jl") | ||
using .Spot | ||
|
||
end |
Oops, something went wrong.