mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
* public endpoints methods added * Completing mapping REST endpoints * Binanceus Wrapper methods -Partially * BinaWra functions with test funs; Not Completed * Finalizing wrapper methods & test * Finalizing wrapper methods & test * Fix & Complete wrapper functions * Adding Stream Datas * WS Test functions * CI: Fix golangci-lint linter issues * CI: Fix reverting unnessesary changes and type conversion issues * CI: Fix reverting unnessesary changes and type conversion issues * CI: Fix comment, method use, error handling, and code handling issues * build(deps): bump github.com/urfave/cli/v2 from 2.4.0 to 2.4.8 (#932) Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.4.0 to 2.4.8. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.4.0...v2.4.8) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump google.golang.org/grpc from 1.45.0 to 1.46.0 (#931) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.45.0 to 1.46.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.45.0...v1.46.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * asset: bitmask type optimisation (#922) * asset: basic optim. bitmask * glorious: nits * currency: forgot parralel in testttttt * ticker/orderbook: test fixes * engine/rpcserver: fix and expand tests * test: use `T.TempDir` to create temporary test directory (#934) * test: use `T.TempDir` to create temporary test directory This commit replaces `ioutil.TempDir` with `t.TempDir` in tests. The directory created by `t.TempDir` is automatically removed when the test and all its subtests complete. Prior to this commit, temporary directory created using `ioutil.TempDir` needs to be removed manually by calling `os.RemoveAll`, which is omitted in some tests. The error handling boilerplate e.g. defer func() { if err := os.RemoveAll(dir); err != nil { t.Fatal(err) } } is also tedious, but `t.TempDir` handles this for us nicely. Reference: https://pkg.go.dev/testing#T.TempDir Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * test: fix TestEncryptTwiceReusesSaltButNewCipher on Windows Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * test: fix TestCheckConnection on Windows Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * test: fix TestRPCServer_GetTicker_LastUpdatedNanos on Windows Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * test: cleanup TestGenerateReport Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> * account: storage, processing and method on balances update (#916) * account: update account storage, retrieval and implement alert functionality when a currency change occurs. * account: Add cancel channel * account: remove old code * account: don't embed mutex * Update exchanges/account/account.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Update exchanges/account/account.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Update exchanges/account/account.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * account: addr nits * account: Pull out test into indiv. * account: Add test for update method * account: add no change to test * Update exchanges/account/account.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * account/portfolio: differentiate between asset type segregation and default to spot holdings. * glorious: nits * thrasher: nit * ticker: fix spelling * Update engine/portfolio_manager.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * thrasher: nits Co-authored-by: Scott <gloriousCode@users.noreply.github.com> Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * build(deps): bump github.com/urfave/cli/v2 from 2.4.8 to 2.5.1 (#936) Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.4.8 to 2.5.1. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.4.8...v2.5.1) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * orderbook/buffer: data integrity and resubscription pass (#910) * orderbook/buffer: data integrity and resubscription pass * btcmarkets: REMOVE THAT LIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIINE!!!!!!!!!!!!!!!!! * buffer: reinstate publish, refaactor, invalidate more and comments * buffer/orderbook: improve update and snapshot performance. Move Update type to orderbook package to util. pointer through entire function calls. (cleanup). Change action string to uint8 for easier comparison. Add parsing helper. Update current test benchmark comments. * dispatch: change publish func to variadic id param * dispatch: remove sender receiver wait time as this adds overhead and complexity. update tests. * dispatch: don't create pointers for every job container * rpcserver: fix assertion issues with data publishing change * linter: fixes * glorious: nits addr * depth: change validation handling to incorporate and store err * linter: fix more issues * dispatch: fix race * travis: update before fetching * depth: wrap and return wrapped error in invalidate call and fix tests * btcmarkets: fix commenting * workflow: check * workflow: check * orderbook: check error * buffer/depth: return invalidation error and fix tests * gctcli: display errors on orderbook streams * buffer: remove unused types * orderbook/bitmex: shift function to bitmex * orderbook: Add specific comments to unexported functions that don't have locking require locking. * orderbook: restrict published data functionality to orderbook.Outbound interface * common: add assertion failure helper for error * dispatch: remove atomics, add mutex protection, remove add/remove worker, redo main tests * dispatch: export function * engine: revert and change sub logger to manager * engine: remove old test * dispatch: add common variable ;) * btcmarket: don't overflow int in tests on 32bit systems * ci: force 1.17.7 usage for go * Revert "ci: force 1.17.7 usage for go" This reverts commit af2f95563bf218cf2b9f36a9fcf3258e2c6a2d91. * golangci: bump version add and remove linter items * Revert "golangci: bump version add and remove linter items" This reverts commit 3c98bffc9d030e39faca0387ea40c151df2ab06b. * dispatch: remove unsused mutex from mux * order: slight optimizations * nits: glorious * dispatch: fix regression on uuid generation and input inline with master * linter: fix * linter: fix * glorious: nit - rm slice segration * account: fix test after merge * coinbasepro: revert change * account: close channel instead of needing a receiver, push alert in routine to prepare for waiter. Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> * exchange/wrapper: add GetServerTime() for exchange analytics (#938) * exchange/wrapper: add GetServerTime() for exchange analytics * binance: fix linter issue * glorious: nits * glorious: nits rides again * thrasher: nits implement huobi * thrasher: nits add to exchange_wrapper_issues cmd * order: slight optimizations (#917) * order: slight optimizations * orders: add benchmarks, small optimize and change order side to uin8 for comparitive optimizations. * orders: continue to convert string type -> uint * orders/backtester: interim move type to orders package, later can expand or deprecate. * orders: handle errors * orders: optimize filters and remove error returns when its clearly not needed * orders: remove log call * backtester: zero value check * orders/futures: zero value -> flag * linter: fix * linter: more fixes * linters: rides again * glorious: nits * common: Add zero value unix check for time values; also addresses glorious nits * glorious scott: nits Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> * btcm: add order execution limit wrapper support (#941) * btcm: add in order execution limit fetching * btcm/test: add t.Parrrrrralllleeellllllllll * btcm/wrapper: add update on startup * glorious: nits * thrasher: nit add status field * build(deps): bump github.com/urfave/cli/v2 from 2.5.1 to 2.6.0 (#944) Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.5.1 to 2.6.0. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.5.1...v2.6.0) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * proto/lint: Add protobuf GitHub action and linter (#943) * Buf upgrades * Buf format and basic endpoint fixes * gRPC linter fixes * Amend buf.yaml linter exceptions * Update README * Freshly generated gRPC code after depends update * Nitterinos * ordermanager: fix test error introduced in #917 (#942) * ordermanager: fix residual test issue from #917 and reduce some racey action * glorious: nits; also removed functions that weren't being used and were unexported * rm: pew * linter: fix issues * glourious: nits * credentials: fix test issue with racey racey horse basey * engine: Add websocket data handler register function (#935) * engine: Add websocket interceptor register function * Update engine/engine.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Update engine/websocketroutine_manager_types.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * engine/websock: switch to data handler function register and range over handlers to still include default gct handling * engine/websocket: change name * glorious: nits * linter: fix * glorious: nits Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * btcm: add modify order functionality, change return to pointer (#940) * btcm: add modify order functionality, change return to pointer * glorious: nits * glorious: nits * btcm: Adjust function name * thrasher: nits * thrasher: nits cont... * request: adds WithVerbose function to package to add verbosity to request context (#950) * request: adds WithVerbose function to package to add verbosity to request context * request: add t.Parr.... * thrasher: nits * build(deps): bump google.golang.org/grpc from 1.46.0 to 1.46.2 (#951) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.46.0 to 1.46.2. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.46.0...v1.46.2) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * exchange: expose GetCredentials() and split GetAuthenticatedAPISupport() (#954) * exchange/wrapper: expose GetCredentials func to IBotInterface * exchanges: split up GetAuthenticatedAPISupport into specific function calls, organize IBotExchange functionality getter functions * interface: change name - RPCSercer: rm GetBase func call. * glorious: nits (fix panic) Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> * CI: merge fixes * CI: fixing github generated lint issues * orders: Add method for creating cancel struct from order details (#947) * orders: Add method for creating cancel struct from order details * orders: remove uneeded fields * glorious: nit * grpc: add shutdown call for external management (#957) * grpc: add shutdown call for external management * go mod: tidy * glorious: suggestion * Update engine/engine.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update engine/rpcserver.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update main.go Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> * Update engine/rpcserver.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * build(deps): bump github.com/lib/pq from 1.10.5 to 1.10.6 (#960) Bumps [github.com/lib/pq](https://github.com/lib/pq) from 1.10.5 to 1.10.6. - [Release notes](https://github.com/lib/pq/releases) - [Commits](https://github.com/lib/pq/compare/v1.10.5...v1.10.6) --- updated-dependencies: - dependency-name: github.com/lib/pq dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/urfave/cli/v2 from 2.6.0 to 2.8.0 (#958) Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.6.0 to 2.8.0. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.6.0...v2.8.0) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/grpc-ecosystem/grpc-gateway/v2 (#963) Bumps [github.com/grpc-ecosystem/grpc-gateway/v2](https://github.com/grpc-ecosystem/grpc-gateway) from 2.10.0 to 2.10.2. - [Release notes](https://github.com/grpc-ecosystem/grpc-gateway/releases) - [Changelog](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/.goreleaser.yml) - [Commits](https://github.com/grpc-ecosystem/grpc-gateway/compare/v2.10.0...v2.10.2) --- updated-dependencies: - dependency-name: github.com/grpc-ecosystem/grpc-gateway/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * orders: adds method to retrieve snapshot of order execution limit values (#946) * orders: add method to Limit to retrieve order execution limit snapshots * currency/btcmarkets: add error and update field name to standard * linter: fix * limts: don't return pointer * limit: Add notes * glorious: nits * linter: fix * limit: reinstate nil check * exchanges: change field names to be more consistent (@thrasher-) suggestion Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> * orders: Add derive modify struct method from order.Detail (#948) * orders: Add derive modify struct method to order.Detail and then subsequent method to derive and standardize response details * exchanges: call modify method in wrappers * linter: fixes * engine/wsroutineman: remove print summary * glorious: nits, removed modifyOrder functionality for Bithumb. There are not docs to support this. * Update exchanges/order/orders.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * build(deps): bump github.com/spf13/viper from 1.11.0 to 1.12.0 (#965) Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.11.0 to 1.12.0. - [Release notes](https://github.com/spf13/viper/releases) - [Commits](https://github.com/spf13/viper/compare/v1.11.0...v1.12.0) --- updated-dependencies: - dependency-name: github.com/spf13/viper dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/urfave/cli/v2 from 2.8.0 to 2.8.1 (#964) Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.8.0 to 2.8.1. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.8.0...v2.8.1) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * orders: Add methods to derive SubmitResponse and Detail types (#955) * orders: deprecate SubmitResponse return and change to *order.Detail construct detail from order.Submit struct * orders: add coverage, fix tests * coinut: rm test for checking * orders: revert change for return and change field ID to a more explicit name OrderID * orders: Add method to see if the order was placed * order: change field name in Cancel type to be more explicit * orders: standardize field -> OrderID * backtester: populate change * orders: add test * gctscript: fix field name * linter: fix issues * linter: more fixes * linter: forever * exchanges_tests: populate order.Submit field exchange name * Update exchanges/order/order_types.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Update exchanges/order/orders.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * glorious: nits * thrasher: nits Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * build(deps): bump bufbuild/buf-setup-action from 1.4.0 to 1.5.0 (#973) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.4.0 to 1.5.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.4.0...v1.5.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump google.golang.org/grpc from 1.46.2 to 1.47.0 (#972) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.46.2 to 1.47.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.46.2...v1.47.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/grpc-ecosystem/grpc-gateway/v2 (#971) Bumps [github.com/grpc-ecosystem/grpc-gateway/v2](https://github.com/grpc-ecosystem/grpc-gateway) from 2.10.2 to 2.10.3. - [Release notes](https://github.com/grpc-ecosystem/grpc-gateway/releases) - [Changelog](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/.goreleaser.yml) - [Commits](https://github.com/grpc-ecosystem/grpc-gateway/compare/v2.10.2...v2.10.3) --- updated-dependencies: - dependency-name: github.com/grpc-ecosystem/grpc-gateway/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/d5/tengo/v2 from 2.10.1 to 2.11.2 (#975) Bumps [github.com/d5/tengo/v2](https://github.com/d5/tengo) from 2.10.1 to 2.11.2. - [Release notes](https://github.com/d5/tengo/releases) - [Changelog](https://github.com/d5/tengo/blob/master/.goreleaser.yml) - [Commits](https://github.com/d5/tengo/compare/v2.10.1...v2.11.2) --- updated-dependencies: - dependency-name: github.com/d5/tengo/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/urfave/cli/v2 from 2.8.1 to 2.10.1 (#979) Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.8.1 to 2.10.1. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.8.1...v2.10.1) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/d5/tengo/v2 from 2.11.2 to 2.12.0 (#978) Bumps [github.com/d5/tengo/v2](https://github.com/d5/tengo) from 2.11.2 to 2.12.0. - [Release notes](https://github.com/d5/tengo/releases) - [Changelog](https://github.com/d5/tengo/blob/master/.goreleaser.yml) - [Commits](https://github.com/d5/tengo/compare/v2.11.2...v2.12.0) --- updated-dependencies: - dependency-name: github.com/d5/tengo/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * CI: adding WS and REST tests, and minor fixes * CI: fixes on available asset and related minor issues * CI: fixes on endpoint function, test functions, and types * CI: updating templates and slight fixes * CI: updating slight fixes on tests and withdraws Request model * build(deps): bump styfle/cancel-workflow-action from 0.9.1 to 0.10.0 (#985) Bumps [styfle/cancel-workflow-action](https://github.com/styfle/cancel-workflow-action) from 0.9.1 to 0.10.0. - [Release notes](https://github.com/styfle/cancel-workflow-action/releases) - [Commits](https://github.com/styfle/cancel-workflow-action/compare/0.9.1...0.10.0) --- updated-dependencies: - dependency-name: styfle/cancel-workflow-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump bufbuild/buf-setup-action from 1.5.0 to 1.6.0 (#984) Bumps [bufbuild/buf-setup-action](https://github.com/bufbuild/buf-setup-action) from 1.5.0 to 1.6.0. - [Release notes](https://github.com/bufbuild/buf-setup-action/releases) - [Commits](https://github.com/bufbuild/buf-setup-action/compare/v1.5.0...v1.6.0) --- updated-dependencies: - dependency-name: bufbuild/buf-setup-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * backtester: Futures handling & FTX Cash and Carry example strategy (#930) * implements futures functions and GRPC functions on new branch * lint and test fixes * Fix uneven split pnl. Adds collateral weight test. docs. New clear func * Test protection if someone has zero collateral * Uses string instead of double for accuracy * Fixes old code panic * context, match, docs * Addresses Shazniterinos, var names, expanded tests * Returns subaccount name, provides USD values when offlinecalc * Fixes oopsie * Fixes cool bug which allowed made up subaccount results * Subaccount override on FTX, subaccount results for collateral * Strenghten collateral account info checks. Improve FTX test * English is my first language * Fixes oopsies * Adds some conceptual futures order details to track PNL * Initial design of future order processing in the backtester * Introduces futures concept for collateral and spot/futures config diffs * Fixes most tests * Simple designs for collateral funding pair concept * Expands interface use so much it hurts * Implements more collateral interfaces * Adds liquidation, adds strategy, struggles with Binance * Attempts at getting FTX to work * Adds calculatePNL as a wrapper function and adds an `IsFutures` asset check * Successfully loads backtester with collateral currency * Fails to really get much going for supporting futures * Merges master changes * Fleshes out how FTX processes collateral * Further FTX collateral workings * hooks up more ftx collateral and pnl calculations * more funcs to flesh out handling * Adds more links, just can't fit the pieces together :( * Greatly expands futures order processing * Fleshes out position tracker to also handle asset and exchange +testing * RM linkedOrderID. rn positioncontroller, unexport * Successfully tracks futures order positions * Fails to calculate PNL * Calculates pnl from orders accurately with exception to flipping orders * Calculates PNL from orders * Adds another controller layer to make it ez from orderstore * Backtester now compiles. Adds test coverage * labels things add scaling collateral test * Calculates pnl in line with fees * Mostly accurate PNL, with exception to appending with diff prices * Adds locks, adds rpc function * grpc implementations * Gracefully handles rpc function * beautiful tests! * rejiggles tests to polish * Finishes FTX testing, adds comments * Exposes collateral calculations to rpc * Adds commands and testing for rpcserver.go functions * Increase testing and fix up backtester code * Returns cool changes to original branch * end of day fixes * Fixing some tests * Fixing tests 🎉 * Fixes all the tests * Splits the backtester setup and running into different files * Merge, minor fixes * Messing with some strategy updates * Failed understanding at collateral usage * Begins the creation of cash and carry strategy * Adds underlying pair, adds filldependentevent for futures * Completes fill prerequsite event implementation. Can't short though * Some bug fixes * investigating funds * CAN NOW CREATE A SHORT ORDER * Minor change in short size * Fixes for unrealised PNL & collateral rendering * Fixes lint and tests * Adds some verbosity * Updates to pnl calc * Tracks pnl for short orders, minor update to strategy * Close and open event based on conditions * Adds pnl data for currency statistics * Working through PNL calculation automatically. Now panics * Adds tracking, is blocked from design * Work to flesh out closing a position * vain attempts at tracking zeroing out bugs * woww, super fun new subloggers 🎉 * Begins attempt at automatically handling contracts and collateral based on direction * Merge master + fixes * Investigating issues with pnl and holdings * Minor pnl fixes * Fixes future position sizing, needs contract sizing * Can render pnl results, focussing on funding statistics * tracking candles for futures, but why not btc * Improves funding statistics * Colours and stats * Fixes collateral and snapshot bugs * Completes test * Fixes totals bug * Fix double buy, expand stats, fixes usd totals, introduce interface * Begins report formatting and calculations * Appends pnl to receiving curr. Fixes map[time]. accurate USD * Improves report output rendering * PNL stats in report. New tests for futures * Fixes existing tests before adding new coverage * Test coverage * Completes portfolio coverage * Increase coverage exchange, portfolio. fix size bug. NEW CHART * WHAT IS GOING ON WITH PNL * Fixes PNL calculation. Adds ability to skip om futures tracking * minor commit before merge * Adds basic liquidation to backtester * Changes liquidation to order based * Liquidationnnnnn * Further fleshes out liquidations * Completes liquidations in a honorable manner. Adds AppendReasonf * Beginnings of spot futures gap chart. Needs to link currencies to render difference * Removes fake liquidation. Adds cool new chart * Fixes somet tests,allows for zero fee value v nil distinction,New tests * Some annoying test fixes that took too long * portfolio coverage * holding coverage, privatisation funding * Testwork * boring tests * engine coverage * More backtesting coverage * Funding, strategy, report test coverage * Completes coverage of report package * Documentation, fixes some assumptions on asset errors * Changes before master merge * Lint and Tests * defaults to non-coloured rendering * Chart rendering * Fixes surprise non-local-lints * Niterinos to the extremeos * Fixes merge problems * The linter splintered across the glinting plinths * Many nits addressed. Now sells spot position on final candle * Adds forgotten coverage * Adds ability to size futures contracts to match spot positions. * fixes order sell sizing * Adds tests to sizing. Fixes charting issue * clint splintered the linters with flint * Improves stats, stat rendering * minifix * Fixes tests and fee bug * Merge fixeroos * Microfixes * Updates orderPNL on first Correctly utilises fees. Adds committed funds * New base funcs. New order summary * Fun test updates * Fix logo colouring * Fixes niteroonies * Fix report * BAD COMMIT * Fixes funding issues.Updates default fee rates.Combines cashcarry case * doc regen * Now returns err * Fixes sizing bug issue introduced in PR * Fixes fun fee/total US value bug * Fix chart bug. Show log charts with disclaimer * sellside fee * fixes fee and slippage view * Fixed slippage price issue * Fixes calculation and removes rendering * Fixes stats and some rendering * Merge fix * Fixes merge issues * go mod tidy, lint updates * New linter attempt * Version bump in appveyor and makefile * Regex filename, config fixes, template h2 fixes * Removes bad stats. * neatens config builder. Moves filename generator * Fixes issue where linter wants to fix my spelling * Fixes pointers and starts * build(deps): bump github.com/urfave/cli/v2 from 2.10.1 to 2.10.3 (#982) Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.10.1 to 2.10.3. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.10.1...v2.10.3) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * alert: Add optimizations (#939) * alert: Add optimizations * alert: add basic benchmarks * alert: fix linter issue * documentation: change to text/template as html/template escapes to protect against code injection. Add readme.md for alert. * README: Add package name * alert: link up with engine settings * request: isVerbose refactor * Update exchanges/alert/alert_test.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Update exchanges/alert/alert.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * glorious: fun police * documentation: regen Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * technical_analysis: TWAP & VWAP + TA methods to candles and link to existing RPC server for GCTCLI prototyping (#970) * kline: add weighted price helpers for candles * twap/vwap: basic implementation and hook to rpc for protype * ta: cont implementation. (WIP) * kline: Add tests * kline: add helpers * ta: full impl. * kline: remove support for macd and add in correlation-coefficient handling * rpc: change naming convention * linter: fix * protolinter: fix * linter: ++ * kline: reinstate macd handling after adding in check * glorious: nits * gctcl: linter * Update exchanges/kline/weighted_price.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * glorious: nits v2.0 * kline: fix test * huobi-tests: shift from next quarter to this weeks contracts as they were erroring out in tests. * btcmarkets: update supported kline intervals * zb: fix test * rpcserver: fix bug and tests Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * build(deps): bump github.com/urfave/cli/v2 from 2.10.3 to 2.11.0 (#993) Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.10.3 to 2.11.0. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.10.3...v2.11.0) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * FTX: Margin lending/borrow rate history (#981) * Adds lending rates/borrows to FTX and the command * Movements, renames, rpc test * Fleshing out rpc response * Allows rpcserver to calculate offline (but not gctcli). Expands tests * rn structs. add exchange_wrapper_issues support * Adds a nice yearly rate * Surprise yearly borrow rate! * Rn+Mv to margin package. Fixes some serious whoopsies * Adds average lend/borrow rates instead of sum * rm oopsie whoopsie * This is what the linter was having an issue with * re-gen * lintl * niteroos * build(deps): bump google.golang.org/grpc from 1.47.0 to 1.48.0 (#995) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.47.0 to 1.48.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.47.0...v1.48.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * account: segregate holdings by credentials for future multi-key management (#956) * exchanges/account: shift credentials to account package and segregate funds to keys * merge: fixes * linter: fix * Update exchanges/account/account.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits + protection for string panic * glorious_suggestion: add method for matching keys * linter: fix tests * account: add protected method for credentials minimizing access, display full account details to rpc. * linter: spelling kweeeeeeen * accounts/portfolio: clean/check portfolio code and quickly check balances from change. Add protected method for future matching. * accounts: theres no point in pointerising everything * linter: ok pointerise this then... * exchanges: fix regression add in little notes. * glorious: nits * Update exchanges/account/credentials.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Update exchanges/account/credentials_test.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * Update exchanges/account/credentials_test.go Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * glorious: nits * gloriously: fix glorious glorious test gloriously Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io> Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * CI: fixing linter issue and conflicts * CI: fixing ratelimit and other slight issues * build(deps): bump github.com/grpc-ecosystem/grpc-gateway/v2 (#998) Bumps [github.com/grpc-ecosystem/grpc-gateway/v2](https://github.com/grpc-ecosystem/grpc-gateway) from 2.10.3 to 2.11.0. - [Release notes](https://github.com/grpc-ecosystem/grpc-gateway/releases) - [Changelog](https://github.com/grpc-ecosystem/grpc-gateway/blob/master/.goreleaser.yml) - [Commits](https://github.com/grpc-ecosystem/grpc-gateway/compare/v2.10.3...v2.11.0) --- updated-dependencies: - dependency-name: github.com/grpc-ecosystem/grpc-gateway/v2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/d5/tengo/v2 from 2.12.0 to 2.12.1 (#997) Bumps [github.com/d5/tengo/v2](https://github.com/d5/tengo) from 2.12.0 to 2.12.1. - [Release notes](https://github.com/d5/tengo/releases) - [Changelog](https://github.com/d5/tengo/blob/master/.goreleaser.yml) - [Commits](https://github.com/d5/tengo/compare/v2.12.0...v2.12.1) --- updated-dependencies: - dependency-name: github.com/d5/tengo/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump github.com/urfave/cli/v2 from 2.11.0 to 2.11.1 (#996) Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.11.0 to 2.11.1. - [Release notes](https://github.com/urfave/cli/releases) - [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md) - [Commits](https://github.com/urfave/cli/compare/v2.11.0...v2.11.1) --- updated-dependencies: - dependency-name: github.com/urfave/cli/v2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * CI: fixing type and other slight issues * Cleanup after merge * Endpoints rate limit update Signed-off-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ryan O'Hara-Reid <oharareid.ryan@gmail.com> Co-authored-by: Eng Zer Jun <engzerjun@gmail.com> Co-authored-by: Scott <gloriousCode@users.noreply.github.com> Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> Co-authored-by: Ryan O'Hara-Reid <ryan.oharareid@thrasher.io>
1944 lines
58 KiB
Go
1944 lines
58 KiB
Go
package binanceus
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"log"
|
|
"os"
|
|
reflects "reflect"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
"github.com/thrasher-corp/gocryptotrader/config"
|
|
"github.com/thrasher-corp/gocryptotrader/core"
|
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
|
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
|
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
|
|
)
|
|
|
|
// Please supply your own keys here to test authenticated endpoints
|
|
const (
|
|
apiKey = ""
|
|
apiSecret = ""
|
|
canManipulateRealOrders = false
|
|
)
|
|
|
|
var (
|
|
bi Binanceus
|
|
testPairMapping = currency.NewPair(currency.BTC, currency.USDT)
|
|
// this lock guards against orderbook tests race
|
|
binanceusOrderBookLock = &sync.Mutex{}
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
cfg := config.GetConfig()
|
|
err := cfg.LoadConfig("../../testdata/configtest.json", true)
|
|
if err != nil {
|
|
log.Fatal("Binanceus load config error", err)
|
|
}
|
|
|
|
exchCfg, err := cfg.GetExchangeConfig("Binanceus")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
exchCfg.API.AuthenticatedSupport = true
|
|
exchCfg.API.AuthenticatedWebsocketSupport = true
|
|
exchCfg.API.Credentials.Key = apiKey
|
|
exchCfg.API.Credentials.Secret = apiSecret
|
|
bi.SetDefaults()
|
|
bi.Websocket = sharedtestvalues.NewTestWebsocket()
|
|
bi.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
|
|
err = bi.Setup(exchCfg)
|
|
if err != nil {
|
|
log.Fatal("Binanceus TestMain()", err)
|
|
}
|
|
bi.setupOrderbookManager()
|
|
err = bi.Start(nil)
|
|
if !errors.Is(err, common.ErrNilPointer) {
|
|
log.Fatalf("%s received: '%v' but expected: '%v'", bi.Name, err, common.ErrNilPointer)
|
|
}
|
|
var testWg sync.WaitGroup
|
|
err = bi.Start(&testWg)
|
|
if err != nil {
|
|
log.Fatal("Binanceus Starting error ", err)
|
|
}
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
func areTestAPIKeysSet() bool {
|
|
return bi.ValidateAPICredentials(bi.GetDefaultCredentials()) == nil
|
|
}
|
|
|
|
func TestServerTime(t *testing.T) {
|
|
t.Parallel()
|
|
if _, er := bi.GetServerTime(context.Background(), asset.Spot); er != nil {
|
|
t.Error("Binanceus SystemTime() error", er)
|
|
}
|
|
}
|
|
|
|
func TestServerStatus(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetSystemStatus(context.Background()); er != nil {
|
|
t.Error("Binanceus GetSystemStatus() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetExchangeInfo(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := bi.GetExchangeInfo(context.Background())
|
|
if err != nil {
|
|
t.Error("Binanceus GetExchangeInfo() error", err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateTicker(t *testing.T) {
|
|
t.Parallel()
|
|
r, err := bi.UpdateTicker(context.Background(), testPairMapping, asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if r.Pair.Base != currency.BTC && r.Pair.Quote != currency.USDT {
|
|
t.Error("Binanceus UpdateTicker() invalid pair values")
|
|
}
|
|
}
|
|
|
|
func TestUpdateTickers(t *testing.T) {
|
|
t.Parallel()
|
|
err := bi.UpdateTickers(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateOrderBook(t *testing.T) {
|
|
t.Parallel()
|
|
_, er := bi.UpdateOrderbook(context.Background(), testPairMapping, asset.Spot)
|
|
if er != nil {
|
|
t.Error("Binanceus UpdateOrderBook() error", er)
|
|
}
|
|
}
|
|
|
|
func TestFetchTradablePairs(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, err := bi.FetchTradablePairs(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error("Binanceus FetchTradablePairs() error", err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateTradablePairs(t *testing.T) {
|
|
t.Parallel()
|
|
err := bi.UpdateTradablePairs(context.Background(), false)
|
|
if err != nil {
|
|
t.Error("Binanceus UpdateTradablePairs() error", err)
|
|
}
|
|
}
|
|
|
|
func TestFetchAccountInfo(t *testing.T) {
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
t.Parallel()
|
|
if _, err := bi.FetchAccountInfo(context.Background(), asset.Spot); err != nil {
|
|
t.Error("Binanceus FetchAccountInfo() error", err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateAccountInfo(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, err := bi.UpdateAccountInfo(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error("Binanceus UpdateAccountInfo() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetRecentTrades(t *testing.T) {
|
|
t.Parallel()
|
|
pair := currency.Pair{Base: currency.BTC, Quote: currency.USD}
|
|
_, err := bi.GetRecentTrades(context.Background(), pair, asset.Spot)
|
|
if err != nil {
|
|
t.Error("Binanceus GetRecentTrades() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricTrades(t *testing.T) {
|
|
t.Parallel()
|
|
pair := currency.Pair{Base: currency.BTC, Quote: currency.USD}
|
|
_, err := bi.GetHistoricTrades(context.Background(), pair, asset.Spot, time.Time{}, time.Time{})
|
|
if err != nil {
|
|
t.Error("Binanceus GetHistoricTrades() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFeeByType(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetFeeByType(context.Background(), &exchange.FeeBuilder{
|
|
IsMaker: true,
|
|
Pair: currency.NewPair(currency.USD, currency.BTC),
|
|
FeeType: exchange.CryptocurrencyTradeFee,
|
|
}); er != nil {
|
|
t.Error("Binanceus GetFeeByType() error", er)
|
|
}
|
|
if _, er := bi.GetFeeByType(context.Background(), &exchange.FeeBuilder{
|
|
IsMaker: true,
|
|
Pair: currency.NewPair(currency.USD, currency.BTC),
|
|
FeeType: exchange.CryptocurrencyWithdrawalFee,
|
|
}); er != nil {
|
|
t.Error("Binanceus GetFeeByType() error", er)
|
|
}
|
|
}
|
|
|
|
func TestSubmitOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip(bi.Name, "API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
var orderSubmission = &order.Submit{
|
|
Pair: currency.Pair{
|
|
Base: currency.XRP,
|
|
Quote: currency.USD,
|
|
},
|
|
AssetType: asset.Spot,
|
|
Side: order.Sell,
|
|
Type: order.Limit,
|
|
Price: 1000,
|
|
Amount: 20,
|
|
ClientID: "binanceSamOrder",
|
|
Exchange: bi.Name,
|
|
}
|
|
response, err := bi.SubmitOrder(context.Background(), orderSubmission)
|
|
switch {
|
|
case areTestAPIKeysSet() && err != nil && strings.Contains(err.Error(), "{\"code\":-1013,\"msg\":\"Market is closed.\""):
|
|
t.Skip("Binanceus SubmitOrder() Market is Closed")
|
|
case areTestAPIKeysSet() && err != nil:
|
|
t.Errorf("Binanceus SubmitOrder() Could not place order: %v", err)
|
|
case areTestAPIKeysSet() && response.Status != order.Filled:
|
|
t.Error("Binanceus SubmitOrder() Order not placed")
|
|
case !areTestAPIKeysSet() && err == nil:
|
|
t.Error("Binanceus SubmitOrder() Expecting an error when no keys are set")
|
|
}
|
|
}
|
|
|
|
func TestCancelOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
pair := currency.NewPair(currency.BTC, currency.USD)
|
|
err := bi.CancelOrder(context.Background(), &order.Cancel{
|
|
AssetType: asset.Spot,
|
|
OrderID: "1337",
|
|
})
|
|
if err != nil && !errors.Is(err, errMissingCurrencySymbol) {
|
|
t.Error("Binanceus CancelOrder() error", err)
|
|
}
|
|
err = bi.CancelOrder(context.Background(), &order.Cancel{
|
|
AssetType: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
|
})
|
|
if err != nil && !(errors.Is(err, errEitherOrderIDOrClientOrderIDIsRequired) || strings.Contains(err.Error(), "ID not set")) {
|
|
t.Errorf("Binanceus CancelOrder() expecting %v, but found %v", errEitherOrderIDOrClientOrderIDIsRequired, err)
|
|
}
|
|
var cancellationOrder = &order.Cancel{
|
|
OrderID: "1",
|
|
Pair: pair,
|
|
AssetType: asset.Spot,
|
|
}
|
|
err = bi.CancelOrder(context.Background(), cancellationOrder)
|
|
if err != nil && !strings.Contains(err.Error(), "Unknown order sent.") {
|
|
t.Error("Binanceus CancelOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllOrders(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip("Binanceus API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
var orderCancellation = &order.Cancel{
|
|
Pair: currency.NewPair(currency.LTC, currency.BTC),
|
|
AssetType: asset.Spot,
|
|
}
|
|
if _, err := bi.CancelAllOrders(context.Background(), orderCancellation); err != nil {
|
|
t.Error("Binanceus CancelAllOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderInfo(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.Skip("Binanceus GetOrderInfo() skipping test: api keys not set")
|
|
}
|
|
tradablePairs, err := bi.FetchTradablePairs(context.Background(),
|
|
asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if len(tradablePairs) == 0 {
|
|
t.Fatal("Binanceus GetOrderInfo() no tradable pairs")
|
|
}
|
|
cp, err := currency.NewPairFromString(tradablePairs[0])
|
|
if err != nil {
|
|
t.Error("Binanceus GetOrderInfo() error", err)
|
|
}
|
|
_, err = bi.GetOrderInfo(context.Background(),
|
|
"123", cp, asset.Spot)
|
|
if !strings.Contains(err.Error(), "Order does not exist.") {
|
|
t.Error("Binanceus GetOrderInfo() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetDepositAddress(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, err := bi.GetDepositAddress(context.Background(), currency.EMPTYCODE, "", currency.BNB.String())
|
|
if err != nil && !errors.Is(err, errMissingRequiredArgumentCoin) {
|
|
t.Errorf("Binanceus GetDepositAddress() expecting %v, but found %v", errMissingRequiredArgumentCoin, err)
|
|
}
|
|
if _, err := bi.GetDepositAddress(context.Background(), currency.USDT, "", currency.BNB.String()); err != nil {
|
|
t.Error("Binanceus GetDepositAddress() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetWithdrawalHistory(t *testing.T) {
|
|
t.Parallel()
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip("Binanceus API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
_, err := bi.GetWithdrawalsHistory(context.Background(), currency.ETH, asset.Spot)
|
|
switch {
|
|
case areTestAPIKeysSet() && err != nil:
|
|
t.Error("Binanceus GetWithdrawalsHistory() error", err)
|
|
case !areTestAPIKeysSet() && err == nil:
|
|
t.Error("Binanceus GetWithdrawalsHistory() expecting an error when no keys are set")
|
|
}
|
|
}
|
|
|
|
func TestWithdrawFiat(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.WithdrawFiat(context.Background(), &WithdrawFiatRequestParams{
|
|
PaymentChannel: "SILVERGATE",
|
|
PaymentAccount: "myaccount",
|
|
PaymentMethod: "SEN",
|
|
Amount: 1,
|
|
}); er != nil && !strings.Contains(er.Error(), "You are not authorized to execute this request.") {
|
|
t.Error("Binanceus WithdrawFiat() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetActiveOrders(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
var getOrdersRequest = order.GetOrdersRequest{
|
|
Type: order.AnyType,
|
|
AssetType: asset.Spot,
|
|
}
|
|
_, err := bi.GetActiveOrders(context.Background(), &getOrdersRequest)
|
|
if err != nil {
|
|
t.Error("Binanceus GetActiveOrders() error", err)
|
|
}
|
|
}
|
|
|
|
func TestWithdraw(t *testing.T) {
|
|
t.Parallel()
|
|
if !(areTestAPIKeysSet() && canManipulateRealOrders) {
|
|
t.Skip("Binanceus API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
withdrawCryptoRequest := withdraw.Request{
|
|
Exchange: bi.Name,
|
|
Amount: -1,
|
|
Currency: currency.BTC,
|
|
Description: "WITHDRAW IT ALL",
|
|
Crypto: withdraw.CryptoRequest{
|
|
Address: core.BitcoinDonationAddress,
|
|
Chain: "BSC",
|
|
},
|
|
}
|
|
_, err := bi.WithdrawCryptocurrencyFunds(context.Background(), &withdrawCryptoRequest)
|
|
if err != nil && !strings.EqualFold(errAmountValueMustBeGreaterThan0.Error(), err.Error()) {
|
|
t.Errorf("Binanceus Withdraw() expecting %v, but found %v", errAmountValueMustBeGreaterThan0, err)
|
|
} else if !areTestAPIKeysSet() && err == nil {
|
|
t.Error("Binanceus Withdraw() expecting an error when no keys are set")
|
|
}
|
|
withdrawCryptoRequest.Amount = 1
|
|
_, err = bi.WithdrawCryptocurrencyFunds(context.Background(), &withdrawCryptoRequest)
|
|
if err != nil && !strings.Contains(err.Error(), "You are not authorized to execute this request.") {
|
|
t.Error("Binanceus WithdrawCryptocurrencyFunds() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetFee(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
var feeBuilder = &exchange.FeeBuilder{
|
|
Amount: 1,
|
|
FeeType: exchange.CryptocurrencyTradeFee,
|
|
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
|
PurchasePrice: 1,
|
|
}
|
|
_, er := bi.GetFeeByType(context.Background(), feeBuilder)
|
|
if er != nil {
|
|
t.Fatal("Binanceus GetFeeByType() error", er)
|
|
}
|
|
var withdrawalFeeBuilder = &exchange.FeeBuilder{
|
|
Amount: 1,
|
|
FeeType: exchange.CryptocurrencyWithdrawalFee,
|
|
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
|
PurchasePrice: 1,
|
|
}
|
|
_, er = bi.GetFeeByType(context.Background(), withdrawalFeeBuilder)
|
|
if er != nil {
|
|
t.Fatal("Binanceus GetFeeByType() error", er)
|
|
}
|
|
var offlineFeeTradeBuilder = &exchange.FeeBuilder{
|
|
Amount: 1,
|
|
FeeType: exchange.OfflineTradeFee,
|
|
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
|
PurchasePrice: 1,
|
|
}
|
|
_, er = bi.GetFeeByType(context.Background(), offlineFeeTradeBuilder)
|
|
if er != nil {
|
|
t.Fatal("Binanceus GetFeeByType() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricCandles(t *testing.T) {
|
|
t.Parallel()
|
|
pair := currency.NewPair(currency.BTC, currency.USDT)
|
|
startTime := time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC)
|
|
endTime := time.Date(2021, 2, 15, 0, 0, 0, 0, time.UTC)
|
|
_, er := bi.GetHistoricCandles(context.Background(), pair, asset.Spot, startTime, endTime, kline.Interval(time.Hour*5))
|
|
if !strings.Contains(er.Error(), "interval not supported") {
|
|
t.Errorf("Binanceus GetHistoricCandles() expected %s, but found %v", "interval not supported", er)
|
|
}
|
|
_, er = bi.GetHistoricCandles(context.Background(), pair, asset.Spot, time.Time{}, time.Time{}, kline.FourHour)
|
|
if er != nil {
|
|
t.Error("Binanceus GetHistoricCandles() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricCandlesExtended(t *testing.T) {
|
|
t.Parallel()
|
|
pair := currency.NewPair(currency.BTC, currency.USDT)
|
|
startTime := time.Date(2020, 9, 1, 0, 0, 0, 0, time.UTC)
|
|
endTime := time.Date(2021, 2, 15, 0, 0, 0, 0, time.UTC)
|
|
_, er := bi.GetHistoricCandlesExtended(context.Background(), pair, asset.Spot, startTime, endTime, kline.FourHour)
|
|
if er != nil && !strings.Contains(er.Error(), "interval not supported") {
|
|
t.Errorf("Binanceus GetHistoricCandlesExtended() expected %s, but found %v", "interval not supported", er)
|
|
}
|
|
startTime = time.Now().Add(-time.Hour * 30)
|
|
endTime = time.Now()
|
|
_, er = bi.GetHistoricCandlesExtended(context.Background(), pair, asset.Spot, startTime, endTime, kline.FourHour)
|
|
if er != nil {
|
|
t.Error("Binanceus GetHistoricCandlesExtended() error", er)
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
|
|
// TestGetMostRecentTrades -- test most recent trades end-point
|
|
func TestGetMostRecentTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := bi.GetMostRecentTrades(context.Background(), RecentTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Limit: 15,
|
|
})
|
|
if err != nil {
|
|
t.Error("Binanceus GetMostRecentTrades() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricalTrades(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, err := bi.GetHistoricalTrades(context.Background(), HistoricalTradeParams{
|
|
Symbol: "BTCUSDT",
|
|
Limit: 5,
|
|
FromID: 0,
|
|
})
|
|
if err != nil {
|
|
t.Errorf("Binanceus GetHistoricalTrades() error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAggregateTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := bi.GetAggregateTrades(context.Background(),
|
|
&AggregatedTradeRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Limit: 5,
|
|
})
|
|
if err != nil {
|
|
t.Error("Binanceus GetAggregateTrades() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderBookDepth(t *testing.T) {
|
|
t.Parallel()
|
|
_, er := bi.GetOrderBookDepth(context.Background(), &OrderBookDataRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Limit: 1000,
|
|
})
|
|
if er != nil {
|
|
t.Error("Binanceus GetOrderBook() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetCandlestickData(t *testing.T) {
|
|
t.Parallel()
|
|
_, er := bi.GetSpotKline(context.Background(), &KlinesRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
Interval: kline.FiveMin.Short(),
|
|
Limit: 24,
|
|
StartTime: time.Unix(1577836800, 0),
|
|
EndTime: time.Unix(1580515200, 0),
|
|
})
|
|
if er != nil {
|
|
t.Error("Binanceus GetSpotKline() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetPriceDatas(t *testing.T) {
|
|
t.Parallel()
|
|
_, er := bi.GetPriceDatas(context.Background())
|
|
if er != nil {
|
|
t.Error("Binanceus GetPriceDatas() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetSinglePriceData(t *testing.T) {
|
|
t.Parallel()
|
|
_, er := bi.GetSinglePriceData(context.Background(), currency.Pair{
|
|
Base: currency.BTC,
|
|
Quote: currency.USDT,
|
|
})
|
|
if er != nil {
|
|
t.Error("Binanceus GetSinglePriceData() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetAveragePrice(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := bi.GetAveragePrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error("Binance GetAveragePrice() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetBestPrice(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := bi.GetBestPrice(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error("Binanceus GetBestPrice() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetPriceChangeStats(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := bi.GetPriceChangeStats(context.Background(), currency.NewPair(currency.BTC, currency.USDT))
|
|
if err != nil {
|
|
t.Error("Binance GetPriceChangeStats() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetTickers(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := bi.GetTickers(context.Background())
|
|
if err != nil {
|
|
t.Error("Binance TestGetTickers error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAccount(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetAccount(context.Background())
|
|
if er != nil {
|
|
t.Error("Binanceus GetAccount() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetUserAccountStatus(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetUserAccountStatus(context.Background(), 3000)
|
|
if er != nil {
|
|
t.Error("Binanceus GetUserAccountStatus() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetUserAPITradingStatus(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetUserAPITradingStatus(context.Background(), 3000)
|
|
if er != nil {
|
|
t.Error("Binanceus GetUserAPITradingStatus() error", er)
|
|
}
|
|
}
|
|
func TestGetTradeFee(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetTradeFee(context.Background(), 3000, "BTC-USDT")
|
|
if er != nil {
|
|
t.Error("Binanceus GetTradeFee() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetAssetDistributionHistory(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetAssetDistributionHistory(context.Background(), "", 0, 0, 3000)
|
|
if er != nil {
|
|
t.Error("Binanceus GetAssetDistributionHistory() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetMasterAccountTotalUSDValue(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetMasterAccountTotalUSDValue(context.Background(), "", 0, 0); er != nil && !strings.Contains(er.Error(), "Sub-account function is not enabled.") {
|
|
t.Errorf("Binanceus GetMasterAccountTotalUSDValue() expecting %s, but found %v", "Sub-account function is not enabled.", er)
|
|
}
|
|
}
|
|
|
|
func TestGetSubaccountStatusList(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetSubaccountStatusList(context.Background(), ""); er != nil && !errors.Is(er, errMissingSubAccountEmail) {
|
|
t.Errorf("Binanceus GetSubaccountStatusList() expecting %v, but found %v", errMissingSubAccountEmail, er)
|
|
}
|
|
if _, er := bi.GetSubaccountStatusList(context.Background(), "someone@thrasher.corp"); er != nil && !strings.Contains(er.Error(), "Sub-account function is not enabled.") {
|
|
t.Errorf("Binanceus GetSubaccountStatusList() expecting %s, but found %v", "Sub-account function is not enabled.", er)
|
|
}
|
|
}
|
|
|
|
func TestGetSubAccountDepositAddress(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetSubAccountDepositAddress(context.Background(), SubAccountDepositAddressRequestParams{}); er != nil && !errors.Is(er, errMissingSubAccountEmail) {
|
|
t.Errorf("Binanceus GetSubAccountDepositAddress() %v, but found %v", errMissingSubAccountEmail, er)
|
|
}
|
|
if _, er := bi.GetSubAccountDepositAddress(context.Background(), SubAccountDepositAddressRequestParams{
|
|
Email: "someone@thrasher.io",
|
|
}); er != nil && !errors.Is(er, errMissingCurrencyCoin) {
|
|
t.Errorf("Binanceus GetSubAccountDepositAddress() %v, but found %v", errMissingCurrencyCoin, er)
|
|
}
|
|
if _, er := bi.GetSubAccountDepositAddress(context.Background(), SubAccountDepositAddressRequestParams{
|
|
Email: "someone@thrasher.io",
|
|
Coin: currency.BTC,
|
|
}); er != nil && !strings.Contains(er.Error(), "This parent sub have no relation") {
|
|
t.Errorf("Binanceus GetSubAccountDepositAddress() %v, but found %v", errMissingCurrencyCoin, er)
|
|
}
|
|
}
|
|
|
|
var subAccountDepositHistoryItemJSON = `{
|
|
"amount": "9.9749",
|
|
"coin": "BTC",
|
|
"network": "btc",
|
|
"status": 4,
|
|
"address": "bc1qxurvdd7tzn09agdvg3j8xpm3f7e978y07wg83s",
|
|
"addressTag": "",
|
|
"txId": "0x1b4b8c8090d15e3c1b0476b1c19118b1f00066e01de567cd7bc5b6e9c100193f",
|
|
"insertTime": 1652942429211,
|
|
"transferType": 0,
|
|
"confirmTimes": "0/0"
|
|
}`
|
|
|
|
func TestGetSubAccountDepositHistory(t *testing.T) {
|
|
t.Parallel()
|
|
var resp SubAccountDepositItem
|
|
if er := json.Unmarshal([]byte(subAccountDepositHistoryItemJSON), &resp); er != nil {
|
|
t.Error("Binanceus Decerializing to SubAccountDepositItem error", er)
|
|
}
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetSubAccountDepositHistory(context.Background(), "", currency.BTC, 1, time.Time{}, time.Time{}, 0, 0); er != nil && !errors.Is(er, errMissingSubAccountEmail) {
|
|
t.Errorf("Binanceus GetSubAccountDepositHistory() expecting %v, but found %v", errMissingSubAccountEmail, er)
|
|
}
|
|
if _, er := bi.GetSubAccountDepositHistory(context.Background(), "someone@thrasher.io", currency.BTC, 1, time.Time{}, time.Time{}, 0, 0); er != nil && !strings.Contains(er.Error(), "This parent sub have no relation") {
|
|
t.Errorf("Binanceus GetSubAccountDepositHistory() expecting %s, but found %v", "This parent sub have no relation", er)
|
|
}
|
|
}
|
|
|
|
var subaccountItemJSON = `{
|
|
"email": "123@test.com",
|
|
"status": "enabled",
|
|
"activated": true,
|
|
"mobile": "91605290",
|
|
"gAuth": true,
|
|
"createTime": 1544433328000
|
|
}`
|
|
|
|
func TestGetSubaccountInformation(t *testing.T) {
|
|
t.Parallel()
|
|
var resp SubAccount
|
|
if er := json.Unmarshal([]byte(subaccountItemJSON), &resp); er != nil {
|
|
t.Error("Binanceus decerializing to SubAccount error", er)
|
|
}
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetSubaccountInformation(context.Background(), 1, 100, "", "")
|
|
if er != nil && !strings.Contains(er.Error(), "Sub-account function is not enabled.") {
|
|
t.Error("Binanceus GetSubaccountInformation() error", er)
|
|
}
|
|
}
|
|
|
|
var referalRewardHistoryResponse = `{
|
|
"total": 1,
|
|
"rows": [
|
|
{
|
|
"userId": 350991652,
|
|
"rewardAmount": "8",
|
|
"receiveDateTime": 1651131084091,
|
|
"rewardType": "USD"
|
|
}
|
|
]
|
|
}`
|
|
|
|
func TestGetReferralRewardHistory(t *testing.T) {
|
|
t.Parallel()
|
|
var resp ReferralRewardHistoryResponse
|
|
if er := json.Unmarshal([]byte(referalRewardHistoryResponse), &resp); er != nil {
|
|
t.Error("Binanceus decerializing to ReferalRewardHistoryResponse error", er)
|
|
}
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetReferralRewardHistory(context.Background(), 9, 5, 50); !errors.Is(er, errInvalidUserBusinessType) {
|
|
t.Errorf("Binanceus GetReferralRewardHistory() expecting %v, but found %v", errInvalidUserBusinessType, er)
|
|
}
|
|
if _, er := bi.GetReferralRewardHistory(context.Background(), 1, 0, 50); !errors.Is(er, errMissingPageNumber) {
|
|
t.Errorf("Binanceus GetReferralRewardHistory() expecting %v, but found %v", errMissingPageNumber, er)
|
|
}
|
|
if _, er := bi.GetReferralRewardHistory(context.Background(), 1, 5, 0); !errors.Is(er, errInvalidRowNumber) {
|
|
t.Errorf("Binanceus GetReferralRewardHistory() expecting %v, but found %v", errInvalidRowNumber, er)
|
|
}
|
|
if _, er := bi.GetReferralRewardHistory(context.Background(), 1, 5, 50); er != nil {
|
|
t.Error("Binanceus GetReferralRewardHistory() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetSubaccountTransferHistory(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetSubaccountTransferHistory(context.Background(), "", 0, 0, 0, 0)
|
|
if !errors.Is(er, errNotValidEmailAddress) {
|
|
t.Errorf("Binanceus GetSubaccountTransferHistory() expected %v, but received: %s", errNotValidEmailAddress, er)
|
|
}
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.Skip("Binanceus GetSubaccountTransferHistory() skipping test, either api keys or canManipulateRealOrders isn't set")
|
|
}
|
|
_, er = bi.GetSubaccountTransferHistory(context.Background(), "example@golang.org", 0, 0, 0, 0)
|
|
if er != nil && !(errors.Is(er, errNotValidEmailAddress) || strings.Contains(er.Error(), "Sub-account function is not enabled.")) {
|
|
t.Fatalf("Binanceus GetSubaccountTransferHistory() error %v", er)
|
|
}
|
|
}
|
|
|
|
func TestExecuteSubAccountTransfer(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.ExecuteSubAccountTransfer(context.Background(), &SubAccountTransferRequestParams{})
|
|
if !errors.Is(er, errUnacceptableSenderEmail) {
|
|
t.Errorf("binanceus error: expected %v, but found %v", errUnacceptableSenderEmail, er)
|
|
}
|
|
_, er = bi.ExecuteSubAccountTransfer(context.Background(), &SubAccountTransferRequestParams{
|
|
FromEmail: "fromemail@thrasher.io",
|
|
ToEmail: "toemail@threasher.io",
|
|
Asset: "BTC",
|
|
Amount: 0.000005,
|
|
})
|
|
if er != nil && !strings.Contains(er.Error(), "You are not authorized to execute this request.") {
|
|
t.Errorf("Binanceus GetSubaccountTransferHistory() error %v", er)
|
|
}
|
|
}
|
|
|
|
func TestGetSubaccountAssets(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetSubaccountAssets(context.Background(), "")
|
|
if !errors.Is(er, errNotValidEmailAddress) {
|
|
t.Errorf("Binanceus GetSubaccountAssets() expected %v, but found %v", er, errNotValidEmailAddress)
|
|
}
|
|
_, er = bi.GetSubaccountAssets(context.Background(), "subaccount@thrasher.io")
|
|
if er != nil && !strings.Contains(er.Error(), "This account does not exist.") {
|
|
t.Fatal("Binanceus GetSubaccountAssets() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderRateLimits(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetOrderRateLimits(context.Background(), 0)
|
|
if er != nil {
|
|
t.Error("Binanceus GetOrderRateLimits() error", er)
|
|
}
|
|
}
|
|
|
|
var testNewOrderResponseJSON = `{
|
|
"symbol": "BTCUSDT",
|
|
"orderId": 28,
|
|
"orderListId": -1,
|
|
"clientOrderId": "6gCrw2kRUAF9CvJDGP16IP",
|
|
"transactTime": 1507725176595,
|
|
"price": "0.00000000",
|
|
"origQty": "10.00000000",
|
|
"executedQty": "10.00000000",
|
|
"cummulativeQuoteQty": "10.00000000",
|
|
"status": "FILLED",
|
|
"timeInForce": "GTC",
|
|
"type": "MARKET",
|
|
"side": "SELL"
|
|
}`
|
|
|
|
func TestNewOrderTest(t *testing.T) {
|
|
t.Parallel()
|
|
var resp NewOrderResponse
|
|
if er := json.Unmarshal([]byte(testNewOrderResponseJSON), &resp); er != nil {
|
|
t.Error("Binanceus decerializing to Order error", er)
|
|
}
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
req := &NewOrderRequest{
|
|
Symbol: currency.NewPair(currency.LTC, currency.BTC),
|
|
Side: order.Buy.String(),
|
|
TradeType: BinanceRequestParamsOrderLimit,
|
|
Price: 0.0025,
|
|
Quantity: 100000,
|
|
TimeInForce: BinanceRequestParamsTimeGTC,
|
|
}
|
|
_, err := bi.NewOrderTest(context.Background(), req)
|
|
if err != nil {
|
|
t.Error("Binanceus NewOrderTest() error", err)
|
|
}
|
|
req = &NewOrderRequest{
|
|
Symbol: currency.NewPair(currency.LTC, currency.BTC),
|
|
Side: order.Sell.String(),
|
|
TradeType: BinanceRequestParamsOrderMarket,
|
|
Price: 0.0045,
|
|
QuoteOrderQty: 10,
|
|
}
|
|
_, err = bi.NewOrderTest(context.Background(), req)
|
|
if err != nil {
|
|
t.Error("NewOrderTest() error", err)
|
|
}
|
|
}
|
|
|
|
func TestNewOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
req := &NewOrderRequest{
|
|
Symbol: currency.NewPair(currency.LTC, currency.BTC),
|
|
Side: order.Buy.String(),
|
|
TradeType: BinanceRequestParamsOrderLimit,
|
|
Price: 0.0025,
|
|
Quantity: 100000,
|
|
TimeInForce: BinanceRequestParamsTimeGTC,
|
|
}
|
|
if _, err := bi.NewOrder(context.Background(), req); err != nil && !strings.Contains(err.Error(), "Account has insufficient balance for requested action") {
|
|
t.Error("Binanceus NewOrder() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetOrder(context.Background(), &OrderRequestParams{})
|
|
if !errors.Is(er, errIncompleteArguments) {
|
|
t.Errorf("Binanceus GetOrder() error expecting %v, but found %v", errIncompleteArguments, er)
|
|
}
|
|
_, er = bi.GetOrder(context.Background(), &OrderRequestParams{
|
|
Symbol: "BTCUSDT",
|
|
OrigClientOrderID: "something",
|
|
})
|
|
// You can check the existence of an order using a valid Symbol and OrigClient Order ID
|
|
if er != nil && !strings.Contains(er.Error(), "Order does not exist.") {
|
|
t.Error("Binanceus GetOrder() error", er)
|
|
}
|
|
}
|
|
|
|
var openOrdersItemJSON = `{
|
|
"symbol": "LTCBTC",
|
|
"orderId": 1,
|
|
"orderListId": -1,
|
|
"clientOrderId": "myOrder1",
|
|
"price": "0.1",
|
|
"origQty": "1.0",
|
|
"executedQty": "0.0",
|
|
"cummulativeQuoteQty": "0.0",
|
|
"status": "NEW",
|
|
"timeInForce": "GTC",
|
|
"type": "LIMIT",
|
|
"side": "BUY",
|
|
"stopPrice": "0.0",
|
|
"icebergQty": "0.0",
|
|
"time": 1499827319559,
|
|
"updateTime": 1499827319559,
|
|
"isWorking": true,
|
|
"origQuoteOrderQty": "0.000000"
|
|
}`
|
|
|
|
func TestGetAllOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
var resp Order
|
|
if er := json.Unmarshal([]byte(openOrdersItemJSON), &resp); er != nil {
|
|
t.Error("Binanceus decerializing to Order error", er)
|
|
}
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetAllOpenOrders(context.Background(), "")
|
|
if er != nil {
|
|
t.Error("Binanceus GetAllOpenOrders() error", er)
|
|
}
|
|
}
|
|
|
|
func TestCancelExistingOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.Skip("Binanceus CancelExistingOrder() skipping test, either api keys or canManipulateRealOrders isn't set")
|
|
}
|
|
_, er := bi.CancelExistingOrder(context.Background(), &CancelOrderRequestParams{Symbol: currency.NewPair(currency.BTC, currency.USDT)})
|
|
if er != nil && !errors.Is(er, errEitherOrderIDOrClientOrderIDIsRequired) {
|
|
t.Errorf("Binanceus CancelExistingOrder() error expecting %v, but found %v", errEitherOrderIDOrClientOrderIDIsRequired, er)
|
|
}
|
|
_, er = bi.CancelExistingOrder(context.Background(), &CancelOrderRequestParams{
|
|
Symbol: currency.NewPair(currency.BTC, currency.USDT),
|
|
ClientSuppliedOrderID: "1234",
|
|
})
|
|
if er != nil && !strings.Contains(er.Error(), "Unknown order sent.") {
|
|
t.Error("Binanceus CancelExistingorder() error", er)
|
|
}
|
|
}
|
|
|
|
func TestCancelOpenOrdersForSymbol(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.CancelOpenOrdersForSymbol(context.Background(), "")
|
|
if !errors.Is(er, errMissingCurrencySymbol) {
|
|
t.Errorf("Binanceus CancelOpenOrdersForSymbol() error expecting %v, but found %v", errIncompleteArguments, er)
|
|
}
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.Skip("Binanceus CancelOpenOrdersForSymbol() skipping test, either api keys or canManipulateRealOrders isn't set")
|
|
}
|
|
_, er = bi.CancelOpenOrdersForSymbol(context.Background(), "BTCUSDT")
|
|
if er != nil && !strings.Contains(er.Error(), "Unknown order sent") {
|
|
t.Error("Binanceus CancelOpenOrdersForSymbol() error", er)
|
|
}
|
|
}
|
|
|
|
// TestGetTrades test for fetching the list of
|
|
// trades attached with this account.
|
|
func TestGetTrades(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetTrades(context.Background(), &GetTradesParams{})
|
|
if !errors.Is(er, errIncompleteArguments) {
|
|
t.Errorf(" Binanceus GetTrades() expecting error %v, but found %v", errIncompleteArguments, er)
|
|
}
|
|
_, er = bi.GetTrades(context.Background(), &GetTradesParams{Symbol: "BTCUSDT"})
|
|
if er != nil {
|
|
t.Error("Binanceus GetTrades() error", er)
|
|
}
|
|
}
|
|
|
|
func TestCreateNewOCOOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.CreateNewOCOOrder(context.Background(),
|
|
&OCOOrderInputParams{
|
|
StopPrice: 1000,
|
|
Side: order.Buy.String(),
|
|
Quantity: 0.0000001,
|
|
Price: 1232334.00,
|
|
})
|
|
if !errors.Is(er, errIncompleteArguments) {
|
|
t.Errorf("Binanceus CreatenewOCOOrder() error expected %v, but found %v", errIncompleteArguments, er)
|
|
}
|
|
_, er = bi.CreateNewOCOOrder(
|
|
context.Background(),
|
|
&OCOOrderInputParams{
|
|
Symbol: "XTZUSD",
|
|
Price: 100,
|
|
StopPrice: 3,
|
|
StopLimitPrice: 2.5,
|
|
Side: order.Buy.String(),
|
|
Quantity: 1,
|
|
StopLimitTimeInForce: "GTC",
|
|
RecvWindow: 6000,
|
|
})
|
|
if er != nil && !strings.Contains(er.Error(), "Precision is over the maximum defined for this asset.") {
|
|
t.Error("Binanceus CreateNewOCOOrder() error", er)
|
|
}
|
|
}
|
|
|
|
var ocoOrderJSON = `{
|
|
"orderListId": 27,
|
|
"contingencyType": "OCO",
|
|
"listStatusType": "EXEC_STARTED",
|
|
"listOrderStatus": "EXECUTING",
|
|
"listClientOrderId": "h2USkA5YQpaXHPIrkd96xE",
|
|
"transactionTime": 1565245656253,
|
|
"symbol": "LTCBTC",
|
|
"orders": [
|
|
{
|
|
"symbol": "LTCBTC",
|
|
"orderId": 4,
|
|
"clientOrderId": "qD1gy3kc3Gx0rihm9Y3xwS"
|
|
},
|
|
{
|
|
"symbol": "LTCBTC",
|
|
"orderId": 5,
|
|
"clientOrderId": "ARzZ9I00CPM8i3NhmU9Ega"
|
|
}
|
|
]
|
|
}`
|
|
|
|
func TestGetOCOOrder(t *testing.T) {
|
|
t.Parallel()
|
|
var resp OCOOrderResponse
|
|
if er := json.Unmarshal([]byte(ocoOrderJSON), &resp); er != nil {
|
|
t.Error("Binanceus decerializing OCOOrderResponse error", er)
|
|
}
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetOCOOrder(context.Background(), &GetOCOOrderRequestParams{})
|
|
if !errors.Is(er, errIncompleteArguments) {
|
|
t.Errorf("Binanceus GetOCOOrder() error expecting %v, but found %v", errIncompleteArguments, er)
|
|
}
|
|
_, er = bi.GetOCOOrder(context.Background(), &GetOCOOrderRequestParams{
|
|
OrderListID: "123445",
|
|
})
|
|
if er != nil && !strings.Contains(er.Error(), "Order list does not exist.") {
|
|
t.Error("Binanceus GetOCOOrder() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetAllOCOOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetAllOCOOrder(context.Background(), &OCOOrdersRequestParams{})
|
|
if er != nil {
|
|
t.Error("Binanceus GetAllOCOOrder() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetOpenOCOOrders(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetOpenOCOOrders(context.Background(), 0)
|
|
if er != nil {
|
|
t.Error("Binanceus GetOpenOCOOrders() error", er)
|
|
}
|
|
}
|
|
|
|
func TestCancelOCOOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.CancelOCOOrder(context.Background(), &OCOOrdersDeleteRequestParams{})
|
|
if !errors.Is(er, errIncompleteArguments) {
|
|
t.Errorf("Binanceus CancelOCOOrder() error expected %v, but found %v", errIncompleteArguments, er)
|
|
}
|
|
}
|
|
|
|
// OTC end Points test code.
|
|
func TestGetSupportedCoinPairs(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetSupportedCoinPairs(context.Background(), currency.Pair{Base: currency.BTC, Quote: currency.USDT})
|
|
if er != nil {
|
|
t.Error("Binanceus GetSupportedCoinPairs() error", er)
|
|
}
|
|
}
|
|
|
|
func TestRequestForQuote(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.RequestForQuote(context.Background(), &RequestQuoteParams{ToCoin: "BTC", RequestCoin: "USDT", RequestAmount: 1})
|
|
if er != nil && !errors.Is(er, errMissingFromCoinName) {
|
|
t.Errorf("Binanceus RequestForQuote() expecting %v, but found %v", errMissingFromCoinName, er)
|
|
}
|
|
_, er = bi.RequestForQuote(context.Background(), &RequestQuoteParams{FromCoin: "ETH", RequestCoin: "USDT", RequestAmount: 1})
|
|
if er != nil && !errors.Is(er, errMissingToCoinName) {
|
|
t.Errorf("Binanceus RequestForQuote() expecting %v, but found %v", errMissingToCoinName, er)
|
|
}
|
|
_, er = bi.RequestForQuote(context.Background(), &RequestQuoteParams{FromCoin: "ETH", ToCoin: "BTC", RequestCoin: "USDT"})
|
|
if er != nil && !errors.Is(er, errMissingRequestAmount) {
|
|
t.Errorf("Binanceus RequestForQuote() expecting %v, but found %v", errMissingRequestAmount, er)
|
|
}
|
|
_, er = bi.RequestForQuote(context.Background(), &RequestQuoteParams{FromCoin: "ETH", ToCoin: "BTC", RequestAmount: 1})
|
|
if er != nil && !errors.Is(er, errMissingRequestCoin) {
|
|
t.Errorf("Binanceus RequestForQuote() expecting %v, but found %v", errMissingRequestCoin, er)
|
|
}
|
|
_, er = bi.RequestForQuote(context.Background(), &RequestQuoteParams{FromCoin: "BTC", ToCoin: "USDT", RequestCoin: "BTC", RequestAmount: 1})
|
|
if er != nil {
|
|
t.Error("Binanceus RequestForQuote() error", er)
|
|
}
|
|
}
|
|
|
|
var testPlaceOTCTradeOrderJSON = `{
|
|
"orderId": "10002349",
|
|
"createTime": 1641906714,
|
|
"orderStatus": "PROCESS"
|
|
}`
|
|
|
|
func TestPlaceOTCTradeOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
var res OTCTradeOrderResponse
|
|
er := json.Unmarshal([]byte(testPlaceOTCTradeOrderJSON), &res)
|
|
if er != nil {
|
|
t.Error("Binanceus PlaceOTCTradeOrder() error", er)
|
|
}
|
|
_, er = bi.PlaceOTCTradeOrder(context.Background(), "")
|
|
if !errors.Is(er, errMissingQuoteID) {
|
|
t.Errorf("Binanceus PlaceOTCTradeOrder() expecting %v, but found %v", errMissingQuoteID, er)
|
|
}
|
|
_, er = bi.PlaceOTCTradeOrder(context.Background(), "15848701022")
|
|
if er != nil && !strings.Contains(er.Error(), "-9000") {
|
|
t.Error("Binanceus PlaceOTCTradeOrder() error", er)
|
|
}
|
|
}
|
|
|
|
var testGetOTCTradeOrderJSON = `{
|
|
"quoteId": "4e5446f2cc6f44ab86ab02abf19a2fd2",
|
|
"orderId": "10002349",
|
|
"orderStatus": "SUCCESS",
|
|
"fromCoin": "BTC",
|
|
"fromAmount": 1,
|
|
"toCoin": "USDT",
|
|
"toAmount": 50550.26,
|
|
"ratio": 50550.26,
|
|
"inverseRatio": 0.00001978,
|
|
"createTime": 1641806714
|
|
}`
|
|
|
|
func TestGetOTCTradeOrder(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
var val OTCTradeOrder
|
|
er := json.Unmarshal([]byte(testGetOTCTradeOrderJSON), &val)
|
|
if er != nil {
|
|
t.Error("Binanceus JSON GetOTCTradeOrder() error", er)
|
|
}
|
|
_, er = bi.GetOTCTradeOrder(context.Background(), 10002349)
|
|
if er != nil && !strings.Contains(er.Error(), "status code: 400") {
|
|
t.Error("Binanceus GetOTCTradeOrder() error ", er)
|
|
}
|
|
}
|
|
|
|
var getAllOTCTradeOrders = `[
|
|
{
|
|
"quoteId": "4e5446f2cc6f44ab86ab02abf19a2fd2",
|
|
"orderId": "10002349",
|
|
"orderStatus": "SUCCESS",
|
|
"fromCoin": "BTC",
|
|
"fromAmount": 1,
|
|
"toCoin": "USDT",
|
|
"toAmount": 50550.26,
|
|
"ratio": 50550.26,
|
|
"inverseRatio": 0.00001978,
|
|
"createTime": 1641806714
|
|
},
|
|
{
|
|
"quoteId": "15848645308",
|
|
"orderId": "10002380",
|
|
"orderStatus": "PROCESS",
|
|
"fromCoin": "SHIB",
|
|
"fromAmount": 10000,
|
|
"toCoin": "KSHIB",
|
|
"toAmount": 10,
|
|
"ratio": 0.001,
|
|
"inverseRatio": 1000,
|
|
"createTime": 1641916714
|
|
}
|
|
]
|
|
`
|
|
|
|
func TestGetAllOTCTradeOrders(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
var orders []OTCTradeOrder
|
|
er := json.Unmarshal([]byte(getAllOTCTradeOrders), &orders)
|
|
if er != nil {
|
|
t.Error(er)
|
|
}
|
|
_, er = bi.GetAllOTCTradeOrders(context.Background(), &OTCTradeOrderRequestParams{})
|
|
if er != nil {
|
|
t.Error("Binanceus GetAllOTCTradeOrders() error", er)
|
|
}
|
|
}
|
|
|
|
var ocbsTradeOrderJSON = `
|
|
{
|
|
"quoteId": "4e5446f2cc6f44ab86ab02abf19abvd",
|
|
"orderId": "1000238000",
|
|
"orderStatus": "FAIL",
|
|
"fromCoin": "USD",
|
|
"fromAmount": 1000.5,
|
|
"toCoin": "ETH",
|
|
"toAmount": 0.5,
|
|
"feeCoin": "USD",
|
|
"feeAmount": 0.5,
|
|
"ratio": 2000,
|
|
"createTime": 1641916714
|
|
}`
|
|
|
|
func TestGetAllOCBSTradeOrders(t *testing.T) {
|
|
t.Parallel()
|
|
var orderDetail OCBSOrder
|
|
if er := json.Unmarshal([]byte(ocbsTradeOrderJSON), &orderDetail); er != nil {
|
|
t.Error("Binanceus decerializing to OCBSOrder error", er)
|
|
}
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetAllOCBSTradeOrders(context.Background(), OCBSOrderRequestParams{}); er != nil {
|
|
t.Error("Binanceus GetAllOCBSTradeOrders() error", er)
|
|
}
|
|
}
|
|
|
|
func TestGetAssetFeesAndWalletStatus(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetAssetFeesAndWalletStatus(context.Background())
|
|
if er != nil {
|
|
t.Error("Binanceus GetAssetFeesAndWalletStatus() error", er)
|
|
}
|
|
}
|
|
|
|
func TestWithdrawCrypto(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.WithdrawCrypto(context.Background(), &withdraw.Request{})
|
|
if !errors.Is(er, errMissingRequiredArgumentCoin) {
|
|
t.Errorf("Binanceus WithdrawCrypto() error expecting %v, but found %v", errMissingRequiredArgumentCoin, er)
|
|
}
|
|
if _, er = bi.WithdrawCrypto(context.Background(), &withdraw.Request{
|
|
Currency: currency.BTC,
|
|
}); !errors.Is(er, errMissingRequiredArgumentNetwork) {
|
|
t.Errorf("Binanceus WithdrawCrypto() expecting %v, but found %v", errMissingRequiredArgumentNetwork, er)
|
|
}
|
|
params := &withdraw.Request{
|
|
Currency: currency.BTC,
|
|
}
|
|
params.Crypto.Chain = "BSC"
|
|
if _, er = bi.WithdrawCrypto(context.Background(), params); !errors.Is(er, errMissingRequiredParameterAddress) {
|
|
t.Errorf("Binanceus WithdrawCrypto() expecting %v, but found %v", errMissingRequiredParameterAddress, er)
|
|
}
|
|
params.Crypto.Address = "1234567"
|
|
if _, er = bi.WithdrawCrypto(context.Background(), params); !errors.Is(er, errAmountValueMustBeGreaterThan0) {
|
|
t.Errorf("Binanceus WithdrawCrypto() expecting %v, but found %v", errAmountValueMustBeGreaterThan0, er)
|
|
}
|
|
params.Amount = 1
|
|
if _, er = bi.WithdrawCrypto(context.Background(), params); er != nil && !strings.Contains(er.Error(), "You are not authorized to execute this request.") {
|
|
t.Error("Binanceus WithdrawCrypto() error", er)
|
|
}
|
|
}
|
|
|
|
func TestFiatWithdrawalHistory(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.FiatWithdrawalHistory(context.Background(), &FiatWithdrawalRequestParams{
|
|
FiatCurrency: "USDT",
|
|
})
|
|
if er != nil {
|
|
t.Errorf("%s FiatWithdrawalHistory() error %v", bi.Name, er)
|
|
}
|
|
}
|
|
|
|
func TestDepositHistory(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.DepositHistory(context.Background(), currency.USD, 1, time.Time{}, time.Time{}, 0, 100)
|
|
if er != nil {
|
|
t.Error("Binanceus DepositHistory() error", er)
|
|
}
|
|
}
|
|
func TestFiatDepositHistory(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.FiatDepositHistory(context.Background(), &FiatWithdrawalRequestParams{})
|
|
if er != nil {
|
|
t.Error("Binanceus FiatDepositHistory() error", er)
|
|
}
|
|
}
|
|
|
|
// WEBSOCKET support testing
|
|
// Since both binance and Binance US has same websocket functions,
|
|
// the tests functions are also similar
|
|
|
|
// TestWebsocketStreamKey this test mmethod handles the
|
|
// creating, updating, and deleting of user stream key or "listenKey"
|
|
// all the three methods in one test methods.
|
|
func TestWebsocketStreamKey(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
_, er := bi.GetWsAuthStreamKey(context.Background())
|
|
if er != nil {
|
|
t.Error("Binanceus GetWsAuthStreamKey() error", er)
|
|
}
|
|
er = bi.MaintainWsAuthStreamKey(context.Background())
|
|
if er != nil {
|
|
t.Error("Binanceus MaintainWsAuthStreamKey() error", er)
|
|
}
|
|
er = bi.CloseUserDataStream(context.Background())
|
|
if er != nil {
|
|
t.Error("Binanceus CloseUserDataStream() error", er)
|
|
}
|
|
}
|
|
|
|
var subscriptionRequestString = `{
|
|
"method": "SUBSCRIBE",
|
|
"params": [
|
|
"btcusdt@aggTrade",
|
|
"btcusdt@depth"
|
|
],
|
|
"id": 1
|
|
}`
|
|
|
|
func TestWebsocketSubscriptionHandling(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
rawData := []byte(subscriptionRequestString)
|
|
err := bi.wsHandleData(rawData)
|
|
if err != nil {
|
|
t.Error("Binanceus wsHandleData() error", err)
|
|
}
|
|
}
|
|
|
|
func TestWebsocketUnsubscriptionHandling(t *testing.T) {
|
|
pressXToJSON := []byte(`{
|
|
"method": "UNSUBSCRIBE",
|
|
"params": [
|
|
"btcusdt@depth"
|
|
],
|
|
"id": 312
|
|
}`)
|
|
err := bi.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetSubscriptions(t *testing.T) {
|
|
t.Parallel()
|
|
if _, err := bi.GetSubscriptions(); err != nil {
|
|
t.Error("Binanceus GetSubscriptions() error", err)
|
|
}
|
|
}
|
|
|
|
var ticker24hourChangeStream = `{
|
|
"stream":"btcusdt@ticker",
|
|
"data" :{
|
|
"e": "24hrTicker",
|
|
"E": 123456789,
|
|
"s": "BNBBTC",
|
|
"p": "0.0015",
|
|
"P": "250.00",
|
|
"w": "0.0018",
|
|
"x": "0.0009",
|
|
"c": "0.0025",
|
|
"Q": "10",
|
|
"b": "0.0024",
|
|
"B": "10",
|
|
"a": "0.0026",
|
|
"A": "100",
|
|
"o": "0.0010",
|
|
"h": "0.0025",
|
|
"l": "0.0010",
|
|
"v": "10000",
|
|
"q": "18",
|
|
"O": 0,
|
|
"C": 86400000,
|
|
"F": 0,
|
|
"L": 18150,
|
|
"n": 18151
|
|
}
|
|
}`
|
|
|
|
func TestWebsocketTickerUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
if err := bi.wsHandleData([]byte(ticker24hourChangeStream)); err != nil {
|
|
t.Error("Binanceus wsHandleData() for Ticker 24h Change Stream", err)
|
|
}
|
|
}
|
|
|
|
func TestWebsocketKlineUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
pressXToJSON := []byte(`
|
|
{
|
|
"stream":"btcusdt@kline_1m",
|
|
"data":{
|
|
"e": "kline",
|
|
"E": 123456789,
|
|
"s": "BNBBTC",
|
|
"k": {
|
|
"t": 123400000,
|
|
"T": 123460000,
|
|
"s": "BNBBTC",
|
|
"i": "1m",
|
|
"f": 100,
|
|
"L": 200,
|
|
"o": "0.0010",
|
|
"c": "0.0020",
|
|
"h": "0.0025",
|
|
"l": "0.0015",
|
|
"v": "1000",
|
|
"n": 100,
|
|
"x": false,
|
|
"q": "1.0000",
|
|
"V": "500",
|
|
"Q": "0.500",
|
|
"B": "123456"
|
|
}
|
|
}
|
|
}`)
|
|
if err := bi.wsHandleData(pressXToJSON); err != nil {
|
|
t.Error("Binanceus wsHandleData() btcusdt@kline_1m stream data conversion ", err)
|
|
}
|
|
}
|
|
|
|
func TestWebsocketStreamTradeUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
pressXToJSON := []byte(`{"stream":"btcusdt@trade","data":{
|
|
"e": "trade",
|
|
"E": 123456789,
|
|
"s": "BNBBTC",
|
|
"t": 12345,
|
|
"p": "0.001",
|
|
"q": "100",
|
|
"b": 88,
|
|
"a": 50,
|
|
"T": 123456785,
|
|
"m": true,
|
|
"M": true
|
|
}}`)
|
|
if err := bi.wsHandleData(pressXToJSON); err != nil {
|
|
t.Error("Binanceus wsHandleData() error", err)
|
|
}
|
|
}
|
|
|
|
// TestWsDepthUpdate copied from the Binance Test
|
|
func TestWebsocketOrderBookDepthDiffStream(t *testing.T) {
|
|
binanceusOrderBookLock.Lock()
|
|
defer binanceusOrderBookLock.Unlock()
|
|
bi.setupOrderbookManager()
|
|
seedLastUpdateID := int64(161)
|
|
book := OrderBook{
|
|
Asks: []OrderbookItem{
|
|
{Price: 6621.80000000, Quantity: 0.00198100},
|
|
{Price: 6622.14000000, Quantity: 4.00000000},
|
|
{Price: 6622.46000000, Quantity: 2.30000000},
|
|
{Price: 6622.47000000, Quantity: 1.18633300},
|
|
{Price: 6622.64000000, Quantity: 4.00000000},
|
|
{Price: 6622.73000000, Quantity: 0.02900000},
|
|
{Price: 6622.76000000, Quantity: 0.12557700},
|
|
{Price: 6622.81000000, Quantity: 2.08994200},
|
|
{Price: 6622.82000000, Quantity: 0.01500000},
|
|
{Price: 6623.17000000, Quantity: 0.16831300},
|
|
},
|
|
Bids: []OrderbookItem{
|
|
{Price: 6621.55000000, Quantity: 0.16356700},
|
|
{Price: 6621.45000000, Quantity: 0.16352600},
|
|
{Price: 6621.41000000, Quantity: 0.86091200},
|
|
{Price: 6621.25000000, Quantity: 0.16914100},
|
|
{Price: 6621.23000000, Quantity: 0.09193600},
|
|
{Price: 6621.22000000, Quantity: 0.00755100},
|
|
{Price: 6621.13000000, Quantity: 0.08432000},
|
|
{Price: 6621.03000000, Quantity: 0.00172000},
|
|
{Price: 6620.94000000, Quantity: 0.30506700},
|
|
{Price: 6620.93000000, Quantity: 0.00200000},
|
|
},
|
|
LastUpdateID: seedLastUpdateID,
|
|
}
|
|
update1 := []byte(`{"stream":"btcusdt@depth","data":{
|
|
"e": "depthUpdate",
|
|
"E": 123456788,
|
|
"s": "BTCUSDT",
|
|
"U": 157,
|
|
"u": 160,
|
|
"b": [
|
|
["6621.45", "0.3"]
|
|
],
|
|
"a": [
|
|
["6622.46", "1.5"]
|
|
]
|
|
}}`)
|
|
|
|
p := currency.NewPairWithDelimiter("BTC", "USDT", "-")
|
|
if err := bi.SeedLocalCacheWithBook(p, &book); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if err := bi.wsHandleData(update1); err != nil {
|
|
t.Error(err)
|
|
}
|
|
bi.obm.state[currency.BTC][currency.USDT][asset.Spot].fetchingBook = false
|
|
ob, err := bi.Websocket.Orderbook.GetOrderbook(p, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if exp, got := seedLastUpdateID, ob.LastUpdateID; got != exp {
|
|
t.Fatalf("Unexpected Last update id of orderbook for old update. Exp: %d, got: %d", exp, got)
|
|
}
|
|
if exp, got := 2.3, ob.Asks[2].Amount; got != exp {
|
|
t.Fatalf("Ask altered by outdated update. Exp: %f, got %f", exp, got)
|
|
}
|
|
if exp, got := 0.163526, ob.Bids[1].Amount; got != exp {
|
|
t.Fatalf("Bid altered by outdated update. Exp: %f, got %f", exp, got)
|
|
}
|
|
update2 := []byte(`{
|
|
"stream":"btcusdt@depth","data":{
|
|
"e": "depthUpdate",
|
|
"E": 123456789,
|
|
"s": "BTCUSDT",
|
|
"U": 161,
|
|
"u": 165,
|
|
"b": [
|
|
["6621.45", "0.163526"]
|
|
],
|
|
"a": [
|
|
["6622.46", "2.3"],
|
|
["6622.47", "1.9"]
|
|
]
|
|
}
|
|
}`)
|
|
if err = bi.wsHandleData(update2); err != nil {
|
|
t.Error("Binanceus wshandlerData error", err)
|
|
}
|
|
ob, err = bi.Websocket.Orderbook.GetOrderbook(p, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal("Binanceus GetOrderBook error", err)
|
|
}
|
|
if exp, got := int64(165), ob.LastUpdateID; got != exp {
|
|
t.Fatalf("Binanceus Unexpected Last update id of orderbook for new update. Exp: %d, got: %d", exp, got)
|
|
}
|
|
if exp, got := 2.3, ob.Asks[2].Amount; got != exp {
|
|
t.Fatalf("Binanceus Unexpected Ask amount. Exp: %f, got %f", exp, got)
|
|
}
|
|
if exp, got := 1.9, ob.Asks[3].Amount; got != exp {
|
|
t.Fatalf("Binanceus Unexpected Ask amount. Exp: %f, got %f", exp, got)
|
|
}
|
|
if exp, got := 0.163526, ob.Bids[1].Amount; got != exp {
|
|
t.Fatalf("Binanceus Unexpected Bid amount. Exp: %f, got %f", exp, got)
|
|
}
|
|
bi.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0
|
|
}
|
|
|
|
// TestWebsocketPartialOrderBookDepthStream copied from the Binance Test
|
|
func TestWebsocketPartialOrderBookDepthStream(t *testing.T) {
|
|
t.Parallel()
|
|
update1 := []byte(`{"stream":"btcusdt@depth5","data":
|
|
{
|
|
"lastUpdateId": 160,
|
|
"bids": [
|
|
[
|
|
"0.0024",
|
|
"10"
|
|
]
|
|
],
|
|
"asks": [
|
|
[
|
|
"0.0026",
|
|
"100"
|
|
]
|
|
]
|
|
}}`)
|
|
var err error
|
|
if err = bi.wsHandleData(update1); err != nil {
|
|
t.Error("Binanceus Partial Order Book Depth Sream error", err)
|
|
}
|
|
update2 := []byte(`{
|
|
"stream":"btcusdt@depth10",
|
|
"data":{
|
|
"lastUpdateId": 160,
|
|
"bids": [
|
|
[
|
|
"0.0024",
|
|
"10"
|
|
]
|
|
],
|
|
"asks": [
|
|
[
|
|
"0.0026",
|
|
"100"
|
|
]
|
|
]
|
|
}
|
|
}`)
|
|
if err = bi.wsHandleData(update2); err != nil {
|
|
t.Error("Binanceus Partial Order Book Depth Sream error", err)
|
|
}
|
|
}
|
|
|
|
func TestWebsocketBookTicker(t *testing.T) {
|
|
t.Parallel()
|
|
var bookTickerJSON = []byte(
|
|
`{
|
|
"stream": "btcusdt@bookTicker",
|
|
"data": {
|
|
"u":400900217,
|
|
"s":"BNBUSDT",
|
|
"b":"25.35190000",
|
|
"B":"31.21000000",
|
|
"a":"25.36520000",
|
|
"A":"40.66000000"
|
|
}
|
|
}`)
|
|
if err := bi.wsHandleData(bookTickerJSON); err != nil {
|
|
t.Error("Binanceus Book Ticker error", err)
|
|
}
|
|
var bookTickerForAllSymbols = []byte(`
|
|
{
|
|
"stream" : "!bookTicker",
|
|
"data":{
|
|
"u":400900217,
|
|
"s":"BNBUSDT",
|
|
"b":"25.35190000",
|
|
"B":"31.21000000",
|
|
"a":"25.36520000",
|
|
"A":"40.66000000"
|
|
}
|
|
}`)
|
|
if err := bi.wsHandleData(bookTickerForAllSymbols); err != nil {
|
|
t.Error("Binanceus Web socket Book ticker for all symbols error", err)
|
|
}
|
|
}
|
|
|
|
func TestWebsocketAggTrade(t *testing.T) {
|
|
t.Parallel()
|
|
var aggTradejson = []byte(
|
|
`{
|
|
"stream":"btcusdt@aggTrade",
|
|
"data": {
|
|
"e": "aggTrade",
|
|
"E": 123456789,
|
|
"s": "BNBBTC",
|
|
"a": 12345,
|
|
"p": "0.001",
|
|
"q": "100",
|
|
"f": 100,
|
|
"l": 105,
|
|
"T": 123456785,
|
|
"m": true,
|
|
"M": true
|
|
}
|
|
}`)
|
|
if err := bi.wsHandleData(aggTradejson); err != nil {
|
|
t.Error("Binanceus Aggregated Trade Order Json() error", err)
|
|
}
|
|
}
|
|
|
|
var balanceUpdateInputJSON = `
|
|
{
|
|
"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc",
|
|
"data":{
|
|
"e": "balanceUpdate",
|
|
"E": 1573200697110,
|
|
"a": "BTC",
|
|
"d": "100.00000000",
|
|
"T": 1573200697068
|
|
}
|
|
}`
|
|
|
|
func TestWebsocketBalanceUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
thejson := []byte(balanceUpdateInputJSON)
|
|
if err := bi.wsHandleData(thejson); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
var listStatusUserDataStreamPayload = `
|
|
{
|
|
"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc",
|
|
"data":{
|
|
"e": "listStatus",
|
|
"E": 1564035303637,
|
|
"s": "ETHBTC",
|
|
"g": 2,
|
|
"c": "OCO",
|
|
"l": "EXEC_STARTED",
|
|
"L": "EXECUTING",
|
|
"r": "NONE",
|
|
"C": "F4QN4G8DlFATFlIUQ0cjdD",
|
|
"T": 1564035303625,
|
|
"O": [
|
|
{
|
|
"s": "ETHBTC",
|
|
"i": 17,
|
|
"c": "AJYsMjErWJesZvqlJCTUgL"
|
|
},
|
|
{
|
|
"s": "ETHBTC",
|
|
"i": 18,
|
|
"c": "bfYPSQdLoqAJeNrOr9adzq"
|
|
}
|
|
]
|
|
}
|
|
}`
|
|
|
|
func TestWebsocketListStatus(t *testing.T) {
|
|
t.Parallel()
|
|
if err := bi.wsHandleData([]byte(listStatusUserDataStreamPayload)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestExecutionTypeToOrderStatus(t *testing.T) {
|
|
type TestCases struct {
|
|
Case string
|
|
Result order.Status
|
|
}
|
|
testCases := []TestCases{
|
|
{Case: "NEW", Result: order.New},
|
|
{Case: "PARTIALLY_FILLED", Result: order.PartiallyFilled},
|
|
{Case: "FILLED", Result: order.Filled},
|
|
{Case: "CANCELED", Result: order.Cancelled},
|
|
{Case: "PENDING_CANCEL", Result: order.PendingCancel},
|
|
{Case: "REJECTED", Result: order.Rejected},
|
|
{Case: "EXPIRED", Result: order.Expired},
|
|
{Case: "LOL", Result: order.UnknownStatus},
|
|
}
|
|
for i := range testCases {
|
|
result, _ := stringToOrderStatus(testCases[i].Case)
|
|
if result != testCases[i].Result {
|
|
t.Errorf("Binanceus Exepcted: %v, received: %v", testCases[i].Result, result)
|
|
}
|
|
}
|
|
}
|
|
|
|
var websocketDepthUpdate = []byte(
|
|
`{
|
|
"e": "depthUpdate",
|
|
"E": 123456789,
|
|
"s": "BNBBTC",
|
|
"U": 157,
|
|
"u": 160,
|
|
"b": [
|
|
[
|
|
"0.0024",
|
|
"10"
|
|
]
|
|
],
|
|
"a": [
|
|
[
|
|
"0.0026",
|
|
"100"
|
|
]
|
|
]
|
|
}
|
|
`)
|
|
|
|
func TestProcessUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
binanceusOrderBookLock.Lock()
|
|
defer binanceusOrderBookLock.Unlock()
|
|
p := currency.NewPair(currency.BTC, currency.USDT)
|
|
var depth WebsocketDepthStream
|
|
err := json.Unmarshal(websocketDepthUpdate, &depth)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = bi.obm.stageWsUpdate(&depth, p, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = bi.obm.fetchBookViaREST(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = bi.obm.cleanup(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
bi.obm.state[currency.BTC][currency.USDT][asset.Spot].lastUpdateID = 0
|
|
}
|
|
|
|
func TestWebsocketOrderExecutionReport(t *testing.T) {
|
|
payload := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"executionReport","E":1616627567900,"s":"BTCUSDT","c":"c4wyKsIhoAaittTYlIVLqk","S":"BUY","o":"LIMIT","f":"GTC","q":"0.00028400","p":"52789.10000000","P":"0.00000000","F":"0.00000000","g":-1,"C":"","x":"NEW","X":"NEW","r":"NONE","i":5340845958,"l":"0.00000000","z":"0.00000000","L":"0.00000000","n":"0","N":"BTC","T":1616627567900,"t":-1,"I":11388173160,"w":true,"m":false,"M":false,"O":1616627567900,"Z":"0.00000000","Y":"0.00000000","Q":"0.00000000"}}`)
|
|
expRes := order.Detail{
|
|
Price: 52789.1,
|
|
Amount: 0.00028400,
|
|
RemainingAmount: 0.00028400,
|
|
CostAsset: currency.USDT,
|
|
FeeAsset: currency.BTC,
|
|
Exchange: "Binanceus",
|
|
OrderID: "5340845958",
|
|
ClientOrderID: "c4wyKsIhoAaittTYlIVLqk",
|
|
Type: order.Limit,
|
|
Side: order.Buy,
|
|
Status: order.New,
|
|
AssetType: asset.Spot,
|
|
Date: time.UnixMilli(1616627567900),
|
|
LastUpdated: time.UnixMilli(1616627567900),
|
|
Pair: currency.NewPair(currency.BTC, currency.USDT),
|
|
}
|
|
for len(bi.Websocket.DataHandler) > 0 {
|
|
<-bi.Websocket.DataHandler
|
|
}
|
|
err := bi.wsHandleData(payload)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
res := <-bi.Websocket.DataHandler
|
|
switch r := res.(type) {
|
|
case *order.Detail:
|
|
if !reflects.DeepEqual(expRes, *r) {
|
|
t.Errorf("Binanceus Results do not match:\nexpected: %v\nreceived: %v", expRes, *r)
|
|
}
|
|
default:
|
|
t.Fatalf("Binanceus expected type order.Detail, found %T", res)
|
|
}
|
|
payload = []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"executionReport","E":1616633041556,"s":"BTCUSDT","c":"YeULctvPAnHj5HXCQo9Mob","S":"BUY","o":"LIMIT","f":"GTC","q":"0.00028600","p":"52436.85000000","P":"0.00000000","F":"0.00000000","g":-1,"C":"","x":"TRADE","X":"FILLED","r":"NONE","i":5341783271,"l":"0.00028600","z":"0.00028600","L":"52436.85000000","n":"0.00000029","N":"BTC","T":1616633041555,"t":726946523,"I":11390206312,"w":false,"m":false,"M":true,"O":1616633041555,"Z":"14.99693910","Y":"14.99693910","Q":"0.00000000"}}`)
|
|
err = bi.wsHandleData(payload)
|
|
if err != nil {
|
|
t.Fatal("Binanceus OrderExecutionReport json conversion error", err)
|
|
}
|
|
}
|
|
|
|
func TestWebsocketOutboundAccountPosition(t *testing.T) {
|
|
t.Parallel()
|
|
payload := []byte(`{"stream":"jTfvpakT2yT0hVIo5gYWVihZhdM2PrBgJUZ5PyfZ4EVpCkx4Uoxk5timcrQc","data":{"e":"outboundAccountPosition","E":1616628815745,"u":1616628815745,"B":[{"a":"BTC","f":"0.00225109","l":"0.00123000"},{"a":"BNB","f":"0.00000000","l":"0.00000000"},{"a":"USDT","f":"54.43390661","l":"0.00000000"}]}}`)
|
|
if err := bi.wsHandleData(payload); err != nil {
|
|
t.Fatal("Binanceus testing \"outboundAccountPosition\" data conversion error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAvailableTransferChains(t *testing.T) {
|
|
t.Parallel()
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetAvailableTransferChains(context.Background(), currency.BTC); er != nil {
|
|
t.Error("Binanceus GetAvailableTransferChains() error", er)
|
|
}
|
|
}
|
|
|
|
func TestQuickEnableCryptoWithdrawal(t *testing.T) {
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if er := bi.QuickEnableCryptoWithdrawal(context.Background()); er != nil && !strings.Contains(er.Error(), "unexpected end of JSON input") {
|
|
t.Errorf("Binanceus QuickEnableCryptoWithdrawal() expecting %s, but found %v", "unexpected end of JSON input", er)
|
|
}
|
|
}
|
|
func TestQuickDisableCryptoWithdrawal(t *testing.T) {
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if er := bi.QuickDisableCryptoWithdrawal(context.Background()); er != nil && !strings.Contains(er.Error(), "unexpected end of JSON input") {
|
|
t.Errorf("Binanceus QuickDisableCryptoWithdrawal() expecting %s, but found %v", "unexpected end of JSON input", er)
|
|
}
|
|
}
|
|
|
|
func TestGetUsersSpotAssetSnapshot(t *testing.T) {
|
|
if !areTestAPIKeysSet() {
|
|
t.SkipNow()
|
|
}
|
|
if _, er := bi.GetUsersSpotAssetSnapshot(context.Background(), time.Time{}, time.Time{}, 10, 6); er != nil {
|
|
t.Error("Binanceus GetUsersSpotAssetSnapshot() error", er)
|
|
}
|
|
}
|