Skip to content

Commit 5b1e347

Browse files
Add Aevo derivatives exchange (#46)
1 parent 144898f commit 5b1e347

File tree

12 files changed

+416
-0
lines changed

12 files changed

+416
-0
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ Then, to install CryptoAPIs, simply use the Julia package manager:
3333
<th>Module</th>
3434
<th>Documentation</th>
3535
</tr>
36+
<tr>
37+
<td><img src="docs/src/assets/aevo.png" alt="Aevo Logo" width="20" height="20"></td>
38+
<td><a href="https://www.aevo.xyz/">Aevo</a></td>
39+
<td><a href="https://api-docs.aevo.xyz/reference/overview">Futures</a></td>
40+
<td><a href="src/Aevo/Futures">CryptoAPIs.Aevo.Futures</a></td>
41+
<td><a href="https://bhftbootcamp.github.io/CryptoAPIs.jl/stable/pages/Aevo/#Futures">Futures</a></td>
42+
</tr>
3643
<tr>
3744
<td><img src="docs/src/assets/binance.png" alt="Binance Logo" width="20" height="20"></td>
3845
<td><a href="https://www.binance.com/en/trade">Binance</a></td>

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ makedocs(;
1616
pages = [
1717
"Home" => "index.md",
1818
"API Reference" => "pages/api_reference.md",
19+
"pages/Aevo.md"
1920
"pages/Binance.md",
2021
"pages/Bitfinex.md",
2122
"pages/Bithumb.md",

docs/src/index.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ Then, to install CryptoAPIs, simply use the Julia package manager:
2727
<th>Module</th>
2828
<th>Documentation</th>
2929
</tr>
30+
<tr>
31+
<td><img src="assets/aevo.png" alt="Aevo Logo" width="20" height="20"></td>
32+
<td><a href="https://www.aevo.xyz/">Aevo</a></td>
33+
<td><a href="https://api-docs.aevo.xyz/reference/overview">Futures</a></td>
34+
<td><a href="src/Aevo/Futures">CryptoAPIs.Aevo.Futures</a></td>
35+
<td><a href="https://bhftbootcamp.github.io/CryptoAPIs.jl/stable/pages/Aevo/#Futures">Futures</a></td>
36+
</tr>
3037
<tr>
3138
<td><img src="assets/binance.png" alt="Binance Logo" width="20" height="20"></td>
3239
<td><a href="https://www.binance.com/en/trade">Binance</a></td>

docs/src/pages/Aevo.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Aevo
2+
3+
```@docs
4+
CryptoAPIs.Aevo.AevoClient
5+
CryptoAPIs.Aevo.AevoAPIError
6+
```
7+
8+
## Futures
9+
10+
```@docs
11+
CryptoAPIs.Aevo.Futures.public_client
12+
```
13+
14+
```@docs
15+
CryptoAPIs.Aevo.Futures.funding_rate
16+
CryptoAPIs.Aevo.Futures.product_stats
17+
```

examples/Aevo/Futures.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Aevo/Futures
2+
# https://api-docs.aevo.xyz/reference/overview
3+
4+
using Dates
5+
using CryptoAPIs
6+
using CryptoAPIs.Aevo
7+
8+
CryptoAPIs.Aevo.Futures.funding_rate(;
9+
instrument_name = "ETH-PERP",
10+
)
11+
12+
CryptoAPIs.Aevo.Futures.product_stats(;
13+
asset = "ETH",
14+
instrument_type = Aevo.Futures.ProductStats.PERPETUAL
15+
)

src/Aevo/Aevo.jl

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
module Aevo
2+
3+
export AevoCommonQuery,
4+
AevoPublicQuery,
5+
AevoAccessQuery,
6+
AevoAPIError,
7+
AevoClient,
8+
AevoData
9+
10+
using Serde
11+
using Dates, NanoDates, TimeZones, Base64, Nettle
12+
13+
using ..CryptoAPIs
14+
import ..CryptoAPIs: Maybe, AbstractAPIsError, AbstractAPIsData, AbstractAPIsQuery, AbstractAPIsClient
15+
16+
abstract type AevoData <: AbstractAPIsData end
17+
abstract type AevoCommonQuery <: AbstractAPIsQuery end
18+
abstract type AevoPublicQuery <: AevoCommonQuery end
19+
abstract type AevoAccessQuery <: AevoCommonQuery end
20+
21+
"""
22+
AevoClient <: AbstractAPIsClient
23+
24+
Client info.
25+
26+
## Required fields
27+
- `base_url::String`: Base URL for the client.
28+
29+
## Optional fields
30+
- `public_key::String`: Public key for authentication.
31+
- `secret_key::String`: Secret key for authentication.
32+
- `interface::String`: Interface for the client.
33+
- `proxy::String`: Proxy information for the client.
34+
- `account_name::String`: Account name associated with the client.
35+
- `description::String`: Description of the client.
36+
"""
37+
Base.@kwdef struct AevoClient <: AbstractAPIsClient
38+
base_url::String
39+
public_key::Maybe{String} = nothing
40+
secret_key::Maybe{String} = nothing
41+
interface::Maybe{String} = nothing
42+
proxy::Maybe{String} = nothing
43+
account_name::Maybe{String} = nothing
44+
description::Maybe{String} = nothing
45+
end
46+
47+
"""
48+
AevoAPIError{T} <: AbstractAPIsError
49+
50+
Exception thrown when an API method fails with code `T`.
51+
52+
## Required fields
53+
- `error::String`: Error message.
54+
"""
55+
struct AevoAPIError{T} <: AbstractAPIsError
56+
error::String
57+
58+
function AevoAPIError(error::String, x...)
59+
return new{Symbol(error)}(error, x...)
60+
end
61+
end
62+
63+
CryptoAPIs.error_type(::AevoClient) = AevoAPIError
64+
65+
function Base.show(io::IO, e::AevoAPIError)
66+
return print(io, "error = ", "\"", e.error)
67+
end
68+
69+
function CryptoAPIs.request_sign!(::AevoClient, query::Q, ::String)::Q where {Q<:AevoCommonQuery}
70+
return query
71+
end
72+
73+
function CryptoAPIs.request_body(::Q)::String where {Q<:AevoCommonQuery}
74+
return ""
75+
end
76+
77+
function CryptoAPIs.request_query(query::Q)::String where {Q<:AevoCommonQuery}
78+
return Serde.to_query(query)
79+
end
80+
81+
function CryptoAPIs.request_headers(client::AevoClient, ::AevoCommonQuery)::Vector{Pair{String,String}}
82+
return Pair{String,String}[
83+
"accept" => "application/json",
84+
]
85+
end
86+
87+
include("Utils.jl")
88+
include("Errors.jl")
89+
90+
include("Futures/Futures.jl")
91+
using .Futures
92+
93+
end

src/Aevo/Errors.jl

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Errors
2+
# https://api-docs.aevo.xyz/reference/errors
3+
4+
import ..CryptoAPIs: APIsResult, APIsUndefError, isretriable, retry_maxcount, retry_timeout
5+
6+
# UNHANDLED
7+
isretriable(::APIsResult{AevoAPIError}) = true
8+
9+
# UNKNOWN
10+
isretriable(e::APIsResult{AevoAPIError{Symbol("UNKNOWN")}}) = false
11+
12+
# TIMED_OUT
13+
isretriable(e::APIsResult{AevoAPIError{Symbol("TIMED_OUT")}}) = true
14+
15+
# BAD_REQUEST
16+
isretriable(e::APIsResult{AevoAPIError{Symbol("BAD_REQUEST")}}) = false
17+
18+
# ASSET_INVALID
19+
isretriable(e::APIsResult{AevoAPIError{Symbol("ASSET_INVALID")}}) = false
20+
21+
# AMOUNT_STEP_SIZE_NOT_WITHIN_RANGE
22+
isretriable(e::APIsResult{AevoAPIError{Symbol("AMOUNT_STEP_SIZE_NOT_WITHIN_RANGE")}}) = false
23+
24+
# INSTRUMENT_DELISTING
25+
isretriable(e::APIsResult{AevoAPIError{Symbol("INSTRUMENT_DELISTING")}}) = false
26+
27+
# INSTRUMENT_EXPIRED
28+
isretriable(e::APIsResult{AevoAPIError{Symbol("INSTRUMENT_EXPIRED")}}) = false
29+
30+
# INSTRUMENT_ID_INVALID
31+
isretriable(e::APIsResult{AevoAPIError{Symbol("INSTRUMENT_ID_INVALID")}}) = false
32+
33+
# INSTRUMENT_INACTIVE
34+
isretriable(e::APIsResult{AevoAPIError{Symbol("INSTRUMENT_INACTIVE")}}) = false
35+
36+
# INSTRUMENT_INVALID
37+
isretriable(e::APIsResult{AevoAPIError{Symbol("INSTRUMENT_INVALID")}}) = false
38+
39+
# INSTRUMENT_NOT_FOUND
40+
isretriable(e::APIsResult{AevoAPIError{Symbol("INSTRUMENT_NOT_FOUND")}}) = false
41+
42+
# INSTRUMENT_NOT_PERPETUAL
43+
isretriable(e::APIsResult{AevoAPIError{Symbol("INSTRUMENT_NOT_PERPETUAL")}}) = false
44+
45+
# INSTRUMENT_PAUSED
46+
isretriable(e::APIsResult{AevoAPIError{Symbol("INSTRUMENT_PAUSED")}}) = false
47+
48+
# INVALID_INSTRUMENT
49+
isretriable(e::APIsResult{AevoAPIError{Symbol("INVALID_INSTRUMENT")}}) = false
50+
51+
# INVALID_PERPETUAL_NAME
52+
isretriable(e::APIsResult{AevoAPIError{Symbol("INVALID_PERPETUAL_NAME")}}) = false
53+
54+
# INVALID_RANGE
55+
isretriable(e::APIsResult{AevoAPIError{Symbol("INVALID_RANGE")}}) = false
56+
57+
# INVALID_TIMESTAMP
58+
isretriable(e::APIsResult{AevoAPIError{Symbol("INVALID_TIMESTAMP")}}) = false
59+
60+
# MISSING_FROM
61+
isretriable(e::APIsResult{AevoAPIError{Symbol("MISSING_FROM")}}) = false
62+
63+
# MISSING_LIMIT
64+
isretriable(e::APIsResult{AevoAPIError{Symbol("MISSING_LIMIT")}}) = false
65+
66+
# MISSING_START
67+
isretriable(e::APIsResult{AevoAPIError{Symbol("MISSING_START")}}) = false
68+
69+
# MISSING_SYMBOL
70+
isretriable(e::APIsResult{AevoAPIError{Symbol("MISSING_SYMBOL")}}) = false
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
module FundingRate
2+
3+
export FundingRateQuery,
4+
FundingRateData,
5+
funding_rate
6+
7+
using Serde
8+
using Dates, NanoDates, TimeZones
9+
10+
using CryptoAPIs.Aevo
11+
using CryptoAPIs: Maybe, APIsRequest
12+
13+
@enum InstrumentType OPTION SPOT PERPETUAL
14+
15+
Base.@kwdef struct FundingRateQuery <: AevoPublicQuery
16+
instrument_name::String
17+
start_time::Maybe{DateTime} = nothing
18+
end_time::Maybe{DateTime} = nothing
19+
limit::Maybe{Int64} = nothing
20+
end
21+
22+
struct FundingHistory <: AevoData
23+
instrument_name::String
24+
timestamp::NanoDate
25+
funding_rate::Float64
26+
mark_price::Float64
27+
end
28+
29+
struct FundingRateData <: AevoData
30+
funding_history::Vector{FundingHistory}
31+
end
32+
33+
"""
34+
funding_rate(client::AevoClient, query::FundingRateQuery)
35+
funding_rate(client::AevoClient = Aevo.Futures.public_client; kw...)
36+
37+
Returns the funding rate history for the instrument.
38+
39+
[`GET funding-history`](https://api-docs.aevo.xyz/reference/getfundinghistory)
40+
41+
## Code samples:
42+
43+
```julia
44+
using Serde
45+
using CryptoAPIs.Aevo
46+
47+
result = Aevo.Futures.funding_rate(;
48+
instrument_name = "ETH-PERP",
49+
)
50+
51+
to_pretty_json(result.result)
52+
```
53+
54+
## Result:
55+
56+
```json
57+
{
58+
"funding_history":[
59+
{
60+
"instrument_name":"ETH-PERP",
61+
"timestamp":"2024-07-08T22:00:00",
62+
"funding_rate":2.0e-6,
63+
"mark_price":3026.093939
64+
},
65+
...
66+
]
67+
}
68+
```
69+
"""
70+
function funding_rate(client::AevoClient, query::FundingRateQuery)
71+
return APIsRequest{FundingRateData}("GET", "funding-history", query)(client)
72+
end
73+
74+
function funding_rate(client::AevoClient = Aevo.Futures.public_client; kw...)
75+
return funding_rate(client, FundingRateQuery(; kw...))
76+
end
77+
78+
end

0 commit comments

Comments
 (0)