Merge pull request #1139 from c9s/refactor/max-client

REFACTOR: [max] refactor api requests
This commit is contained in:
Yo-An Lin 2023-04-12 16:38:57 +08:00 committed by GitHub
commit 6bf7a6c0ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 955 additions and 373 deletions

16
go.mod
View File

@ -9,11 +9,10 @@ require (
github.com/Masterminds/squirrel v1.5.3
github.com/adshao/go-binance/v2 v2.4.1
github.com/c-bata/goptuna v0.8.1
github.com/c9s/requestgen v1.3.0
github.com/c9s/requestgen v1.3.4
github.com/c9s/rockhopper v1.2.2-0.20220617053729-ffdc87df194b
github.com/cenkalti/backoff/v4 v4.2.0
github.com/cheggaaa/pb/v3 v3.0.8
github.com/cloudflare/cfssl v0.0.0-20190808011637-b1ec8c586c2a
github.com/codingconcepts/env v0.0.0-20200821220118-a8fbf8d84482
github.com/ethereum/go-ethereum v1.10.23
github.com/evanphx/json-patch/v5 v5.6.0
@ -55,7 +54,7 @@ require (
github.com/x-cray/logrus-prefixed-formatter v0.5.2
github.com/zserge/lorca v0.1.9
go.uber.org/multierr v1.7.0
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/sync v0.1.0
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
gonum.org/v1/gonum v0.8.2
google.golang.org/grpc v1.45.0
@ -137,11 +136,12 @@ require (
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
golang.org/x/net v0.0.0-20220607020251-c690dde0001d // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.11 // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.8.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
golang.org/x/text v0.8.0 // indirect
golang.org/x/tools v0.7.0 // indirect
google.golang.org/genproto v0.0.0-20220405205423-9d709892a2bf // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect

32
go.sum
View File

@ -49,8 +49,6 @@ github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrU
github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o=
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
github.com/adshao/go-binance/v2 v2.3.10 h1:iWtHD/sQ8GK6r+cSMMdOynpGI/4Q6P5LZtiEHdWOjag=
github.com/adshao/go-binance/v2 v2.3.10/go.mod h1:Z3MCnWI0gHC4Rea8TWiF3aN1t4nV9z3CaU/TeHcKsLM=
github.com/adshao/go-binance/v2 v2.4.1 h1:fOZ2tCbN7sgDZvvsawUMjhsOoe40X87JVE4DklIyyyc=
github.com/adshao/go-binance/v2 v2.4.1/go.mod h1:6Qoh+CYcj8U43h4HgT6mqJnsGj4mWZKA/nsj8LN8ZTU=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
@ -76,7 +74,6 @@ github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkN
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k=
@ -84,8 +81,8 @@ github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFA
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U=
github.com/c-bata/goptuna v0.8.1 h1:25+n1MLv0yvCsD56xv4nqIus3oLHL9GuPAZDLIqmX1U=
github.com/c-bata/goptuna v0.8.1/go.mod h1:knmS8+Iyq5PPy1YUeIEq0pMFR4Y6x7z/CySc9HlZTCY=
github.com/c9s/requestgen v1.3.0 h1:3cTHvWIlrc37nGEdJLIO07XaVidDeOwcew06csBz++U=
github.com/c9s/requestgen v1.3.0/go.mod h1:5n9FU3hr5307IiXAmbMiZbHYaPiys1u9jCWYexZr9qA=
github.com/c9s/requestgen v1.3.4 h1:kK2rIO3OAt9JoY5gT0OSkSpq0dy/+JeuI22FwSKpUrY=
github.com/c9s/requestgen v1.3.4/go.mod h1:wp4saiPdh0zLF5AkopGCqPQfy9Q5xvRh+TQBOA1l1r4=
github.com/c9s/rockhopper v1.2.2-0.20220617053729-ffdc87df194b h1:wT8c03PHLv7+nZUIGqxAzRvIfYHNxMCNVWwvdGkOXTs=
github.com/c9s/rockhopper v1.2.2-0.20220617053729-ffdc87df194b/go.mod h1:EKObf66Cp7erWxym2de+07qNN5T1N9PXxHdh97N44EQ=
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
@ -105,7 +102,6 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cfssl v0.0.0-20190808011637-b1ec8c586c2a h1:ym8P2+ZvUvVtpLzy8wFLLvdggUIU31mvldvxixQQI2o=
github.com/cloudflare/cfssl v0.0.0-20190808011637-b1ec8c586c2a/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@ -427,7 +423,6 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
@ -788,6 +783,8 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -831,8 +828,8 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -849,8 +846,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -912,11 +910,12 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -924,8 +923,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -983,8 +983,8 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.11 h1:loJ25fNOEhSXfHrpoGj91eCUThwdNX6u24rO1xnNteY=
golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -72,13 +72,13 @@ func (e *Exchange) QueryTicker(ctx context.Context, symbol string) (*types.Ticke
return &types.Ticker{
Time: ticker.Time,
Volume: fixedpoint.MustNewFromString(ticker.Volume),
Last: fixedpoint.MustNewFromString(ticker.Last),
Open: fixedpoint.MustNewFromString(ticker.Open),
High: fixedpoint.MustNewFromString(ticker.High),
Low: fixedpoint.MustNewFromString(ticker.Low),
Buy: fixedpoint.MustNewFromString(ticker.Buy),
Sell: fixedpoint.MustNewFromString(ticker.Sell),
Volume: ticker.Volume,
Last: ticker.Last,
Open: ticker.Open,
High: ticker.High,
Low: ticker.Low,
Buy: ticker.Buy,
Sell: ticker.Sell,
}, nil
}
@ -112,15 +112,16 @@ func (e *Exchange) QueryTickers(ctx context.Context, symbol ...string) (map[stri
if _, ok := m[toGlobalSymbol(k)]; len(symbol) != 0 && !ok {
continue
}
tickers[toGlobalSymbol(k)] = types.Ticker{
Time: v.Time,
Volume: fixedpoint.MustNewFromString(v.Volume),
Last: fixedpoint.MustNewFromString(v.Last),
Open: fixedpoint.MustNewFromString(v.Open),
High: fixedpoint.MustNewFromString(v.High),
Low: fixedpoint.MustNewFromString(v.Low),
Buy: fixedpoint.MustNewFromString(v.Buy),
Sell: fixedpoint.MustNewFromString(v.Sell),
Volume: v.Volume,
Last: v.Last,
Open: v.Open,
High: v.High,
Low: v.Low,
Buy: v.Buy,
Sell: v.Sell,
}
}
}
@ -551,7 +552,7 @@ func (e *Exchange) QueryAccount(ctx context.Context) (*types.Account, error) {
return nil, err
}
vipLevel, err := e.client.AccountService.NewGetVipLevelRequest().Do(ctx)
vipLevel, err := e.client.NewGetVipLevelRequest().Do(ctx)
if err != nil {
return nil, err
}
@ -642,14 +643,14 @@ func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since
}
log.Infof("querying withdraw %s: %s <=> %s", asset, startTime, endTime)
req := e.client.AccountService.NewGetWithdrawalHistoryRequest()
req := e.client.NewGetWithdrawalHistoryRequest()
if len(asset) > 0 {
req.Currency(toLocalCurrency(asset))
}
withdraws, err := req.
From(startTime.Unix()).
To(endTime.Unix()).
From(startTime).
To(endTime).
Limit(limit).
Do(ctx)
@ -690,7 +691,7 @@ func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since
txIDs[d.TxID] = struct{}{}
withdraw := types.Withdraw{
Exchange: types.ExchangeMax,
ApplyTime: types.Time(time.Unix(d.CreatedAt, 0)),
ApplyTime: types.Time(d.CreatedAt),
Asset: toGlobalCurrency(d.Currency),
Amount: d.Amount,
Address: "",
@ -710,7 +711,7 @@ func (e *Exchange) QueryWithdrawHistory(ctx context.Context, asset string, since
startTime = endTime
} else {
// its in descending order, so we get the first record
startTime = time.Unix(withdraws[0].CreatedAt, 0)
startTime = withdraws[0].CreatedAt.Time()
}
}
@ -739,14 +740,14 @@ func (e *Exchange) QueryDepositHistory(ctx context.Context, asset string, since,
log.Infof("querying deposit history %s: %s <=> %s", asset, startTime, endTime)
req := e.client.AccountService.NewGetDepositHistoryRequest()
req := e.client.NewGetDepositHistoryRequest()
if len(asset) > 0 {
req.Currency(toLocalCurrency(asset))
}
deposits, err := req.
From(startTime.Unix()).
To(endTime.Unix()).
From(startTime).
To(endTime).
Limit(limit).
Do(ctx)
@ -762,7 +763,7 @@ func (e *Exchange) QueryDepositHistory(ctx context.Context, asset string, since,
allDeposits = append(allDeposits, types.Deposit{
Exchange: types.ExchangeMax,
Time: types.Time(time.Unix(d.CreatedAt, 0)),
Time: types.Time(d.CreatedAt),
Amount: d.Amount,
Asset: toGlobalCurrency(d.Currency),
Address: "", // not supported
@ -775,7 +776,7 @@ func (e *Exchange) QueryDepositHistory(ctx context.Context, asset string, since,
if len(deposits) < limit {
startTime = endTime
} else {
startTime = time.Unix(deposits[0].CreatedAt, 0)
startTime = time.Time(deposits[0].CreatedAt)
}
}
@ -959,8 +960,7 @@ func (e *Exchange) QueryAveragePrice(ctx context.Context, symbol string) (fixedp
return fixedpoint.Zero, err
}
return fixedpoint.MustNewFromString(ticker.Sell).
Add(fixedpoint.MustNewFromString(ticker.Buy)).Div(Two), nil
return ticker.Sell.Add(ticker.Buy).Div(Two), nil
}
func (e *Exchange) RepayMarginAsset(ctx context.Context, asset string, amount fixedpoint.Value) error {

View File

@ -5,9 +5,12 @@ package max
//go:generate -command DeleteRequest requestgen -method DELETE
import (
"time"
"github.com/c9s/requestgen"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
type AccountService struct {
@ -79,8 +82,8 @@ type GetVipLevelRequest struct {
client requestgen.AuthenticatedAPIClient
}
func (s *AccountService) NewGetVipLevelRequest() *GetVipLevelRequest {
return &GetVipLevelRequest{client: s.client}
func (c *RestClient) NewGetVipLevelRequest() *GetVipLevelRequest {
return &GetVipLevelRequest{client: c}
}
//go:generate GetRequest -url "v2/members/accounts/:currency" -type GetAccountRequest -responseType .Account
@ -90,8 +93,8 @@ type GetAccountRequest struct {
currency string `param:"currency,slug"`
}
func (s *AccountService) NewGetAccountRequest() *GetAccountRequest {
return &GetAccountRequest{client: s.client}
func (c *RestClient) NewGetAccountRequest() *GetAccountRequest {
return &GetAccountRequest{client: c}
}
//go:generate GetRequest -url "v2/members/accounts" -type GetAccountsRequest -responseType []Account
@ -99,36 +102,36 @@ type GetAccountsRequest struct {
client requestgen.AuthenticatedAPIClient
}
func (s *AccountService) NewGetAccountsRequest() *GetAccountsRequest {
return &GetAccountsRequest{client: s.client}
func (c *RestClient) NewGetAccountsRequest() *GetAccountsRequest {
return &GetAccountsRequest{client: c}
}
type Deposit struct {
Currency string `json:"currency"`
CurrencyVersion string `json:"currency_version"` // "eth"
Amount fixedpoint.Value `json:"amount"`
Fee fixedpoint.Value `json:"fee"`
TxID string `json:"txid"`
State string `json:"state"`
Confirmations int64 `json:"confirmations"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
Currency string `json:"currency"`
CurrencyVersion string `json:"currency_version"` // "eth"
Amount fixedpoint.Value `json:"amount"`
Fee fixedpoint.Value `json:"fee"`
TxID string `json:"txid"`
State string `json:"state"`
Confirmations int64 `json:"confirmations"`
CreatedAt types.MillisecondTimestamp `json:"created_at"`
UpdatedAt types.MillisecondTimestamp `json:"updated_at"`
}
//go:generate GetRequest -url "v2/deposits" -type GetDepositHistoryRequest -responseType []Deposit
type GetDepositHistoryRequest struct {
client requestgen.AuthenticatedAPIClient
currency *string `param:"currency"`
from *int64 `param:"from"` // seconds
to *int64 `param:"to"` // seconds
state *string `param:"state"` // submitting, submitted, rejected, accepted, checking, refunded, canceled, suspect
limit *int `param:"limit"`
currency *string `param:"currency"`
from *time.Time `param:"from,seconds"` // seconds
to *time.Time `param:"to,seconds"` // seconds
state *string `param:"state"` // submitting, submitted, rejected, accepted, checking, refunded, canceled, suspect
limit *int `param:"limit"`
}
func (s *AccountService) NewGetDepositHistoryRequest() *GetDepositHistoryRequest {
func (c *RestClient) NewGetDepositHistoryRequest() *GetDepositHistoryRequest {
return &GetDepositHistoryRequest{
client: s.client,
client: c,
}
}
@ -147,26 +150,26 @@ type Withdraw struct {
// "failed", "pending", "confirmed",
// "kgi_manually_processing", "kgi_manually_confirmed", "kgi_possible_failed",
// "sygna_verifying"
State string `json:"state"`
Confirmations int `json:"confirmations"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
Notes string `json:"notes"`
State string `json:"state"`
Confirmations int `json:"confirmations"`
CreatedAt types.MillisecondTimestamp `json:"created_at"`
UpdatedAt types.MillisecondTimestamp `json:"updated_at"`
Notes string `json:"notes"`
}
//go:generate GetRequest -url "v2/withdrawals" -type GetWithdrawHistoryRequest -responseType []Withdraw
type GetWithdrawHistoryRequest struct {
client requestgen.AuthenticatedAPIClient
currency string `param:"currency"`
from *int64 `param:"from"` // seconds
to *int64 `param:"to"` // seconds
state *string `param:"state"` // submitting, submitted, rejected, accepted, checking, refunded, canceled, suspect
limit *int `param:"limit"`
currency string `param:"currency"`
from *time.Time `param:"from,seconds"` // seconds
to *time.Time `param:"to,seconds"` // seconds
state *string `param:"state"` // submitting, submitted, rejected, accepted, checking, refunded, canceled, suspect
limit *int `param:"limit"`
}
func (s *AccountService) NewGetWithdrawalHistoryRequest() *GetWithdrawHistoryRequest {
func (c *RestClient) NewGetWithdrawalHistoryRequest() *GetWithdrawHistoryRequest {
return &GetWithdrawHistoryRequest{
client: s.client,
client: c,
}
}

View File

@ -18,7 +18,7 @@ func TestAccountService_GetAccountsRequest(t *testing.T) {
client := NewRestClient(ProductionAPIURL)
client.Auth(key, secret)
req := client.AccountService.NewGetAccountsRequest()
req := client.NewGetAccountsRequest()
accounts, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotNil(t, accounts)
@ -38,14 +38,14 @@ func TestAccountService_GetAccountRequest(t *testing.T) {
client := NewRestClient(ProductionAPIURL)
client.Auth(key, secret)
req := client.AccountService.NewGetAccountRequest()
req := client.NewGetAccountRequest()
req.Currency("twd")
account, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotNil(t, account)
t.Logf("account: %+v", account)
req2 := client.AccountService.NewGetAccountRequest()
req2 := client.NewGetAccountRequest()
req2.Currency("usdt")
account, err = req.Do(ctx)
assert.NoError(t, err)
@ -64,7 +64,7 @@ func TestAccountService_GetVipLevelRequest(t *testing.T) {
client := NewRestClient(ProductionAPIURL)
client.Auth(key, secret)
req := client.AccountService.NewGetVipLevelRequest()
req := client.NewGetVipLevelRequest()
vipLevel, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotNil(t, vipLevel)
@ -82,7 +82,7 @@ func TestAccountService_GetWithdrawHistoryRequest(t *testing.T) {
client := NewRestClient(ProductionAPIURL)
client.Auth(key, secret)
req := client.AccountService.NewGetWithdrawalHistoryRequest()
req := client.NewGetWithdrawalHistoryRequest()
req.Currency("usdt")
withdraws, err := req.Do(ctx)
assert.NoError(t, err)
@ -102,7 +102,7 @@ func TestAccountService_NewGetDepositHistoryRequest(t *testing.T) {
client := NewRestClient(ProductionAPIURL)
client.Auth(key, secret)
req := client.AccountService.NewGetDepositHistoryRequest()
req := client.NewGetDepositHistoryRequest()
req.Currency("usdt")
deposits, err := req.Do(ctx)
assert.NoError(t, err)

View File

@ -21,8 +21,8 @@ func (g *GetAccountRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for k, v := range params {
query.Add(k, fmt.Sprintf("%v", v))
for _k, _v := range params {
query.Add(_k, fmt.Sprintf("%v", _v))
}
return query, nil
@ -44,13 +44,13 @@ func (g *GetAccountRequest) GetParametersQuery() (url.Values, error) {
return query, err
}
for k, v := range params {
if g.isVarSlice(v) {
g.iterateSlice(v, func(it interface{}) {
query.Add(k+"[]", fmt.Sprintf("%v", it))
for _k, _v := range params {
if g.isVarSlice(_v) {
g.iterateSlice(_v, func(it interface{}) {
query.Add(_k+"[]", fmt.Sprintf("%v", it))
})
} else {
query.Add(k, fmt.Sprintf("%v", v))
query.Add(_k, fmt.Sprintf("%v", _v))
}
}
@ -80,24 +80,24 @@ func (g *GetAccountRequest) GetSlugParameters() (map[string]interface{}, error)
}
func (g *GetAccountRequest) applySlugsToUrl(url string, slugs map[string]string) string {
for k, v := range slugs {
needleRE := regexp.MustCompile(":" + k + "\\b")
url = needleRE.ReplaceAllString(url, v)
for _k, _v := range slugs {
needleRE := regexp.MustCompile(":" + _k + "\\b")
url = needleRE.ReplaceAllString(url, _v)
}
return url
}
func (g *GetAccountRequest) iterateSlice(slice interface{}, f func(it interface{})) {
func (g *GetAccountRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
sliceValue := reflect.ValueOf(slice)
for i := 0; i < sliceValue.Len(); i++ {
it := sliceValue.Index(i).Interface()
f(it)
for _i := 0; _i < sliceValue.Len(); _i++ {
it := sliceValue.Index(_i).Interface()
_f(it)
}
}
func (g *GetAccountRequest) isVarSlice(v interface{}) bool {
rt := reflect.TypeOf(v)
func (g *GetAccountRequest) isVarSlice(_v interface{}) bool {
rt := reflect.TypeOf(_v)
switch rt.Kind() {
case reflect.Slice:
return true
@ -112,8 +112,8 @@ func (g *GetAccountRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil
}
for k, v := range params {
slugs[k] = fmt.Sprintf("%v", v)
for _k, _v := range params {
slugs[_k] = fmt.Sprintf("%v", _v)
}
return slugs, nil

View File

@ -16,8 +16,8 @@ func (g *GetAccountsRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for k, v := range params {
query.Add(k, fmt.Sprintf("%v", v))
for _k, _v := range params {
query.Add(_k, fmt.Sprintf("%v", _v))
}
return query, nil
@ -39,13 +39,13 @@ func (g *GetAccountsRequest) GetParametersQuery() (url.Values, error) {
return query, err
}
for k, v := range params {
if g.isVarSlice(v) {
g.iterateSlice(v, func(it interface{}) {
query.Add(k+"[]", fmt.Sprintf("%v", it))
for _k, _v := range params {
if g.isVarSlice(_v) {
g.iterateSlice(_v, func(it interface{}) {
query.Add(_k+"[]", fmt.Sprintf("%v", it))
})
} else {
query.Add(k, fmt.Sprintf("%v", v))
query.Add(_k, fmt.Sprintf("%v", _v))
}
}
@ -70,24 +70,24 @@ func (g *GetAccountsRequest) GetSlugParameters() (map[string]interface{}, error)
}
func (g *GetAccountsRequest) applySlugsToUrl(url string, slugs map[string]string) string {
for k, v := range slugs {
needleRE := regexp.MustCompile(":" + k + "\\b")
url = needleRE.ReplaceAllString(url, v)
for _k, _v := range slugs {
needleRE := regexp.MustCompile(":" + _k + "\\b")
url = needleRE.ReplaceAllString(url, _v)
}
return url
}
func (g *GetAccountsRequest) iterateSlice(slice interface{}, f func(it interface{})) {
func (g *GetAccountsRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
sliceValue := reflect.ValueOf(slice)
for i := 0; i < sliceValue.Len(); i++ {
it := sliceValue.Index(i).Interface()
f(it)
for _i := 0; _i < sliceValue.Len(); _i++ {
it := sliceValue.Index(_i).Interface()
_f(it)
}
}
func (g *GetAccountsRequest) isVarSlice(v interface{}) bool {
rt := reflect.TypeOf(v)
func (g *GetAccountsRequest) isVarSlice(_v interface{}) bool {
rt := reflect.TypeOf(_v)
switch rt.Kind() {
case reflect.Slice:
return true
@ -102,8 +102,8 @@ func (g *GetAccountsRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil
}
for k, v := range params {
slugs[k] = fmt.Sprintf("%v", v)
for _k, _v := range params {
slugs[_k] = fmt.Sprintf("%v", _v)
}
return slugs, nil

View File

@ -9,6 +9,8 @@ import (
"net/url"
"reflect"
"regexp"
"strconv"
"time"
)
func (g *GetDepositHistoryRequest) Currency(currency string) *GetDepositHistoryRequest {
@ -16,12 +18,12 @@ func (g *GetDepositHistoryRequest) Currency(currency string) *GetDepositHistoryR
return g
}
func (g *GetDepositHistoryRequest) From(from int64) *GetDepositHistoryRequest {
func (g *GetDepositHistoryRequest) From(from time.Time) *GetDepositHistoryRequest {
g.from = &from
return g
}
func (g *GetDepositHistoryRequest) To(to int64) *GetDepositHistoryRequest {
func (g *GetDepositHistoryRequest) To(to time.Time) *GetDepositHistoryRequest {
g.to = &to
return g
}
@ -41,8 +43,8 @@ func (g *GetDepositHistoryRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for k, v := range params {
query.Add(k, fmt.Sprintf("%v", v))
for _k, _v := range params {
query.Add(_k, fmt.Sprintf("%v", _v))
}
return query, nil
@ -64,7 +66,8 @@ func (g *GetDepositHistoryRequest) GetParameters() (map[string]interface{}, erro
from := *g.from
// assign parameter of from
params["from"] = from
// convert time.Time to seconds time stamp
params["from"] = strconv.FormatInt(from.Unix(), 10)
} else {
}
// check to field -> json key to
@ -72,7 +75,8 @@ func (g *GetDepositHistoryRequest) GetParameters() (map[string]interface{}, erro
to := *g.to
// assign parameter of to
params["to"] = to
// convert time.Time to seconds time stamp
params["to"] = strconv.FormatInt(to.Unix(), 10)
} else {
}
// check state field -> json key state
@ -104,13 +108,13 @@ func (g *GetDepositHistoryRequest) GetParametersQuery() (url.Values, error) {
return query, err
}
for k, v := range params {
if g.isVarSlice(v) {
g.iterateSlice(v, func(it interface{}) {
query.Add(k+"[]", fmt.Sprintf("%v", it))
for _k, _v := range params {
if g.isVarSlice(_v) {
g.iterateSlice(_v, func(it interface{}) {
query.Add(_k+"[]", fmt.Sprintf("%v", it))
})
} else {
query.Add(k, fmt.Sprintf("%v", v))
query.Add(_k, fmt.Sprintf("%v", _v))
}
}
@ -135,24 +139,24 @@ func (g *GetDepositHistoryRequest) GetSlugParameters() (map[string]interface{},
}
func (g *GetDepositHistoryRequest) applySlugsToUrl(url string, slugs map[string]string) string {
for k, v := range slugs {
needleRE := regexp.MustCompile(":" + k + "\\b")
url = needleRE.ReplaceAllString(url, v)
for _k, _v := range slugs {
needleRE := regexp.MustCompile(":" + _k + "\\b")
url = needleRE.ReplaceAllString(url, _v)
}
return url
}
func (g *GetDepositHistoryRequest) iterateSlice(slice interface{}, f func(it interface{})) {
func (g *GetDepositHistoryRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
sliceValue := reflect.ValueOf(slice)
for i := 0; i < sliceValue.Len(); i++ {
it := sliceValue.Index(i).Interface()
f(it)
for _i := 0; _i < sliceValue.Len(); _i++ {
it := sliceValue.Index(_i).Interface()
_f(it)
}
}
func (g *GetDepositHistoryRequest) isVarSlice(v interface{}) bool {
rt := reflect.TypeOf(v)
func (g *GetDepositHistoryRequest) isVarSlice(_v interface{}) bool {
rt := reflect.TypeOf(_v)
switch rt.Kind() {
case reflect.Slice:
return true
@ -167,8 +171,8 @@ func (g *GetDepositHistoryRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil
}
for k, v := range params {
slugs[k] = fmt.Sprintf("%v", v)
for _k, _v := range params {
slugs[_k] = fmt.Sprintf("%v", _v)
}
return slugs, nil

View File

@ -0,0 +1,18 @@
package max
import (
"github.com/c9s/requestgen"
)
//go:generate -command GetRequest requestgen -method GET
//go:generate -command PostRequest requestgen -method POST
//go:generate -command DeleteRequest requestgen -method DELETE
//go:generate GetRequest -url "/api/v2/markets" -type GetMarketsRequest -responseType []Market
type GetMarketsRequest struct {
client requestgen.APIClient
}
func (c *RestClient) NewGetMarketsRequest() *GetMarketsRequest {
return &GetMarketsRequest{client: c}
}

View File

@ -0,0 +1,135 @@
// Code generated by "requestgen -method GET -url /api/v2/markets -type GetMarketsRequest -responseType []Market"; DO NOT EDIT.
package max
import (
"context"
"encoding/json"
"fmt"
"net/url"
"reflect"
"regexp"
)
// GetQueryParameters builds and checks the query parameters and returns url.Values
func (g *GetMarketsRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for _k, _v := range params {
query.Add(_k, fmt.Sprintf("%v", _v))
}
return query, nil
}
// GetParameters builds and checks the parameters and return the result in a map object
func (g *GetMarketsRequest) GetParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
return params, nil
}
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
func (g *GetMarketsRequest) GetParametersQuery() (url.Values, error) {
query := url.Values{}
params, err := g.GetParameters()
if err != nil {
return query, err
}
for _k, _v := range params {
if g.isVarSlice(_v) {
g.iterateSlice(_v, func(it interface{}) {
query.Add(_k+"[]", fmt.Sprintf("%v", it))
})
} else {
query.Add(_k, fmt.Sprintf("%v", _v))
}
}
return query, nil
}
// GetParametersJSON converts the parameters from GetParameters into the JSON format
func (g *GetMarketsRequest) GetParametersJSON() ([]byte, error) {
params, err := g.GetParameters()
if err != nil {
return nil, err
}
return json.Marshal(params)
}
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
func (g *GetMarketsRequest) GetSlugParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
return params, nil
}
func (g *GetMarketsRequest) applySlugsToUrl(url string, slugs map[string]string) string {
for _k, _v := range slugs {
needleRE := regexp.MustCompile(":" + _k + "\\b")
url = needleRE.ReplaceAllString(url, _v)
}
return url
}
func (g *GetMarketsRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
sliceValue := reflect.ValueOf(slice)
for _i := 0; _i < sliceValue.Len(); _i++ {
it := sliceValue.Index(_i).Interface()
_f(it)
}
}
func (g *GetMarketsRequest) isVarSlice(_v interface{}) bool {
rt := reflect.TypeOf(_v)
switch rt.Kind() {
case reflect.Slice:
return true
}
return false
}
func (g *GetMarketsRequest) GetSlugsMap() (map[string]string, error) {
slugs := map[string]string{}
params, err := g.GetSlugParameters()
if err != nil {
return slugs, nil
}
for _k, _v := range params {
slugs[_k] = fmt.Sprintf("%v", _v)
}
return slugs, nil
}
func (g *GetMarketsRequest) Do(ctx context.Context) ([]Market, error) {
// no body params
var params interface{}
query := url.Values{}
apiURL := "/api/v2/markets"
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
if err != nil {
return nil, err
}
response, err := g.client.SendRequest(req)
if err != nil {
return nil, err
}
var apiResponse []Market
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err
}
return apiResponse, nil
}

View File

@ -0,0 +1,20 @@
package max
import (
"github.com/c9s/requestgen"
)
//go:generate -command GetRequest requestgen -method GET
//go:generate -command PostRequest requestgen -method POST
//go:generate -command DeleteRequest requestgen -method DELETE
//go:generate GetRequest -url "/api/v2/tickers/:market" -type GetTickerRequest -responseType .Ticker
type GetTickerRequest struct {
client requestgen.APIClient
market *string `param:"market,slug"`
}
func (c *RestClient) NewGetTickerRequest() *GetTickerRequest {
return &GetTickerRequest{client: c}
}

View File

@ -0,0 +1,154 @@
// Code generated by "requestgen -method GET -url /api/v2/tickers/:market -type GetTickerRequest -responseType .Ticker"; DO NOT EDIT.
package max
import (
"context"
"encoding/json"
"fmt"
"net/url"
"reflect"
"regexp"
)
func (g *GetTickerRequest) Market(market string) *GetTickerRequest {
g.market = &market
return g
}
// GetQueryParameters builds and checks the query parameters and returns url.Values
func (g *GetTickerRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for _k, _v := range params {
query.Add(_k, fmt.Sprintf("%v", _v))
}
return query, nil
}
// GetParameters builds and checks the parameters and return the result in a map object
func (g *GetTickerRequest) GetParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
return params, nil
}
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
func (g *GetTickerRequest) GetParametersQuery() (url.Values, error) {
query := url.Values{}
params, err := g.GetParameters()
if err != nil {
return query, err
}
for _k, _v := range params {
if g.isVarSlice(_v) {
g.iterateSlice(_v, func(it interface{}) {
query.Add(_k+"[]", fmt.Sprintf("%v", it))
})
} else {
query.Add(_k, fmt.Sprintf("%v", _v))
}
}
return query, nil
}
// GetParametersJSON converts the parameters from GetParameters into the JSON format
func (g *GetTickerRequest) GetParametersJSON() ([]byte, error) {
params, err := g.GetParameters()
if err != nil {
return nil, err
}
return json.Marshal(params)
}
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
func (g *GetTickerRequest) GetSlugParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
// check market field -> json key market
if g.market != nil {
market := *g.market
// assign parameter of market
params["market"] = market
}
return params, nil
}
func (g *GetTickerRequest) applySlugsToUrl(url string, slugs map[string]string) string {
for _k, _v := range slugs {
needleRE := regexp.MustCompile(":" + _k + "\\b")
url = needleRE.ReplaceAllString(url, _v)
}
return url
}
func (g *GetTickerRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
sliceValue := reflect.ValueOf(slice)
for _i := 0; _i < sliceValue.Len(); _i++ {
it := sliceValue.Index(_i).Interface()
_f(it)
}
}
func (g *GetTickerRequest) isVarSlice(_v interface{}) bool {
rt := reflect.TypeOf(_v)
switch rt.Kind() {
case reflect.Slice:
return true
}
return false
}
func (g *GetTickerRequest) GetSlugsMap() (map[string]string, error) {
slugs := map[string]string{}
params, err := g.GetSlugParameters()
if err != nil {
return slugs, nil
}
for _k, _v := range params {
slugs[_k] = fmt.Sprintf("%v", _v)
}
return slugs, nil
}
func (g *GetTickerRequest) Do(ctx context.Context) (*Ticker, error) {
// no body params
var params interface{}
query := url.Values{}
apiURL := "/api/v2/tickers/:market"
slugs, err := g.GetSlugsMap()
if err != nil {
return nil, err
}
apiURL = g.applySlugsToUrl(apiURL, slugs)
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
if err != nil {
return nil, err
}
response, err := g.client.SendRequest(req)
if err != nil {
return nil, err
}
var apiResponse Ticker
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err
}
return &apiResponse, nil
}

View File

@ -0,0 +1,20 @@
package max
import (
"github.com/c9s/requestgen"
)
//go:generate -command GetRequest requestgen -method GET
//go:generate -command PostRequest requestgen -method POST
//go:generate -command DeleteRequest requestgen -method DELETE
type TickerMap map[string]Ticker
//go:generate GetRequest -url "/api/v2/tickers" -type GetTickersRequest -responseType .TickerMap
type GetTickersRequest struct {
client requestgen.APIClient
}
func (c *RestClient) NewGetTickersRequest() *GetTickersRequest {
return &GetTickersRequest{client: c}
}

View File

@ -0,0 +1,135 @@
// Code generated by "requestgen -method GET -url /api/v2/tickers -type GetTickersRequest -responseType .TickerMap"; DO NOT EDIT.
package max
import (
"context"
"encoding/json"
"fmt"
"net/url"
"reflect"
"regexp"
)
// GetQueryParameters builds and checks the query parameters and returns url.Values
func (g *GetTickersRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for _k, _v := range params {
query.Add(_k, fmt.Sprintf("%v", _v))
}
return query, nil
}
// GetParameters builds and checks the parameters and return the result in a map object
func (g *GetTickersRequest) GetParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
return params, nil
}
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
func (g *GetTickersRequest) GetParametersQuery() (url.Values, error) {
query := url.Values{}
params, err := g.GetParameters()
if err != nil {
return query, err
}
for _k, _v := range params {
if g.isVarSlice(_v) {
g.iterateSlice(_v, func(it interface{}) {
query.Add(_k+"[]", fmt.Sprintf("%v", it))
})
} else {
query.Add(_k, fmt.Sprintf("%v", _v))
}
}
return query, nil
}
// GetParametersJSON converts the parameters from GetParameters into the JSON format
func (g *GetTickersRequest) GetParametersJSON() ([]byte, error) {
params, err := g.GetParameters()
if err != nil {
return nil, err
}
return json.Marshal(params)
}
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
func (g *GetTickersRequest) GetSlugParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
return params, nil
}
func (g *GetTickersRequest) applySlugsToUrl(url string, slugs map[string]string) string {
for _k, _v := range slugs {
needleRE := regexp.MustCompile(":" + _k + "\\b")
url = needleRE.ReplaceAllString(url, _v)
}
return url
}
func (g *GetTickersRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
sliceValue := reflect.ValueOf(slice)
for _i := 0; _i < sliceValue.Len(); _i++ {
it := sliceValue.Index(_i).Interface()
_f(it)
}
}
func (g *GetTickersRequest) isVarSlice(_v interface{}) bool {
rt := reflect.TypeOf(_v)
switch rt.Kind() {
case reflect.Slice:
return true
}
return false
}
func (g *GetTickersRequest) GetSlugsMap() (map[string]string, error) {
slugs := map[string]string{}
params, err := g.GetSlugParameters()
if err != nil {
return slugs, nil
}
for _k, _v := range params {
slugs[_k] = fmt.Sprintf("%v", _v)
}
return slugs, nil
}
func (g *GetTickersRequest) Do(ctx context.Context) (TickerMap, error) {
// no body params
var params interface{}
query := url.Values{}
apiURL := "/api/v2/tickers"
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
if err != nil {
return nil, err
}
response, err := g.client.SendRequest(req)
if err != nil {
return nil, err
}
var apiResponse TickerMap
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err
}
return apiResponse, nil
}

View File

@ -0,0 +1,20 @@
package max
import (
"github.com/c9s/requestgen"
)
//go:generate -command GetRequest requestgen -method GET
//go:generate -command PostRequest requestgen -method POST
//go:generate -command DeleteRequest requestgen -method DELETE
type Timestamp int64
//go:generate GetRequest -url "/api/v2/timestamp" -type GetTimestampRequest -responseType .Timestamp
type GetTimestampRequest struct {
client requestgen.APIClient
}
func (c *RestClient) NewGetTimestampRequest() *GetTimestampRequest {
return &GetTimestampRequest{client: c}
}

View File

@ -0,0 +1,135 @@
// Code generated by "requestgen -method GET -url /api/v2/timestamp -type GetTimestampRequest -responseType .Timestamp"; DO NOT EDIT.
package max
import (
"context"
"encoding/json"
"fmt"
"net/url"
"reflect"
"regexp"
)
// GetQueryParameters builds and checks the query parameters and returns url.Values
func (g *GetTimestampRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for _k, _v := range params {
query.Add(_k, fmt.Sprintf("%v", _v))
}
return query, nil
}
// GetParameters builds and checks the parameters and return the result in a map object
func (g *GetTimestampRequest) GetParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
return params, nil
}
// GetParametersQuery converts the parameters from GetParameters into the url.Values format
func (g *GetTimestampRequest) GetParametersQuery() (url.Values, error) {
query := url.Values{}
params, err := g.GetParameters()
if err != nil {
return query, err
}
for _k, _v := range params {
if g.isVarSlice(_v) {
g.iterateSlice(_v, func(it interface{}) {
query.Add(_k+"[]", fmt.Sprintf("%v", it))
})
} else {
query.Add(_k, fmt.Sprintf("%v", _v))
}
}
return query, nil
}
// GetParametersJSON converts the parameters from GetParameters into the JSON format
func (g *GetTimestampRequest) GetParametersJSON() ([]byte, error) {
params, err := g.GetParameters()
if err != nil {
return nil, err
}
return json.Marshal(params)
}
// GetSlugParameters builds and checks the slug parameters and return the result in a map object
func (g *GetTimestampRequest) GetSlugParameters() (map[string]interface{}, error) {
var params = map[string]interface{}{}
return params, nil
}
func (g *GetTimestampRequest) applySlugsToUrl(url string, slugs map[string]string) string {
for _k, _v := range slugs {
needleRE := regexp.MustCompile(":" + _k + "\\b")
url = needleRE.ReplaceAllString(url, _v)
}
return url
}
func (g *GetTimestampRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
sliceValue := reflect.ValueOf(slice)
for _i := 0; _i < sliceValue.Len(); _i++ {
it := sliceValue.Index(_i).Interface()
_f(it)
}
}
func (g *GetTimestampRequest) isVarSlice(_v interface{}) bool {
rt := reflect.TypeOf(_v)
switch rt.Kind() {
case reflect.Slice:
return true
}
return false
}
func (g *GetTimestampRequest) GetSlugsMap() (map[string]string, error) {
slugs := map[string]string{}
params, err := g.GetSlugParameters()
if err != nil {
return slugs, nil
}
for _k, _v := range params {
slugs[_k] = fmt.Sprintf("%v", _v)
}
return slugs, nil
}
func (g *GetTimestampRequest) Do(ctx context.Context) (*Timestamp, error) {
// no body params
var params interface{}
query := url.Values{}
apiURL := "/api/v2/timestamp"
req, err := g.client.NewRequest(ctx, "GET", apiURL, query, params)
if err != nil {
return nil, err
}
response, err := g.client.SendRequest(req)
if err != nil {
return nil, err
}
var apiResponse Timestamp
if err := response.DecodeJSON(&apiResponse); err != nil {
return nil, err
}
return &apiResponse, nil
}

View File

@ -16,8 +16,8 @@ func (g *GetVipLevelRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for k, v := range params {
query.Add(k, fmt.Sprintf("%v", v))
for _k, _v := range params {
query.Add(_k, fmt.Sprintf("%v", _v))
}
return query, nil
@ -39,13 +39,13 @@ func (g *GetVipLevelRequest) GetParametersQuery() (url.Values, error) {
return query, err
}
for k, v := range params {
if g.isVarSlice(v) {
g.iterateSlice(v, func(it interface{}) {
query.Add(k+"[]", fmt.Sprintf("%v", it))
for _k, _v := range params {
if g.isVarSlice(_v) {
g.iterateSlice(_v, func(it interface{}) {
query.Add(_k+"[]", fmt.Sprintf("%v", it))
})
} else {
query.Add(k, fmt.Sprintf("%v", v))
query.Add(_k, fmt.Sprintf("%v", _v))
}
}
@ -70,24 +70,24 @@ func (g *GetVipLevelRequest) GetSlugParameters() (map[string]interface{}, error)
}
func (g *GetVipLevelRequest) applySlugsToUrl(url string, slugs map[string]string) string {
for k, v := range slugs {
needleRE := regexp.MustCompile(":" + k + "\\b")
url = needleRE.ReplaceAllString(url, v)
for _k, _v := range slugs {
needleRE := regexp.MustCompile(":" + _k + "\\b")
url = needleRE.ReplaceAllString(url, _v)
}
return url
}
func (g *GetVipLevelRequest) iterateSlice(slice interface{}, f func(it interface{})) {
func (g *GetVipLevelRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
sliceValue := reflect.ValueOf(slice)
for i := 0; i < sliceValue.Len(); i++ {
it := sliceValue.Index(i).Interface()
f(it)
for _i := 0; _i < sliceValue.Len(); _i++ {
it := sliceValue.Index(_i).Interface()
_f(it)
}
}
func (g *GetVipLevelRequest) isVarSlice(v interface{}) bool {
rt := reflect.TypeOf(v)
func (g *GetVipLevelRequest) isVarSlice(_v interface{}) bool {
rt := reflect.TypeOf(_v)
switch rt.Kind() {
case reflect.Slice:
return true
@ -102,8 +102,8 @@ func (g *GetVipLevelRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil
}
for k, v := range params {
slugs[k] = fmt.Sprintf("%v", v)
for _k, _v := range params {
slugs[_k] = fmt.Sprintf("%v", _v)
}
return slugs, nil

View File

@ -9,6 +9,8 @@ import (
"net/url"
"reflect"
"regexp"
"strconv"
"time"
)
func (g *GetWithdrawHistoryRequest) Currency(currency string) *GetWithdrawHistoryRequest {
@ -16,12 +18,12 @@ func (g *GetWithdrawHistoryRequest) Currency(currency string) *GetWithdrawHistor
return g
}
func (g *GetWithdrawHistoryRequest) From(from int64) *GetWithdrawHistoryRequest {
func (g *GetWithdrawHistoryRequest) From(from time.Time) *GetWithdrawHistoryRequest {
g.from = &from
return g
}
func (g *GetWithdrawHistoryRequest) To(to int64) *GetWithdrawHistoryRequest {
func (g *GetWithdrawHistoryRequest) To(to time.Time) *GetWithdrawHistoryRequest {
g.to = &to
return g
}
@ -41,8 +43,8 @@ func (g *GetWithdrawHistoryRequest) GetQueryParameters() (url.Values, error) {
var params = map[string]interface{}{}
query := url.Values{}
for k, v := range params {
query.Add(k, fmt.Sprintf("%v", v))
for _k, _v := range params {
query.Add(_k, fmt.Sprintf("%v", _v))
}
return query, nil
@ -61,7 +63,8 @@ func (g *GetWithdrawHistoryRequest) GetParameters() (map[string]interface{}, err
from := *g.from
// assign parameter of from
params["from"] = from
// convert time.Time to seconds time stamp
params["from"] = strconv.FormatInt(from.Unix(), 10)
} else {
}
// check to field -> json key to
@ -69,7 +72,8 @@ func (g *GetWithdrawHistoryRequest) GetParameters() (map[string]interface{}, err
to := *g.to
// assign parameter of to
params["to"] = to
// convert time.Time to seconds time stamp
params["to"] = strconv.FormatInt(to.Unix(), 10)
} else {
}
// check state field -> json key state
@ -101,13 +105,13 @@ func (g *GetWithdrawHistoryRequest) GetParametersQuery() (url.Values, error) {
return query, err
}
for k, v := range params {
if g.isVarSlice(v) {
g.iterateSlice(v, func(it interface{}) {
query.Add(k+"[]", fmt.Sprintf("%v", it))
for _k, _v := range params {
if g.isVarSlice(_v) {
g.iterateSlice(_v, func(it interface{}) {
query.Add(_k+"[]", fmt.Sprintf("%v", it))
})
} else {
query.Add(k, fmt.Sprintf("%v", v))
query.Add(_k, fmt.Sprintf("%v", _v))
}
}
@ -132,24 +136,24 @@ func (g *GetWithdrawHistoryRequest) GetSlugParameters() (map[string]interface{},
}
func (g *GetWithdrawHistoryRequest) applySlugsToUrl(url string, slugs map[string]string) string {
for k, v := range slugs {
needleRE := regexp.MustCompile(":" + k + "\\b")
url = needleRE.ReplaceAllString(url, v)
for _k, _v := range slugs {
needleRE := regexp.MustCompile(":" + _k + "\\b")
url = needleRE.ReplaceAllString(url, _v)
}
return url
}
func (g *GetWithdrawHistoryRequest) iterateSlice(slice interface{}, f func(it interface{})) {
func (g *GetWithdrawHistoryRequest) iterateSlice(slice interface{}, _f func(it interface{})) {
sliceValue := reflect.ValueOf(slice)
for i := 0; i < sliceValue.Len(); i++ {
it := sliceValue.Index(i).Interface()
f(it)
for _i := 0; _i < sliceValue.Len(); _i++ {
it := sliceValue.Index(_i).Interface()
_f(it)
}
}
func (g *GetWithdrawHistoryRequest) isVarSlice(v interface{}) bool {
rt := reflect.TypeOf(v)
func (g *GetWithdrawHistoryRequest) isVarSlice(_v interface{}) bool {
rt := reflect.TypeOf(_v)
switch rt.Kind() {
case reflect.Slice:
return true
@ -164,8 +168,8 @@ func (g *GetWithdrawHistoryRequest) GetSlugsMap() (map[string]string, error) {
return slugs, nil
}
for k, v := range params {
slugs[k] = fmt.Sprintf("%v", v)
for _k, _v := range params {
slugs[_k] = fmt.Sprintf("%v", _v)
}
return slugs, nil

View File

@ -3,20 +3,15 @@ package max
import (
"context"
"fmt"
"net/url"
"strings"
"time"
"github.com/c9s/requestgen"
"github.com/pkg/errors"
"github.com/valyala/fastjson"
"github.com/c9s/bbgo/pkg/fixedpoint"
"github.com/c9s/bbgo/pkg/types"
)
type PublicService struct {
client requestgen.AuthenticatedAPIClient
client *RestClient
}
type Market struct {
@ -35,122 +30,46 @@ type Market struct {
type Ticker struct {
Time time.Time
At int64 `json:"at"`
Buy string `json:"buy"`
Sell string `json:"sell"`
Open string `json:"open"`
High string `json:"high"`
Low string `json:"low"`
Last string `json:"last"`
Volume string `json:"vol"`
VolumeInBTC string `json:"vol_in_btc"`
At int64 `json:"at"`
Buy fixedpoint.Value `json:"buy"`
Sell fixedpoint.Value `json:"sell"`
Open fixedpoint.Value `json:"open"`
High fixedpoint.Value `json:"high"`
Low fixedpoint.Value `json:"low"`
Last fixedpoint.Value `json:"last"`
Volume fixedpoint.Value `json:"vol"`
VolumeInBTC fixedpoint.Value `json:"vol_in_btc"`
}
func (s *PublicService) Timestamp() (serverTimestamp int64, err error) {
// sync timestamp with server
req, err := s.client.NewRequest(context.Background(), "GET", "v2/timestamp", nil, nil)
if err != nil {
return 0, err
func (s *PublicService) Timestamp() (int64, error) {
req := s.client.NewGetTimestampRequest()
ts, err := req.Do(context.Background())
if err != nil || ts == nil {
return 0, nil
}
response, err := s.client.SendRequest(req)
if err != nil {
return 0, err
}
err = response.DecodeJSON(&serverTimestamp)
if err != nil {
return 0, err
}
return serverTimestamp, nil
return int64(*ts), nil
}
func (s *PublicService) Markets() ([]Market, error) {
req, err := s.client.NewRequest(context.Background(), "GET", "v2/markets", url.Values{}, nil)
req := s.client.NewGetMarketsRequest()
markets, err := req.Do(context.Background())
if err != nil {
return nil, err
}
response, err := s.client.SendRequest(req)
if err != nil {
return nil, err
}
var m []Market
if err := response.DecodeJSON(&m); err != nil {
return nil, err
}
return m, nil
return markets, nil
}
func (s *PublicService) Tickers() (map[string]Ticker, error) {
var endPoint = "v2/tickers"
req, err := s.client.NewRequest(context.Background(), "GET", endPoint, url.Values{}, nil)
if err != nil {
return nil, err
}
response, err := s.client.SendRequest(req)
if err != nil {
return nil, err
}
v, err := fastjson.ParseBytes(response.Body)
if err != nil {
return nil, err
}
o, err := v.Object()
if err != nil {
return nil, err
}
var tickers = make(map[string]Ticker)
o.Visit(func(key []byte, v *fastjson.Value) {
var ticker = mustParseTicker(v)
tickers[string(key)] = ticker
})
return tickers, nil
func (s *PublicService) Tickers() (TickerMap, error) {
req := s.client.NewGetTickersRequest()
return req.Do(context.Background())
}
func (s *PublicService) Ticker(market string) (*Ticker, error) {
var endPoint = "v2/tickers/" + market
req, err := s.client.NewRequest(context.Background(), "GET", endPoint, url.Values{}, nil)
if err != nil {
return nil, err
}
response, err := s.client.SendRequest(req)
if err != nil {
return nil, err
}
v, err := fastjson.ParseBytes(response.Body)
if err != nil {
return nil, err
}
var ticker = mustParseTicker(v)
return &ticker, nil
}
func mustParseTicker(v *fastjson.Value) Ticker {
var at = v.GetInt64("at")
return Ticker{
Time: time.Unix(at, 0),
At: at,
Buy: string(v.GetStringBytes("buy")),
Sell: string(v.GetStringBytes("sell")),
Volume: string(v.GetStringBytes("vol")),
VolumeInBTC: string(v.GetStringBytes("vol_in_btc")),
Last: string(v.GetStringBytes("last")),
Open: string(v.GetStringBytes("open")),
High: string(v.GetStringBytes("high")),
Low: string(v.GetStringBytes("low")),
}
req := s.client.NewGetTickerRequest()
req.Market(market)
return req.Do(context.Background())
}
type Interval int64
@ -268,51 +187,3 @@ func (s *PublicService) KLines(symbol string, resolution string, start time.Time
return kLines, nil
// return parseKLines(resp.Body, symbol, resolution, interval)
}
func parseKLines(payload []byte, symbol, resolution string, interval Interval) (klines []KLine, err error) {
var parser fastjson.Parser
v, err := parser.ParseBytes(payload)
if err != nil {
return nil, errors.Wrapf(err, "failed to parse payload: %s", payload)
}
arr, err := v.Array()
if err != nil {
return nil, errors.Wrapf(err, "failed to get array: %s", payload)
}
for _, x := range arr {
slice, err := x.Array()
if err != nil {
return nil, errors.Wrapf(err, "failed to get array: %s", payload)
}
if len(slice) < 6 {
return nil, fmt.Errorf("unexpected length of ohlc elements: %s", payload)
}
ts, err := slice[0].Int64()
if err != nil {
return nil, fmt.Errorf("failed to parse timestamp: %s", payload)
}
startTime := time.Unix(ts, 0)
endTime := time.Unix(ts, 0).Add(time.Duration(interval)*time.Minute - time.Millisecond)
isClosed := time.Now().Before(endTime)
klines = append(klines, KLine{
Symbol: symbol,
Interval: resolution,
StartTime: startTime,
EndTime: endTime,
Open: fixedpoint.NewFromFloat(slice[1].GetFloat64()),
High: fixedpoint.NewFromFloat(slice[2].GetFloat64()),
Low: fixedpoint.NewFromFloat(slice[3].GetFloat64()),
Close: fixedpoint.NewFromFloat(slice[4].GetFloat64()),
Volume: fixedpoint.NewFromFloat(slice[5].GetFloat64()),
Closed: isClosed,
})
}
return klines, nil
}

View File

@ -0,0 +1,45 @@
package max
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
)
func TestPublicService(t *testing.T) {
key, secret, ok := integrationTestConfigured(t, "MAX")
if !ok {
t.SkipNow()
}
ctx := context.Background()
client := NewRestClient(ProductionAPIURL)
_ = key
_ = secret
t.Run("v2/timestamp", func(t *testing.T) {
req := client.NewGetTimestampRequest()
serverTimestamp, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotZero(t, serverTimestamp)
})
t.Run("v2/tickers", func(t *testing.T) {
req := client.NewGetTickersRequest()
tickers, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotNil(t, tickers)
assert.NotEmpty(t, tickers)
assert.NotEmpty(t, tickers["btcusdt"])
})
t.Run("v2/ticker/:market", func(t *testing.T) {
req := client.NewGetTickerRequest()
req.Market("btcusdt")
ticker, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotNil(t, ticker)
assert.NotEmpty(t, ticker.Sell)
})
}

View File

@ -18,35 +18,26 @@ func TestRewardService_GetRewardsRequest(t *testing.T) {
client := NewRestClient(ProductionAPIURL)
client.Auth(key, secret)
req := client.RewardService.NewGetRewardsRequest()
rewards, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotNil(t, rewards)
assert.NotEmpty(t, rewards)
t.Run("v2/rewards", func(t *testing.T) {
req := client.RewardService.NewGetRewardsRequest()
rewards, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotNil(t, rewards)
assert.NotEmpty(t, rewards)
t.Logf("rewards: %+v", rewards)
})
t.Logf("rewards: %+v", rewards)
}
func TestRewardService_GetRewardsOfTypeRequest(t *testing.T) {
key, secret, ok := integrationTestConfigured(t, "MAX")
if !ok {
t.SkipNow()
}
ctx := context.Background()
client := NewRestClient(ProductionAPIURL)
client.Auth(key, secret)
req := client.RewardService.NewGetRewardsOfTypeRequest(RewardCommission)
rewards, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotNil(t, rewards)
assert.NotEmpty(t, rewards)
t.Logf("rewards: %+v", rewards)
for _, reward := range rewards {
assert.Equal(t, RewardCommission, reward.Type)
}
t.Run("v2/rewards with type", func(t *testing.T) {
req := client.RewardService.NewGetRewardsOfTypeRequest(RewardCommission)
rewards, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotNil(t, rewards)
assert.NotEmpty(t, rewards)
t.Logf("rewards: %+v", rewards)
for _, reward := range rewards {
assert.Equal(t, RewardCommission, reward.Type)
}
})
}

View File

@ -0,0 +1,27 @@
package max
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
)
func TestWithdrawal(t *testing.T) {
key, secret, ok := integrationTestConfigured(t, "MAX")
if !ok {
t.SkipNow()
}
ctx := context.Background()
client := NewRestClient(ProductionAPIURL)
client.Auth(key, secret)
t.Run("v2/withdrawals", func(t *testing.T) {
req := client.NewGetWithdrawalHistoryRequest()
req.Currency("usdt")
withdrawals, err := req.Do(ctx)
assert.NoError(t, err)
assert.NotEmpty(t, withdrawals)
})
}