Showing preview only (1,007K chars total). Download the full file or copy to clipboard to get everything.
Repository: crypto-crawler/crypto-crawler-rs
Branch: main
Commit: 8091c2ccc932
Files: 306
Total size: 926.4 KB
Directory structure:
gitextract_sqwwf4gd/
├── .config/
│ └── nextest.toml
├── .editorconfig
├── .github/
│ ├── CODEOWNERS
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── Cargo.toml
├── LICENSE
├── README.md
├── crypto-client/
│ ├── Cargo.toml
│ ├── README.md
│ └── src/
│ └── lib.rs
├── crypto-crawler/
│ ├── Cargo.toml
│ ├── README.md
│ ├── src/
│ │ ├── crawlers/
│ │ │ ├── binance.rs
│ │ │ ├── bitmex.rs
│ │ │ ├── deribit.rs
│ │ │ ├── huobi.rs
│ │ │ ├── kucoin.rs
│ │ │ ├── mod.rs
│ │ │ ├── okx.rs
│ │ │ ├── utils.rs
│ │ │ ├── zb.rs
│ │ │ └── zbg.rs
│ │ ├── lib.rs
│ │ ├── msg.rs
│ │ └── utils/
│ │ ├── cmc_rank.rs
│ │ ├── lock.rs
│ │ ├── mod.rs
│ │ └── spot_symbols.rs
│ └── tests/
│ ├── binance.rs
│ ├── bitfinex.rs
│ ├── bitget.rs
│ ├── bithumb.rs
│ ├── bitmex.rs
│ ├── bitstamp.rs
│ ├── bitz.rs
│ ├── bybit.rs
│ ├── coinbase_pro.rs
│ ├── deribit.rs
│ ├── dydx.rs
│ ├── ftx.rs
│ ├── gate.rs
│ ├── huobi.rs
│ ├── kraken.rs
│ ├── kucoin.rs
│ ├── mexc.rs
│ ├── okx.rs
│ ├── utils/
│ │ └── mod.rs
│ ├── zb.rs
│ └── zbg.rs
├── crypto-market-type/
│ ├── Cargo.toml
│ ├── include/
│ │ └── crypto_market_type.h
│ └── src/
│ └── lib.rs
├── crypto-markets/
│ ├── Cargo.toml
│ ├── README.md
│ ├── src/
│ │ ├── error.rs
│ │ ├── exchanges/
│ │ │ ├── binance/
│ │ │ │ ├── binance_inverse.rs
│ │ │ │ ├── binance_linear.rs
│ │ │ │ ├── binance_option.rs
│ │ │ │ ├── binance_spot.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── bitfinex.rs
│ │ │ ├── bitget/
│ │ │ │ ├── bitget_spot.rs
│ │ │ │ ├── bitget_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── bithumb.rs
│ │ │ ├── bitmex.rs
│ │ │ ├── bitstamp.rs
│ │ │ ├── bitz/
│ │ │ │ ├── bitz_spot.rs
│ │ │ │ ├── bitz_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── bybit.rs
│ │ │ ├── coinbase_pro.rs
│ │ │ ├── deribit/
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── dydx/
│ │ │ │ ├── dydx_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── ftx.rs
│ │ │ ├── gate/
│ │ │ │ ├── gate_future.rs
│ │ │ │ ├── gate_spot.rs
│ │ │ │ ├── gate_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── huobi/
│ │ │ │ ├── huobi_future.rs
│ │ │ │ ├── huobi_inverse_swap.rs
│ │ │ │ ├── huobi_linear_swap.rs
│ │ │ │ ├── huobi_option.rs
│ │ │ │ ├── huobi_spot.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── kraken/
│ │ │ │ ├── kraken_futures.rs
│ │ │ │ ├── kraken_spot.rs
│ │ │ │ └── mod.rs
│ │ │ ├── kucoin/
│ │ │ │ ├── kucoin_spot.rs
│ │ │ │ ├── kucoin_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── mexc/
│ │ │ │ ├── mexc_spot.rs
│ │ │ │ ├── mexc_swap.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── mod.rs
│ │ │ ├── okx.rs
│ │ │ ├── utils.rs
│ │ │ ├── zb/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── zb_spot.rs
│ │ │ │ └── zb_swap.rs
│ │ │ └── zbg/
│ │ │ ├── mod.rs
│ │ │ ├── zbg_spot.rs
│ │ │ └── zbg_swap.rs
│ │ ├── lib.rs
│ │ ├── main.rs
│ │ └── market.rs
│ └── tests/
│ ├── binance.rs
│ ├── bitfinex.rs
│ ├── bitget.rs
│ ├── bithumb.rs
│ ├── bitmex.rs
│ ├── bitstamp.rs
│ ├── bitz.rs
│ ├── bybit.rs
│ ├── coinbase_pro.rs
│ ├── deribit.rs
│ ├── dydx.rs
│ ├── ftx.rs
│ ├── gate.rs
│ ├── huobi.rs
│ ├── kraken.rs
│ ├── kucoin.rs
│ ├── mexc.rs
│ ├── okx.rs
│ ├── utils/
│ │ └── mod.rs
│ ├── zb.rs
│ └── zbg.rs
├── crypto-msg-type/
│ ├── Cargo.toml
│ ├── include/
│ │ └── crypto_msg_type.h
│ └── src/
│ ├── exchanges/
│ │ ├── binance.rs
│ │ ├── bitfinex.rs
│ │ ├── bitmex.rs
│ │ ├── bybit.rs
│ │ ├── deribit.rs
│ │ ├── ftx.rs
│ │ ├── huobi.rs
│ │ ├── mod.rs
│ │ ├── okex.rs
│ │ └── okx.rs
│ └── lib.rs
├── crypto-rest-client/
│ ├── Cargo.toml
│ ├── README.md
│ ├── src/
│ │ ├── error.rs
│ │ ├── exchanges/
│ │ │ ├── binance/
│ │ │ │ ├── binance_inverse.rs
│ │ │ │ ├── binance_linear.rs
│ │ │ │ ├── binance_option.rs
│ │ │ │ ├── binance_spot.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── bitfinex.rs
│ │ │ ├── bitget/
│ │ │ │ ├── bitget_spot.rs
│ │ │ │ ├── bitget_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── bithumb.rs
│ │ │ ├── bitmex.rs
│ │ │ ├── bitstamp.rs
│ │ │ ├── bitz/
│ │ │ │ ├── bitz_spot.rs
│ │ │ │ ├── bitz_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── bybit.rs
│ │ │ ├── coinbase_pro.rs
│ │ │ ├── deribit.rs
│ │ │ ├── dydx/
│ │ │ │ ├── dydx_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── ftx.rs
│ │ │ ├── gate/
│ │ │ │ ├── gate_future.rs
│ │ │ │ ├── gate_spot.rs
│ │ │ │ ├── gate_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── huobi/
│ │ │ │ ├── huobi_future.rs
│ │ │ │ ├── huobi_inverse_swap.rs
│ │ │ │ ├── huobi_linear_swap.rs
│ │ │ │ ├── huobi_option.rs
│ │ │ │ ├── huobi_spot.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── kraken/
│ │ │ │ ├── kraken_futures.rs
│ │ │ │ ├── kraken_spot.rs
│ │ │ │ └── mod.rs
│ │ │ ├── kucoin/
│ │ │ │ ├── kucoin_spot.rs
│ │ │ │ ├── kucoin_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── mexc/
│ │ │ │ ├── mexc_spot.rs
│ │ │ │ ├── mexc_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── mod.rs
│ │ │ ├── okx.rs
│ │ │ ├── utils.rs
│ │ │ ├── zb/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── zb_spot.rs
│ │ │ │ └── zb_swap.rs
│ │ │ └── zbg/
│ │ │ ├── mod.rs
│ │ │ ├── zbg_spot.rs
│ │ │ └── zbg_swap.rs
│ │ └── lib.rs
│ └── tests/
│ ├── binance_inverse.rs
│ ├── binance_linear.rs
│ ├── binance_option.rs
│ ├── binance_spot.rs
│ ├── bitfinex.rs
│ ├── bitget_spot.rs
│ ├── bitget_swap.rs
│ ├── bithumb.rs
│ ├── bitmex.rs
│ ├── bitstamp.rs
│ ├── bitz_spot.rs
│ ├── bitz_swap.rs
│ ├── bybit.rs
│ ├── coinbase_pro.rs
│ ├── deribit.rs
│ ├── dydx.rs
│ ├── ftx.rs
│ ├── gate.rs
│ ├── huobi.rs
│ ├── kraken.rs
│ ├── kucoin.rs
│ ├── mexc.rs
│ ├── okx.rs
│ ├── zb.rs
│ └── zbg.rs
├── crypto-ws-client/
│ ├── Cargo.toml
│ ├── README.md
│ ├── src/
│ │ ├── clients/
│ │ │ ├── binance.rs
│ │ │ ├── binance_option.rs
│ │ │ ├── bitfinex.rs
│ │ │ ├── bitget/
│ │ │ │ ├── bitget_spot.rs
│ │ │ │ ├── bitget_swap.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── bithumb.rs
│ │ │ ├── bitmex.rs
│ │ │ ├── bitstamp.rs
│ │ │ ├── bitz/
│ │ │ │ ├── bitz_spot.rs
│ │ │ │ └── mod.rs
│ │ │ ├── bybit/
│ │ │ │ ├── bybit_inverse.rs
│ │ │ │ ├── bybit_linear_swap.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── coinbase_pro.rs
│ │ │ ├── common_traits.rs
│ │ │ ├── deribit.rs
│ │ │ ├── dydx/
│ │ │ │ ├── dydx_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── ftx.rs
│ │ │ ├── gate/
│ │ │ │ ├── gate_future.rs
│ │ │ │ ├── gate_spot.rs
│ │ │ │ ├── gate_swap.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── huobi.rs
│ │ │ ├── kraken/
│ │ │ │ ├── kraken_futures.rs
│ │ │ │ ├── kraken_spot.rs
│ │ │ │ └── mod.rs
│ │ │ ├── kucoin/
│ │ │ │ ├── kucoin_spot.rs
│ │ │ │ ├── kucoin_swap.rs
│ │ │ │ ├── mod.rs
│ │ │ │ └── utils.rs
│ │ │ ├── mexc/
│ │ │ │ ├── mexc_spot.rs
│ │ │ │ ├── mexc_swap.rs
│ │ │ │ └── mod.rs
│ │ │ ├── mod.rs
│ │ │ ├── okx.rs
│ │ │ ├── zb/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── zb_spot.rs
│ │ │ │ └── zb_swap.rs
│ │ │ └── zbg/
│ │ │ ├── mod.rs
│ │ │ ├── utils.rs
│ │ │ ├── zbg_spot.rs
│ │ │ └── zbg_swap.rs
│ │ ├── common/
│ │ │ ├── command_translator.rs
│ │ │ ├── connect_async.rs
│ │ │ ├── message_handler.rs
│ │ │ ├── mod.rs
│ │ │ ├── utils.rs
│ │ │ ├── ws_client.rs
│ │ │ └── ws_client_internal.rs
│ │ └── lib.rs
│ └── tests/
│ ├── binance.rs
│ ├── binance_option.rs
│ ├── bitfinex.rs
│ ├── bitget.rs
│ ├── bithumb.rs
│ ├── bitmex.rs
│ ├── bitstamp.rs
│ ├── bitz.rs
│ ├── bybit.rs
│ ├── coinbase_pro.rs
│ ├── deribit.rs
│ ├── dydx.rs
│ ├── ftx.rs
│ ├── gate.rs
│ ├── huobi.rs
│ ├── kraken.rs
│ ├── kucoin.rs
│ ├── mexc.rs
│ ├── okx.rs
│ ├── utils/
│ │ └── mod.rs
│ ├── zb.rs
│ └── zbg.rs
└── rustfmt.toml
================================================
FILE CONTENTS
================================================
================================================
FILE: .config/nextest.toml
================================================
[profile.default]
slow-timeout = { period = "60s", terminate-after = 2 }
fail-fast = false
retries = 1
================================================
FILE: .editorconfig
================================================
# https://EditorConfig.org
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
# Markdown Files
[*.md]
trim_trailing_whitespace = false
# Batch Files
[*.{cmd,bat}]
end_of_line = crlf
================================================
FILE: .github/CODEOWNERS
================================================
* @soulmachine
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on: [push, pull_request]
env:
CARGO_TERM_COLOR: always
# Stop the previous CI tasks (which is deprecated)
# to conserve the runner resource.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Cargo build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- uses: actions-rs/cargo@v1
with:
command: build
args: --release --all-features
test:
name: Cargo test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- uses: taiki-e/install-action@nextest
- uses: actions-rs/cargo@v1
with:
command: build
- name: Run cargo nextest
run: |
# Run all tests except:
# * bitmex, because bitmex has very low rate limit
# * FTX, the FTX website is not operational
# * zbg, due to the "invalid peer certificate: UnknownIssuer" error
cargo nextest run -E 'all() - binary(~bitmex) - binary(~ftx) - binary(~zbg)'
# Run the '*bitmex*' tests in -j1.
cargo nextest run -E 'binary(~bitmex)' -j1 || true
doc-test:
name: Cargo doctest
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- uses: actions-rs/cargo@v1
with:
command: test
args: --doc
fmt:
name: Cargo fmt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: rustfmt
- uses: actions-rs/cargo@v1
with:
command: fmt
args: -- --check
check:
name: Cargo check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
- uses: actions-rs/cargo@v1
with:
command: check
clippy:
name: Cargo clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
override: true
components: clippy
- uses: actions-rs/cargo@v1
with:
command: clippy
================================================
FILE: .gitignore
================================================
# Generated by Cargo
# will have compiled files and executables
/target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# IDEA configurations
/.idea
*.iml
*.project
*.classpath
================================================
FILE: Cargo.toml
================================================
[workspace]
members = [
"crypto-client",
"crypto-crawler",
"crypto-markets",
"crypto-market-type",
"crypto-msg-type",
"crypto-rest-client",
"crypto-ws-client",
]
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# crypto-crawler-rs
[](https://github.com/crypto-crawler/crypto-crawler-rs/actions?query=branch%3Amain)
[](https://crates.io/crates/crypto-crawler)
[](https://docs.rs/crypto-crawler) [](https://discord.gg/Vych8DNZU2)
==========
A rock-solid cryprocurrency crawler.
## Quickstart
Use the [carbonbot](https://github.com/crypto-crawler/carbonbot) binary to crawl data.
If you need more control and customization, use this library.
## Architecture

- [crypto-crawler](./crypto-crawler) is the crawler library to crawl websocket and restful messages from exchanges
- [carbonbot](https://github.com/crypto-crawler/carbonbot) is the main CLI tool to run crawlers.
- [crypto-ws-client](./crypto-ws-client) is the underlying websocket client library, providing a set of universal APIs for different exchanges.
- [crypto-rest-client](./crypto-rest-client) is the underlying RESTful client library, providing universal APIs to get public data from different exchanges.
- [crypto-markets](./crypto-markets) is a RESTful library to retreive market meta data from cryptocurrency echanges.
- [crypto-client](./crypto-client) is a RESTful client library to place and cancel orders.
- Support multiple languages. Some libraries support multiple languages, which is achieved by first providing a FFI binding, then a languge specific wrapper. For example, `crypto-crawler` provides a C-style FFI binding first, and then provides a Python wrapper and a C++ wrapper based on the FFI binding.
## How to parse raw messages
Use the [crypto-msg-parser](https://github.com/crypto-crawler/crypto-msg-parser) library to parse raw messages.
Crawlers should always preserve the original data without any parsing.
================================================
FILE: crypto-client/Cargo.toml
================================================
[package]
name = "crypto-client"
version = "0.1.0"
authors = ["soulmachine <soulmachine@gmail.com>"]
edition = "2021"
description = "An unified restful client for all cryptocurrency exchanges."
license = "Apache-2.0"
repository = "https://github.com/crypto-crawler/crypto-crawler-rs/tree/main/crypto-client"
homepage = "https://github.com/crypto-crawler/crypto-crawler-rs/tree/main/crypto-client"
[dependencies]
reqwest = { version = "0.11.11", features = ["blocking", "json"] }
serde = { version = "1.0.140", features = ["derive"] }
serde_json = "1.0.82"
================================================
FILE: crypto-client/README.md
================================================
# crypto-client
An unified client for all cryptocurrency exchanges.
## Example
```rust
use crypto_client::{CryptoClient, MarketType};
fn main() {
let config: HashMap<&str, &str> = vec![
("eosAccount", "your-eos-account"),
("eosPrivateKey", "your-eos-private-key"),
].into_iter().collect();
let crypto_client = CryptoClient::new(config);
// buy
let transaction_id = crypto_client.place_order(
{ exchange: "Newdex", pair: "EIDOS_EOS", market_type: "Spot" },
0.00121,
9.2644,
false,
);
println!("{}", transactionId);
}
```
## Supported Exchanges
- Binance
- Huobi
- OKEx
- WhaleEx
================================================
FILE: crypto-client/src/lib.rs
================================================
/// An unified restful client for all cryptocurrency exchanges.
pub struct CryptoClient {
#[allow(dead_code)]
exchange: String,
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}
================================================
FILE: crypto-crawler/Cargo.toml
================================================
[package]
name = "crypto-crawler"
version = "4.7.9"
authors = ["soulmachine <soulmachine@gmail.com>"]
edition = "2021"
description = "A rock-solid cryprocurrency crawler."
license = "Apache-2.0"
repository = "https://github.com/crypto-crawler/crypto-crawler-rs/tree/main/crypto-crawler"
keywords = ["cryptocurrency", "blockchain", "trading"]
[dependencies]
crypto-markets = "1.3.11"
crypto-market-type = "1.1.5"
crypto-msg-parser = "2.8.26"
crypto-msg-type = "1.0.11"
crypto-pair = "2.3.13"
crypto-rest-client = "1.0.1"
crypto-ws-client = "4.12.11"
fslock = "0.2.1"
once_cell = "1.17.1"
log = "0.4.17"
rand = "0.8.5"
reqwest = { version = "0.11.14", features = ["blocking", "gzip"] }
serde = { version = "1.0.157", features = ["derive"] }
serde_json = "1.0.94"
tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread", "sync", "time"] }
[dev_dependencies]
env_logger = "0.9"
test-case = "1"
tokio = { version = "1", features = ["test-util"] }
================================================
FILE: crypto-crawler/README.md
================================================
# crypto-crawler
[](https://github.com/crypto-crawler/crypto-crawler-rs/actions?query=branch%3Amain)
[](https://crates.io/crates/crypto-crawler)
[](https://docs.rs/crypto-crawler)
==========
A rock-solid cryprocurrency crawler.
## Crawl realtime trades
```rust
use crypto_crawler::{crawl_trade, MarketType};
#[tokio::main(flavor = "multi_thread")]
async fn main() {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
for msg in rx {
println!("{}", msg);
}
});
// Crawl realtime trades for all symbols of binance inverse_swap markets
crawl_trade("binance", MarketType::InverseSwap, None, tx).await;
}
```
## Crawl realtime level2 orderbook incremental updates
```rust
use crypto_crawler::{crawl_l2_event, MarketType};
#[tokio::main(flavor = "multi_thread")]
async fn main() {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
for msg in rx {
println!("{}", msg);
}
});
// Crawl realtime level2 incremental updates for all symbols of binance inverse_swap markets
crawl_l2_event("binance", MarketType::InverseSwap, None, tx).await;
}
```
## Crawl level2 orderbook full snapshots from RESTful API
```rust
use crypto_crawler::{crawl_l2_snapshot, MarketType};
fn main() {
let (tx, rx) = std::sync::mpsc::channel();
std::thread::spawn(move || {
for msg in rx {
println!("{}", msg);
}
});
// Crawl level2 full snapshots for all symbols of binance inverse_swap markets
crawl_l2_snapshot("binance", MarketType::InverseSwap, None, tx);
}
```
## Crawl realtime level2 orderbook top-K snapshots
```rust
use crypto_crawler::{crawl_l2_topk, MarketType};
#[tokio::main(flavor = "multi_thread")]
async fn main() {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
for msg in rx {
println!("{}", msg);
}
});
// Crawl realtime level2 top-k snapshots for all symbols of binance inverse_swap markets
crawl_l2_topk("binance", MarketType::InverseSwap, None, tx).await;
}
```
## Crawl realtime level3 orderbook incremental updates
```rust
use crypto_crawler::{crawl_l3_event, MarketType};
#[tokio::main(flavor = "multi_thread")]
async fn main() {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
for msg in rx {
println!("{}", msg);
}
});
// Crawl realtime level3 updates for all symbols of CoinbasePro spot market
crawl_l3_event("coinbase_pro", MarketType::Spot, None, tx).await;
}
```
## Crawl level3 orderbook full snapshots from RESTful API
```rust
use crypto_crawler::{crawl_l3_snapshot, MarketType};
fn main() {
let (tx, rx) = std::sync::mpsc::channel();
std::thread::spawn(move || {
for msg in rx {
println!("{}", msg);
}
});
// Crawl level3 orderbook full snapshots for all symbols of CoinbasePro spot markets
crawl_l3_snapshot("coinbase_pro", MarketType::Spot, None, tx);
}
```
## Crawl realtime BBO
```rust
use crypto_crawler::{crawl_bbo, MarketType};
#[tokio::main(flavor = "multi_thread")]
async fn main() {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
for msg in rx {
println!("{}", msg);
}
});
// Crawl realtime best bid and ask messages for all symbols of binance COIN-margined perpetual markets
crawl_bbo("binance", MarketType::InverseSwap, None, tx).await;
}
```
## Crawl 24hr rolling window tickers
```rust
use crypto_crawler::{crawl_ticker, MarketType};
#[tokio::main(flavor = "multi_thread")]
async fn main() {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
for msg in rx {
println!("{}", msg);
}
});
// Crawl 24hr rolling window tickers for all symbols of binance COIN-margined perpetual markets
crawl_ticker("binance", MarketType::InverseSwap, None, tx).await;
}
```
## Crawl candlesticks(i.e., OHLCV)
```rust
use crypto_crawler::{crawl_candlestick, MarketType};
#[tokio::main(flavor = "multi_thread")]
async fn main() {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
for msg in rx {
println!("{}", msg);
}
});
// Crawl candlesticks from 1 minute to 3 minutes for all symbols of binance COIN-margined perpetual markets
crawl_candlestick("binance", MarketType::InverseSwap, None, tx).await;
}
```
## Crawl funding rates
```rust
use crypto_crawler::{crawl_funding_rate, MarketType};
#[tokio::main(flavor = "multi_thread")]
async fn main() {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
for msg in rx {
println!("{}", msg);
}
});
// Crawl funding rates for all symbols of binance COIN-margined perpetual markets
crawl_funding_rate("binance", MarketType::InverseSwap, None, tx).await;
}
```
================================================
FILE: crypto-crawler/src/crawlers/binance.rs
================================================
use core::panic;
use std::sync::mpsc::Sender;
use crate::{
crawlers::utils::crawl_event, fetch_symbols_retry, get_hot_spot_symbols, msg::Message,
utils::cmc_rank::sort_by_cmc_rank,
};
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use crypto_ws_client::*;
use super::utils::create_conversion_thread;
const EXCHANGE_NAME: &str = "binance";
pub(crate) async fn crawl_trade(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if market_type == MarketType::EuropeanOption
&& (symbols.is_none() || symbols.unwrap().is_empty())
{
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::Trade,
market_type,
tx,
);
let topics: Vec<(String, String)> = vec![
// ("TICKER_ALL".to_string(), "BTCUSDT".to_string()),
("TRADE_ALL".to_string(), "BTCUSDT_C".to_string()),
("TRADE_ALL".to_string(), "BTCUSDT_P".to_string()),
];
let ws_client = BinanceOptionWSClient::new(tx, None).await;
ws_client.subscribe(&topics).await;
ws_client.run().await;
ws_client.close().await;
} else {
crawl_event(EXCHANGE_NAME, MessageType::Trade, market_type, symbols, tx).await;
}
}
pub(crate) async fn crawl_bbo(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if symbols.is_none() || symbols.unwrap().is_empty() {
if market_type == MarketType::Spot {
// spot `!bookTicker` has been removed since December 7, 2022
let mut hot_spot_symbols = tokio::task::block_in_place(move || {
let spot_symbols = fetch_symbols_retry(EXCHANGE_NAME, market_type);
get_hot_spot_symbols(EXCHANGE_NAME, &spot_symbols)
});
sort_by_cmc_rank(EXCHANGE_NAME, &mut hot_spot_symbols);
let symbols = Some(hot_spot_symbols.as_slice());
crawl_event(EXCHANGE_NAME, MessageType::BBO, market_type, symbols, tx).await
} else {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::BBO,
market_type,
tx,
);
let commands =
vec![r#"{"id":9527,"method":"SUBSCRIBE","params":["!bookTicker"]}"#.to_string()]; // All Book Tickers Stream
match market_type {
MarketType::InverseFuture | MarketType::InverseSwap => {
let ws_client = BinanceInverseWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
MarketType::LinearFuture | MarketType::LinearSwap => {
let ws_client = BinanceLinearWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
_ => panic!("Binance {} market does NOT have the BBO channel", market_type),
}
}
} else {
crawl_event(EXCHANGE_NAME, MessageType::BBO, market_type, symbols, tx).await;
}
}
pub(crate) async fn crawl_ticker(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if symbols.is_none() || symbols.unwrap().is_empty() {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::Ticker,
market_type,
tx,
);
let commands =
vec![r#"{"id":9527,"method":"SUBSCRIBE","params":["!ticker@arr"]}"#.to_string()];
match market_type {
MarketType::Spot => {
let ws_client = BinanceSpotWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
MarketType::InverseFuture | MarketType::InverseSwap => {
let ws_client = BinanceInverseWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
MarketType::LinearFuture | MarketType::LinearSwap => {
let ws_client = BinanceLinearWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
MarketType::EuropeanOption => {
let commands = vec![
r#"{"id":9527,"method":"SUBSCRIBE","params":["BTCUSDT@TICKER_ALL"]}"#
.to_string(),
];
let ws_client = BinanceLinearWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
_ => panic!("Binance {} market does NOT have the ticker channel", market_type),
}
} else {
crawl_event(EXCHANGE_NAME, MessageType::Ticker, market_type, symbols, tx).await;
}
}
#[allow(clippy::unnecessary_unwrap)]
pub(crate) async fn crawl_funding_rate(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::FundingRate,
market_type,
tx,
);
let ws_client: Box<dyn WSClient + Send + Sync> = match market_type {
MarketType::InverseSwap => Box::new(BinanceInverseWSClient::new(tx, None).await),
MarketType::LinearSwap => Box::new(BinanceLinearWSClient::new(tx, None).await),
_ => panic!("Binance {} does NOT have funding rates", market_type),
};
if symbols.is_none() || symbols.unwrap().is_empty() {
let commands =
vec![r#"{"id":9527,"method":"SUBSCRIBE","params":["!markPrice@arr"]}"#.to_string()];
ws_client.send(&commands).await;
} else {
let topics = symbols
.unwrap()
.iter()
.map(|symbol| ("markPrice".to_string(), symbol.to_string()))
.collect::<Vec<(String, String)>>();
ws_client.subscribe(&topics).await;
};
ws_client.run().await;
ws_client.close().await;
}
================================================
FILE: crypto-crawler/src/crawlers/bitmex.rs
================================================
use super::{
crawl_candlestick_ext, crawl_event,
utils::{check_args, fetch_symbols_retry},
};
use crate::{crawlers::utils::create_conversion_thread, msg::Message};
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use crypto_ws_client::*;
use std::sync::mpsc::Sender;
const EXCHANGE_NAME: &str = "bitmex";
async fn crawl_all(msg_type: MessageType, tx: Sender<Message>) {
let tx = create_conversion_thread(EXCHANGE_NAME.to_string(), msg_type, MarketType::Unknown, tx);
let channel: &str = match msg_type {
MessageType::Trade => "trade",
MessageType::L2Event => "orderBookL2_25",
MessageType::L2TopK => "orderBook10",
MessageType::BBO => "quote",
MessageType::L2Snapshot => "orderBookL2",
MessageType::FundingRate => "funding",
_ => panic!("unsupported message type {msg_type}"),
};
let commands = vec![format!(r#"{{"op":"subscribe","args":["{channel}"]}}"#)];
let ws_client = BitmexWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
pub(crate) async fn crawl_trade(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if market_type == MarketType::Unknown {
// crawl all symbols
crawl_all(MessageType::Trade, tx).await;
} else {
crawl_event(EXCHANGE_NAME, MessageType::Trade, market_type, symbols, tx).await;
}
}
pub(crate) async fn crawl_l2_event(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if market_type == MarketType::Unknown {
// crawl all symbols
crawl_all(MessageType::L2Event, tx).await;
} else {
crawl_event(EXCHANGE_NAME, MessageType::L2Event, market_type, symbols, tx).await;
}
}
pub(crate) async fn crawl_bbo(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if market_type == MarketType::Unknown {
// crawl all symbols
crawl_all(MessageType::BBO, tx).await;
} else {
crawl_event(EXCHANGE_NAME, MessageType::BBO, market_type, symbols, tx).await;
}
}
pub(crate) async fn crawl_l2_topk(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if market_type == MarketType::Unknown {
// crawl all symbols
crawl_all(MessageType::L2TopK, tx).await;
} else {
crawl_event(EXCHANGE_NAME, MessageType::L2TopK, market_type, symbols, tx).await;
}
}
#[allow(clippy::unnecessary_unwrap)]
pub(crate) async fn crawl_funding_rate(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if market_type == MarketType::Unknown {
// crawl all symbols
crawl_all(MessageType::FundingRate, tx).await;
} else {
let is_empty = match symbols {
Some(list) => {
if list.is_empty() {
true
} else {
check_args(EXCHANGE_NAME, market_type, list);
false
}
}
None => true,
};
let real_symbols = if is_empty {
tokio::task::block_in_place(move || fetch_symbols_retry(EXCHANGE_NAME, market_type))
} else {
symbols.unwrap().to_vec()
};
if real_symbols.is_empty() {
panic!("real_symbols is empty");
}
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::FundingRate,
market_type,
tx,
);
let topics: Vec<(String, String)> =
real_symbols.iter().map(|symbol| ("funding".to_string(), symbol.to_string())).collect();
match market_type {
MarketType::InverseSwap | MarketType::QuantoSwap => {
let ws_client = BitmexWSClient::new(tx, None).await;
ws_client.subscribe(&topics).await;
ws_client.run().await;
ws_client.close().await;
}
_ => panic!("BitMEX {market_type} does NOT have funding rates"),
}
}
}
pub(crate) async fn crawl_candlestick(
market_type: MarketType,
symbol_interval_list: Option<&[(String, usize)]>,
tx: Sender<Message>,
) {
if market_type == MarketType::Unknown {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::Candlestick,
market_type,
tx,
);
let commands = vec![
r#"{"op":"subscribe","args":["tradeBin1m"]}"#.to_string(),
r#"{"op":"subscribe","args":["tradeBin5m"]}"#.to_string(),
];
let ws_client = BitmexWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
} else {
crawl_candlestick_ext(EXCHANGE_NAME, market_type, symbol_interval_list, tx).await;
}
}
================================================
FILE: crypto-crawler/src/crawlers/deribit.rs
================================================
use super::crawl_event;
use crate::{crawlers::utils::create_conversion_thread, msg::Message};
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use crypto_ws_client::*;
use std::sync::mpsc::Sender;
const EXCHANGE_NAME: &str = "deribit";
pub(crate) async fn crawl_trade(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if symbols.is_none() || symbols.unwrap().is_empty() {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::Trade,
market_type,
tx,
);
// "any" menas all, see https://docs.deribit.com/?javascript#trades-kind-currency-interval
let topics: Vec<(String, String)> = match market_type {
MarketType::InverseFuture => {
vec![("trades.future.SYMBOL.100ms".to_string(), "any".to_string())]
}
MarketType::InverseSwap => {
vec![
("trades.SYMBOL.100ms".to_string(), "BTC-PERPETUAL".to_string()),
("trades.SYMBOL.100ms".to_string(), "ETH-PERPETUAL".to_string()),
]
}
MarketType::EuropeanOption => {
vec![("trades.option.SYMBOL.100ms".to_string(), "any".to_string())]
}
_ => panic!("Deribit does NOT have the {market_type} market type"),
};
let ws_client = DeribitWSClient::new(tx, None).await;
ws_client.subscribe(&topics).await;
ws_client.run().await;
ws_client.close().await;
} else {
crawl_event(EXCHANGE_NAME, MessageType::Trade, market_type, symbols, tx).await;
}
}
================================================
FILE: crypto-crawler/src/crawlers/huobi.rs
================================================
use super::utils::fetch_symbols_retry;
use crate::{
crawlers::{crawl_event, utils::create_conversion_thread},
msg::Message,
};
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use crypto_ws_client::*;
use std::sync::mpsc::Sender;
const EXCHANGE_NAME: &str = "huobi";
#[allow(clippy::unnecessary_unwrap)]
pub(crate) async fn crawl_l2_event(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
match market_type {
MarketType::Spot => {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::L2Event,
market_type,
tx,
);
let symbols: Vec<String> = if symbols.is_none() || symbols.unwrap().is_empty() {
tokio::task::block_in_place(move || fetch_symbols_retry(EXCHANGE_NAME, market_type))
} else {
symbols.unwrap().to_vec()
};
// Huobi Spot market.$symbol.mbp.$levels must use wss://api.huobi.pro/feed
// or wss://api-aws.huobi.pro/feed
let ws_client = HuobiSpotWSClient::new(tx, Some("wss://api.huobi.pro/feed")).await;
ws_client.subscribe_orderbook(&symbols).await;
ws_client.run().await;
ws_client.close().await;
}
MarketType::InverseFuture
| MarketType::LinearSwap
| MarketType::InverseSwap
| MarketType::EuropeanOption => {
crawl_event(EXCHANGE_NAME, MessageType::L2Event, market_type, symbols, tx).await
}
_ => panic!("Huobi does NOT have the {market_type} market type"),
}
}
#[allow(clippy::unnecessary_unwrap)]
pub(crate) async fn crawl_funding_rate(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::FundingRate,
market_type,
tx,
);
let symbols: Vec<String> = if symbols.is_none() || symbols.unwrap().is_empty() {
vec!["*".to_string()]
} else {
symbols.unwrap().to_vec()
};
let commands: Vec<String> = symbols
.into_iter()
.map(|symbol| format!(r#"{{"topic":"public.{symbol}.funding_rate","op":"sub"}}"#))
.collect();
match market_type {
MarketType::InverseSwap => {
let ws_client =
HuobiInverseSwapWSClient::new(tx, Some("wss://api.hbdm.com/swap-notification"))
.await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
MarketType::LinearSwap => {
let ws_client = HuobiLinearSwapWSClient::new(
tx,
Some("wss://api.hbdm.com/linear-swap-notification"),
)
.await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
_ => panic!("Huobi {market_type} does NOT have funding rates"),
}
}
================================================
FILE: crypto-crawler/src/crawlers/kucoin.rs
================================================
use crate::{crawlers::utils::create_conversion_thread, msg::Message};
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use crypto_ws_client::*;
use std::sync::mpsc::Sender;
use super::crawl_event;
const EXCHANGE_NAME: &str = "kucoin";
pub(crate) async fn crawl_bbo(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if market_type == MarketType::Spot && (symbols.is_none() || symbols.unwrap().is_empty()) {
let tx =
create_conversion_thread(EXCHANGE_NAME.to_string(), MessageType::BBO, market_type, tx);
// https://docs.kucoin.com/#all-symbols-ticker
let commands: Vec<String> = vec![r#"{"id":"crypto-ws-client","type":"subscribe","topic":"/market/ticker:all","privateChannel":false,"response":true}"#.to_string()];
let ws_client = KuCoinSpotWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
} else {
crawl_event(EXCHANGE_NAME, MessageType::BBO, market_type, symbols, tx).await;
}
}
================================================
FILE: crypto-crawler/src/crawlers/mod.rs
================================================
#[macro_use]
mod utils;
pub(super) mod binance;
pub(super) mod bitmex;
pub(super) mod deribit;
pub(super) mod huobi;
pub(super) mod kucoin;
pub(super) mod okx;
pub(super) mod zb;
pub(super) mod zbg;
pub use utils::fetch_symbols_retry;
pub(super) use utils::{
crawl_candlestick_ext, crawl_event, crawl_open_interest, crawl_snapshot,
create_ws_client_symbol,
};
================================================
FILE: crypto-crawler/src/crawlers/okx.rs
================================================
use super::utils::fetch_symbols_retry;
use crate::{crawlers::utils::create_conversion_thread, msg::Message};
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use crypto_ws_client::*;
use std::sync::mpsc::Sender;
const EXCHANGE_NAME: &str = "okx";
#[allow(clippy::unnecessary_unwrap)]
pub(crate) async fn crawl_funding_rate(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::FundingRate,
market_type,
tx,
);
let symbols: Vec<String> = if symbols.is_none() || symbols.unwrap().is_empty() {
tokio::task::block_in_place(move || fetch_symbols_retry(EXCHANGE_NAME, market_type))
} else {
symbols.unwrap().to_vec()
};
let topics: Vec<(String, String)> =
symbols.into_iter().map(|symbol| ("funding-rate".to_string(), symbol)).collect();
match market_type {
MarketType::InverseSwap | MarketType::LinearSwap => {
let ws_client = OkxWSClient::new(tx, None).await;
ws_client.subscribe(&topics).await;
ws_client.run().await;
ws_client.close().await;
}
_ => panic!("OKX {market_type} does NOT have funding rates"),
}
}
#[deprecated(since = "4.1.2", note = "OKX open interest is fetched via HTTP for now")]
#[allow(dead_code)]
pub(crate) async fn crawl_open_interest(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::OpenInterest,
market_type,
tx,
);
let symbols = if let Some(symbols) = symbols {
if symbols.is_empty() {
tokio::task::block_in_place(move || fetch_symbols_retry(EXCHANGE_NAME, market_type))
} else {
symbols.to_vec()
}
} else {
tokio::task::block_in_place(move || fetch_symbols_retry(EXCHANGE_NAME, market_type))
};
let topics: Vec<(String, String)> =
symbols.into_iter().map(|symbol| ("open-interest".to_string(), symbol)).collect();
if market_type != MarketType::Spot {
let ws_client = OkxWSClient::new(tx, None).await;
ws_client.subscribe(&topics).await;
ws_client.run().await;
ws_client.close().await;
} else {
panic!("spot does NOT have open interest");
}
}
================================================
FILE: crypto-crawler/src/crawlers/utils.rs
================================================
use std::{
sync::{mpsc::Sender, Arc},
time::{Duration, SystemTime, UNIX_EPOCH},
};
use crate::utils::{REST_LOCKS, WS_LOCKS};
use crypto_market_type::{get_market_types, MarketType};
use crypto_markets::fetch_symbols;
use crypto_rest_client::{fetch_l2_snapshot, fetch_l3_snapshot, fetch_open_interest};
use crypto_ws_client::*;
use log::*;
use crate::{get_hot_spot_symbols, utils::cmc_rank::sort_by_cmc_rank, Message, MessageType};
pub fn fetch_symbols_retry(exchange: &str, market_type: MarketType) -> Vec<String> {
let retry_count = std::env::var("REST_RETRY_COUNT")
.unwrap_or_else(|_| "5".to_string())
.parse::<i64>()
.unwrap();
let cooldown_time = get_cooldown_time_per_request(exchange, market_type);
let lock = REST_LOCKS.get(exchange).unwrap().get(&market_type).unwrap().clone();
let mut symbols = Vec::<String>::new();
let mut backoff_factor = 1;
for i in 0..retry_count {
let mut lock_ = lock.lock().unwrap();
if !lock_.owns_lock() {
lock_.lock().unwrap();
}
match fetch_symbols(exchange, market_type) {
Ok(list) => {
symbols = list;
if lock_.owns_lock() {
lock_.unlock().unwrap();
}
break;
}
Err(err) => {
backoff_factor *= 2;
if i == retry_count - 1 {
error!("The {}th time, {}", i, err);
} else {
warn!("The {}th time, {}", i, err);
}
}
}
// Cooldown after each request, and make all other processes wait
// on the lock to avoid parallel requests, thus avoid 429 error
std::thread::sleep(cooldown_time * backoff_factor);
if lock_.owns_lock() {
lock_.unlock().unwrap();
}
}
symbols
}
pub(super) fn check_args(exchange: &str, market_type: MarketType, symbols: &[String]) {
let market_types = get_market_types(exchange);
if !market_types.contains(&market_type) {
panic!("{exchange} does NOT have the {market_type} market type");
}
let valid_symbols = fetch_symbols_retry(exchange, market_type);
let invalid_symbols: Vec<String> =
symbols.iter().filter(|symbol| !valid_symbols.contains(symbol)).cloned().collect();
if !invalid_symbols.is_empty() {
panic!(
"Invalid symbols: {}, {} {} available trading symbols are {}",
invalid_symbols.join(","),
exchange,
market_type,
valid_symbols.join(",")
);
}
}
fn get_cooldown_time_per_request(exchange: &str, market_type: MarketType) -> Duration {
let millis = match exchange {
"binance" => 500, // spot weitht 1200, contract weight 2400
"bitget" => 100, // 20 requests per 2 seconds
"bithumb" => 8 * 10, /* 135 requests per 1 second for public APIs, multiplied by 10 to */
// reduce its frequency
"bitmex" => 2000, /* 60 requests per minute on all routes (reduced to 30 when */
// unauthenticated)
"bitstamp" => 75 * 10, /* 8000 requests per 10 minutes, but bitstamp orderbook is too */
// big, need to reduce its frequency
"bitz" => 34, // no more than 30 times within 1 second
"bybit" => 20 * 10, /* 50 requests per second continuously for 2 minutes, multiplied */
// by 10 to reduce its frequency
"coinbase_pro" => 100, // 10 requests per second
"deribit" => 50, // 20 requests per second
"dydx" => 100, // 100 requests per 10 seconds
"gate" => 4, // 300 read operations per IP per second
"huobi" => 2, // 800 times/second for one IP
"kucoin" => match market_type {
MarketType::Spot => 300, // 3x to avoid 429
_ => 100, // 30 times/3s
},
"mexc" => 100, // 20 times per 2 seconds
"okx" => 100, // 20 requests per 2 seconds
_ => 100,
};
Duration::from_millis(millis)
}
/// Crawl leve2 or level3 orderbook snapshots through RESTful APIs.
pub(crate) fn crawl_snapshot(
exchange: &str,
market_type: MarketType,
msg_type: MessageType, // L2Snapshot or L3Snapshot
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
let is_empty = match symbols {
Some(list) => {
if list.is_empty() {
true
} else {
check_args(exchange, market_type, list);
false
}
}
None => true,
};
let cooldown_time = get_cooldown_time_per_request(exchange, market_type);
let lock = REST_LOCKS.get(exchange).unwrap().get(&market_type).unwrap().clone();
'outer: loop {
let mut real_symbols = if is_empty {
if market_type == MarketType::Spot {
let spot_symbols = fetch_symbols_retry(exchange, market_type);
get_hot_spot_symbols(exchange, &spot_symbols)
} else {
fetch_symbols_retry(exchange, market_type)
}
} else {
symbols.unwrap().to_vec()
};
sort_by_cmc_rank(exchange, &mut real_symbols);
let mut index = 0_usize;
let mut success_count = 0_u64;
let mut backoff_factor = 1;
// retry 5 times at most
while index < real_symbols.len() && backoff_factor < 6 {
let symbol = real_symbols[index].as_str();
let mut lock_ = lock.lock().unwrap();
if !lock_.owns_lock() {
lock_.lock().unwrap();
}
let resp = match msg_type {
MessageType::L2Snapshot => fetch_l2_snapshot(exchange, market_type, symbol, None),
MessageType::L3Snapshot => fetch_l3_snapshot(exchange, market_type, symbol, None),
_ => panic!("msg_type must be L2Snapshot or L3Snapshot"),
};
// Cooldown after each request, and make all other processes wait
// on the lock to avoid parallel requests, thus avoid 429 error
std::thread::sleep(cooldown_time);
if lock_.owns_lock() {
lock_.unlock().unwrap();
}
match resp {
Ok(msg) => {
index += 1;
success_count += 1;
backoff_factor = 1;
let message = Message::new_with_symbol(
exchange.to_string(),
market_type,
msg_type,
symbol.to_string(),
msg,
);
if tx.send(message).is_err() {
// break the loop if there is no receiver
break 'outer;
}
}
Err(err) => {
let current_timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis() as u64;
warn!(
"{} {} {} {} {} {}, error: {}, back off for {} milliseconds",
current_timestamp,
success_count,
backoff_factor,
exchange,
market_type,
symbol,
err,
(backoff_factor * cooldown_time).as_millis()
);
std::thread::sleep(backoff_factor * cooldown_time);
success_count = 0;
backoff_factor += 1;
}
}
}
std::thread::sleep(cooldown_time * 2); // if real_symbols is empty, CPU will be 100% without this line
}
}
/// Crawl open interests of all trading symbols.
pub(crate) fn crawl_open_interest(exchange: &str, market_type: MarketType, tx: Sender<Message>) {
let cooldown_time = get_cooldown_time_per_request(exchange, market_type);
let lock = REST_LOCKS.get(exchange).unwrap().get(&market_type).unwrap().clone();
'outer: loop {
match exchange {
"bitz" | "deribit" | "dydx" | "ftx" | "huobi" | "kucoin" | "okx" => {
let mut lock_ = lock.lock().unwrap();
if !lock_.owns_lock() {
lock_.lock().unwrap();
}
let resp = fetch_open_interest(exchange, market_type, None);
if let Ok(json) = resp {
if exchange == "deribit" {
// A RESTful response of deribit open_interest contains four lines
for x in json.trim().split('\n') {
let message = Message::new(
exchange.to_string(),
market_type,
MessageType::OpenInterest,
x.to_string(),
);
if tx.send(message).is_err() {
break; // break the loop if there is no receiver
}
}
} else {
let message = Message::new(
exchange.to_string(),
market_type,
MessageType::OpenInterest,
json,
);
if tx.send(message).is_err() {
break; // break the loop if there is no receiver
}
}
}
// Cooldown after each request, and make all other processes wait
// on the lock to avoid parallel requests, thus avoid 429 error
std::thread::sleep(cooldown_time);
if lock_.owns_lock() {
lock_.unlock().unwrap();
}
}
"binance" | "bitget" | "bybit" | "gate" | "zbg" => {
let real_symbols = fetch_symbols_retry(exchange, market_type);
let mut index = 0_usize;
let mut success_count = 0_u64;
let mut backoff_factor = 1;
// retry 5 times at most
while index < real_symbols.len() && backoff_factor < 6 {
let symbol = real_symbols[index].as_str();
let mut lock_ = lock.lock().unwrap();
if !lock_.owns_lock() {
lock_.lock().unwrap();
}
let resp = fetch_open_interest(exchange, market_type, Some(symbol));
// Cooldown after each request, and make all other processes wait
// on the lock to avoid parallel requests, thus avoid 429 error
std::thread::sleep(cooldown_time);
if lock_.owns_lock() {
lock_.unlock().unwrap();
}
match resp {
Ok(msg) => {
index += 1;
success_count += 1;
backoff_factor = 1;
let message = Message::new_with_symbol(
exchange.to_string(),
market_type,
MessageType::OpenInterest,
symbol.to_string(),
msg,
);
if tx.send(message).is_err() {
// break the loop if there is no receiver
break 'outer;
}
}
Err(err) => {
let current_timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_millis()
as u64;
warn!(
"{} {} {} {} {} {}, error: {}, back off for {} milliseconds",
current_timestamp,
success_count,
backoff_factor,
exchange,
market_type,
symbol,
err,
(backoff_factor * cooldown_time).as_millis()
);
std::thread::sleep(backoff_factor * cooldown_time);
success_count = 0;
backoff_factor += 1;
}
}
}
}
_ => panic!("{exchange} does NOT have open interest RESTful API"),
}
std::thread::sleep(cooldown_time * 2); // if real_symbols is empty, CPU will be 100% without this line
}
}
async fn subscribe_with_lock(
exchange: String,
market_type: MarketType,
msg_type: MessageType,
symbols: Vec<String>,
ws_client: Arc<dyn WSClient + Send + Sync>,
) {
match msg_type {
MessageType::BBO => ws_client.subscribe_bbo(&symbols).await,
MessageType::Trade => ws_client.subscribe_trade(&symbols).await,
MessageType::L2Event => ws_client.subscribe_orderbook(&symbols).await,
MessageType::L3Event => ws_client.subscribe_l3_orderbook(&symbols).await,
MessageType::L2TopK => ws_client.subscribe_orderbook_topk(&symbols).await,
MessageType::Ticker => ws_client.subscribe_ticker(&symbols).await,
_ => panic!("{exchange} {market_type} does NOT have {msg_type} websocket channel"),
};
}
fn get_connection_interval_ms(exchange: &str, _market_type: MarketType) -> Option<u64> {
match exchange {
"bitfinex" => Some(3000), /* you cannot open more than 20 connections per minute, see https://docs.bitfinex.com/docs/requirements-and-limitations#websocket-rate-limits */
// "bitmex" => Some(9000), // 40 per hour
"bitz" => Some(100), /* `cat crawler-trade-bitz-spot-error-12.log` has many "429 Too */
// Many Requests"
"kucoin" => Some(2000), /* Connection Limit: 30 per minute, see https://docs.kucoin.com/#connection-times */
"okx" => Some(1000), /* Connection limit: 1 time per second, https://www.okx.com/docs-v5/en/#websocket-api-connect */
_ => None,
}
}
fn get_num_subscriptions_per_connection(exchange: &str, market_type: MarketType) -> usize {
match exchange {
// A single connection can listen to a maximum of 200 streams
"binance" => {
if market_type == MarketType::Spot {
// https://binance-docs.github.io/apidocs/spot/en/#websocket-limits
1024
} else {
// https://binance-docs.github.io/apidocs/futures/en/#websocket-market-streams
// https://binance-docs.github.io/apidocs/delivery/en/#websocket-market-streams
200
}
} // https://binance-docs.github.io/apidocs/futures/en/#websocket-market-streams
// All websocket connections have a limit of 30 subscriptions to public market data feed
// channels
"bitfinex" => 30, // https://docs.bitfinex.com/docs/ws-general#subscribe-to-channels
"kucoin" => 300, /* Subscription limit for each connection: 300 topics, see https://docs.kucoin.com/#topic-subscription-limit */
"okx" => 256, // okx spot l2_event throws many ResetWithoutClosingHandshake errors
_ => usize::MAX, // usize::MAX means unlimited
}
}
async fn create_ws_client_internal(
exchange: &str,
market_type: MarketType,
tx: Sender<String>,
) -> Arc<dyn WSClient + Send + Sync> {
match exchange {
"binance" => match market_type {
MarketType::Spot => Arc::new(BinanceSpotWSClient::new(tx, None).await),
MarketType::InverseFuture | MarketType::InverseSwap => {
Arc::new(BinanceInverseWSClient::new(tx, None).await)
}
MarketType::LinearFuture | MarketType::LinearSwap => {
Arc::new(BinanceLinearWSClient::new(tx, None).await)
}
MarketType::EuropeanOption => Arc::new(BinanceOptionWSClient::new(tx, None).await),
_ => panic!("Binance does NOT have the {market_type} market type"),
},
"bitfinex" => Arc::new(BitfinexWSClient::new(tx, None).await),
"bitget" => match market_type {
MarketType::Spot => Arc::new(BitgetSpotWSClient::new(tx, None).await),
MarketType::InverseFuture | MarketType::InverseSwap | MarketType::LinearSwap => {
Arc::new(BitgetSwapWSClient::new(tx, None).await)
}
_ => panic!("Bitget does NOT have the {market_type} market type"),
},
"bithumb" => Arc::new(BithumbWSClient::new(tx, None).await),
"bitmex" => Arc::new(BitmexWSClient::new(tx, None).await),
"bitstamp" => Arc::new(BitstampWSClient::new(tx, None).await),
"bitz" => match market_type {
MarketType::Spot => Arc::new(BitzSpotWSClient::new(tx, None).await),
_ => panic!("Bitz does NOT have the {market_type} market type"),
},
"bybit" => match market_type {
MarketType::InverseFuture | MarketType::InverseSwap => {
Arc::new(BybitInverseWSClient::new(tx, None).await)
}
MarketType::LinearSwap => Arc::new(BybitLinearSwapWSClient::new(tx, None).await),
_ => panic!("Bybit does NOT have the {market_type} market type"),
},
"coinbase_pro" => Arc::new(CoinbaseProWSClient::new(tx, None).await),
"deribit" => Arc::new(DeribitWSClient::new(tx, None).await),
"dydx" => match market_type {
MarketType::LinearSwap => Arc::new(DydxSwapWSClient::new(tx, None).await),
_ => panic!("dYdX does NOT have the {market_type} market type"),
},
"ftx" => Arc::new(FtxWSClient::new(tx, None).await),
"gate" => match market_type {
MarketType::Spot => Arc::new(GateSpotWSClient::new(tx, None).await),
MarketType::InverseSwap => Arc::new(GateInverseSwapWSClient::new(tx, None).await),
MarketType::LinearSwap => Arc::new(GateLinearSwapWSClient::new(tx, None).await),
MarketType::InverseFuture => Arc::new(GateInverseFutureWSClient::new(tx, None).await),
MarketType::LinearFuture => Arc::new(GateLinearFutureWSClient::new(tx, None).await),
_ => panic!("Gate does NOT have the {market_type} market type"),
},
"huobi" => match market_type {
MarketType::Spot => Arc::new(HuobiSpotWSClient::new(tx, None).await),
MarketType::InverseFuture => Arc::new(HuobiFutureWSClient::new(tx, None).await),
MarketType::LinearSwap => Arc::new(HuobiLinearSwapWSClient::new(tx, None).await),
MarketType::InverseSwap => Arc::new(HuobiInverseSwapWSClient::new(tx, None).await),
MarketType::EuropeanOption => Arc::new(HuobiOptionWSClient::new(tx, None).await),
_ => panic!("Huobi does NOT have the {market_type} market type"),
},
"kraken" => match market_type {
MarketType::Spot => Arc::new(KrakenSpotWSClient::new(tx, None).await),
MarketType::InverseFuture | MarketType::InverseSwap => {
Arc::new(KrakenFuturesWSClient::new(tx, None).await)
}
_ => panic!("Kraken does NOT have the {market_type} market type"),
},
"kucoin" => match market_type {
MarketType::Spot => Arc::new(KuCoinSpotWSClient::new(tx, None).await),
MarketType::InverseSwap | MarketType::LinearSwap | MarketType::InverseFuture => {
Arc::new(KuCoinSwapWSClient::new(tx, None).await)
}
_ => panic!("KuCoin does NOT have the {market_type} market type"),
},
"mexc" => match market_type {
MarketType::Spot => Arc::new(MexcSpotWSClient::new(tx, None).await),
MarketType::LinearSwap | MarketType::InverseSwap => {
Arc::new(MexcSwapWSClient::new(tx, None).await)
}
_ => panic!("MEXC does NOT have the {market_type} market type"),
},
"okx" => Arc::new(OkxWSClient::new(tx, None).await),
"zb" => match market_type {
MarketType::Spot => Arc::new(ZbSpotWSClient::new(tx, None).await),
MarketType::LinearSwap => Arc::new(ZbSwapWSClient::new(tx, None).await),
_ => panic!("ZB does NOT have the {market_type} market type"),
},
"zbg" => match market_type {
MarketType::Spot => Arc::new(ZbgSpotWSClient::new(tx, None).await),
MarketType::InverseSwap | MarketType::LinearSwap => {
Arc::new(ZbgSwapWSClient::new(tx, None).await)
}
_ => panic!("ZBG does NOT have the {market_type} market type"),
},
_ => panic!("Unknown exchange {exchange}"),
}
}
async fn create_ws_client(
exchange: &str,
market_type: MarketType,
msg_type: MessageType,
tx: Sender<Message>,
) -> Arc<dyn WSClient + Send + Sync> {
let tx = create_conversion_thread(exchange.to_string(), msg_type, market_type, tx);
if let Some(interval) = get_connection_interval_ms(exchange, market_type) {
let lock = WS_LOCKS.get(exchange).unwrap().get(&market_type).unwrap().clone();
let mut lock = lock.lock().await;
let mut i = 0;
while !lock.owns_lock() {
i += 1;
debug!(
"{} {} {} try_lock_with_pid() the {}th time",
exchange, market_type, msg_type, i
);
if lock.try_lock_with_pid().is_ok() {
break;
} else {
tokio::time::sleep(std::time::Duration::from_millis(
rand::random::<u64>() % 90 + 11,
))
.await; // give chances to other tasks
}
}
let ws_client = create_ws_client_internal(exchange, market_type, tx).await;
tokio::time::sleep(Duration::from_millis(interval)).await;
if lock.owns_lock() {
lock.unlock().unwrap();
}
ws_client
} else {
create_ws_client_internal(exchange, market_type, tx).await
}
}
pub(crate) async fn create_ws_client_symbol(
exchange: &str,
market_type: MarketType,
tx: Sender<String>,
) -> Arc<dyn WSClient + Send + Sync> {
let tx = create_parser_thread(exchange.to_string(), market_type, tx);
create_ws_client_internal(exchange, market_type, tx).await
}
#[derive(Clone)]
struct EmptyStruct {} // for stop channel
fn create_symbol_discovery_thread(
exchange: String,
market_type: MarketType,
subscribed_symbols: Vec<String>,
mut stop_ch_rx: tokio::sync::broadcast::Receiver<EmptyStruct>,
tx: tokio::sync::mpsc::Sender<Vec<String>>, // send out new symbols
) -> tokio::task::JoinHandle<()> {
let num_topics_per_connection = get_num_subscriptions_per_connection(&exchange, market_type);
let mut subscribed_symbols = subscribed_symbols;
let mut num_subscribed_of_last_client = subscribed_symbols.len() % num_topics_per_connection;
let mut hourly = tokio::time::interval(Duration::from_secs(3600));
tokio::task::spawn(async move {
loop {
tokio::select! {
_ = stop_ch_rx.recv() => {
break;
}
_ = hourly.tick() => {
let exchange_clone = exchange.to_string();
let latest_symbols = tokio::task::block_in_place(move || {
fetch_symbols_retry(&exchange_clone, market_type)
});
let mut new_symbols: Vec<String> = latest_symbols
.iter()
.filter(|s| !subscribed_symbols.contains(s))
.cloned()
.collect();
if !new_symbols.is_empty() {
warn!("Found new symbols: {}", new_symbols.join(", "));
if tx.send(new_symbols.clone()).await.is_err() {
break; // break the loop if there is no receiver
}
num_subscribed_of_last_client += new_symbols.len();
subscribed_symbols.append(&mut new_symbols);
}
if num_subscribed_of_last_client >= num_topics_per_connection {
panic!(
"The last connection has subscribed {num_subscribed_of_last_client} topics, which is more than {num_topics_per_connection}, restarting the process",
); // pm2 will restart the whole process
}
}
}
}
})
}
fn create_new_symbol_receiver_thread(
exchange: String,
msg_type: MessageType,
market_type: MarketType,
mut symbols_rx: tokio::sync::mpsc::Receiver<Vec<String>>,
ws_client: Arc<dyn WSClient + Send + Sync>,
) -> tokio::task::JoinHandle<()> {
tokio::task::spawn(async move {
let exchange_clone = exchange;
while let Some(new_symbols) = symbols_rx.recv().await {
subscribe_with_lock(
exchange_clone.clone(),
market_type,
msg_type,
new_symbols,
ws_client.clone(),
)
.await;
}
})
}
fn create_new_symbol_receiver_thread_candlestick(
intervals: Vec<usize>,
mut rx: tokio::sync::mpsc::Receiver<Vec<String>>,
ws_client: Arc<dyn WSClient + Send + Sync>,
) -> tokio::task::JoinHandle<()> {
tokio::task::spawn(async move {
while let Some(new_symbols) = rx.recv().await {
let new_symbol_interval_list = new_symbols
.iter()
.flat_map(|symbol| {
intervals.clone().into_iter().map(move |interval| (symbol.clone(), interval))
})
.collect::<Vec<(String, usize)>>();
ws_client.subscribe_candlestick(&new_symbol_interval_list).await;
}
})
}
// create a thread to convert Sender<Message> Sender<String>
pub(crate) fn create_conversion_thread(
exchange: String,
msg_type: MessageType,
market_type: MarketType,
tx: Sender<Message>,
) -> Sender<String> {
let (tx_raw, rx_raw) = std::sync::mpsc::channel();
tokio::task::spawn_blocking(move || {
for json in rx_raw {
let msg = Message::new(exchange.clone(), market_type, msg_type, json);
if tx.send(msg).is_err() {
break; // break the loop if there is no receiver
}
}
});
tx_raw
}
// create a thread to call `crypto-msg-parser`
fn create_parser_thread(
exchange: String,
market_type: MarketType,
tx: Sender<String>,
) -> Sender<String> {
let (tx_raw, rx_raw) = std::sync::mpsc::channel::<String>();
std::thread::spawn(move || {
for json in rx_raw {
let msg_type = crypto_msg_parser::get_msg_type(&exchange, &json);
let parsed = match msg_type {
MessageType::Trade => serde_json::to_string(
&crypto_msg_parser::parse_trade(&exchange, market_type, &json).unwrap(),
)
.unwrap(),
MessageType::L2Event => {
let received_at = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis()
.try_into()
.unwrap();
serde_json::to_string(
&crypto_msg_parser::parse_l2(
&exchange,
market_type,
&json,
Some(received_at),
)
.unwrap(),
)
.unwrap()
}
_ => panic!("unknown msg type {msg_type}"),
};
if tx.send(parsed).is_err() {
break; // break the loop if there is no receiver
}
}
});
tx_raw
}
async fn crawl_event_one_chunk(
exchange: String,
market_type: MarketType,
msg_type: MessageType,
ws_client: Option<Arc<dyn WSClient + Send + Sync>>,
symbols: Vec<String>,
tx: Sender<Message>,
) -> tokio::task::JoinHandle<()> {
let ws_client = if let Some(ws_client) = ws_client {
ws_client
} else {
let tx_clone = tx.clone();
create_ws_client(&exchange, market_type, msg_type, tx_clone).await
};
{
// fire and forget
let exchange_clone = exchange.to_string();
let ws_client_clone = ws_client.clone();
tokio::task::spawn(async move {
subscribe_with_lock(exchange_clone, market_type, msg_type, symbols, ws_client_clone)
.await;
});
}
tokio::task::spawn(async move {
ws_client.run().await;
ws_client.close().await;
})
}
pub(crate) async fn crawl_event(
exchange: &str,
msg_type: MessageType,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
let num_topics_per_connection = get_num_subscriptions_per_connection(exchange, market_type);
let is_empty = match symbols {
Some(list) => {
if list.is_empty() {
true
} else {
tokio::task::block_in_place(move || check_args(exchange, market_type, list));
false
}
}
None => true,
};
let automatic_symbol_discovery = is_empty;
let real_symbols = if is_empty {
tokio::task::block_in_place(move || fetch_symbols_retry(exchange, market_type))
} else {
symbols.unwrap().to_vec()
};
if real_symbols.is_empty() {
error!("real_symbols is empty due to fetch_symbols_retry() failure");
return;
}
// The stop channel is used by all tokio tasks
let (stop_ch_tx, stop_ch_rx) = tokio::sync::broadcast::channel::<EmptyStruct>(1);
// create a thread to discover new symbols
let (tx_symbols, rx_symbols) = tokio::sync::mpsc::channel::<Vec<String>>(4);
let symbol_discovery_thread = if automatic_symbol_discovery {
let thread = create_symbol_discovery_thread(
exchange.to_string(),
market_type,
real_symbols.clone(),
stop_ch_rx,
tx_symbols,
);
Some(thread)
} else {
None
};
// create a thread to convert Sender<String> to Sender<Message>
if real_symbols.len() <= num_topics_per_connection {
let ws_client = create_ws_client(exchange, market_type, msg_type, tx).await;
subscribe_with_lock(
exchange.to_string(),
market_type,
msg_type,
real_symbols,
ws_client.clone(),
)
.await;
if automatic_symbol_discovery {
create_new_symbol_receiver_thread(
exchange.to_string(),
msg_type,
market_type,
rx_symbols,
ws_client.clone(),
);
}
ws_client.run().await;
ws_client.close().await;
} else {
// split to chunks
let mut chunks: Vec<Vec<String>> = Vec::new();
for i in (0..real_symbols.len()).step_by(num_topics_per_connection) {
let chunk = real_symbols
[i..(std::cmp::min(i + num_topics_per_connection, real_symbols.len()))]
.to_vec();
chunks.push(chunk);
}
debug!("{} {} {}", real_symbols.len(), num_topics_per_connection, chunks.len(),);
assert!(chunks.len() > 1);
let mut last_ws_client = None;
let mut handles = Vec::new();
{
let n = chunks.len();
for (i, chunk) in chunks.into_iter().enumerate() {
last_ws_client = if i == (n - 1) {
let tx_clone = tx.clone();
Some(create_ws_client(exchange, market_type, msg_type, tx_clone).await)
} else {
None
};
let ret = crawl_event_one_chunk(
exchange.to_string(),
market_type,
msg_type,
last_ws_client.clone(),
chunk,
tx.clone(),
);
handles.push(ret.await);
}
drop(tx);
}
if automatic_symbol_discovery && last_ws_client.is_some() {
create_new_symbol_receiver_thread(
exchange.to_string(),
msg_type,
market_type,
rx_symbols,
last_ws_client.unwrap(),
);
}
for handle in handles {
if let Err(err) = handle.await {
panic!("{}", err); // TODO: use tokio::task::JoinSet or futures::stream::FuturesUnordered
}
}
};
_ = stop_ch_tx.send(EmptyStruct {});
if let Some(thread) = symbol_discovery_thread {
_ = thread.await;
}
}
// from 1m to 5m
fn get_candlestick_intervals(exchange: &str, market_type: MarketType) -> Vec<usize> {
match exchange {
"binance" => vec![60, 180, 300],
"bybit" => vec![60, 180, 300],
"deribit" => vec![60, 180, 300],
"gate" => vec![10, 60, 300],
"kucoin" => match market_type {
MarketType::Spot => vec![60, 300], // Reduced to avoid Broken pipe (os error 32)
_ => vec![60, 300],
},
"okx" => vec![60, 180, 300],
"zb" => match market_type {
MarketType::Spot => vec![60, 180, 300],
MarketType::LinearSwap => vec![60, 300],
_ => vec![60, 180, 300],
},
"zbg" => match market_type {
MarketType::Spot => vec![60, 300],
_ => vec![60, 180, 300],
},
_ => vec![60, 300],
}
}
async fn crawl_candlestick_one_chunk(
exchange: String,
market_type: MarketType,
ws_client: Option<Arc<dyn WSClient + Send + Sync>>,
symbol_interval_list: Vec<(String, usize)>,
tx: Sender<Message>,
) -> tokio::task::JoinHandle<()> {
let ws_client = if let Some(ws_client) = ws_client {
ws_client
} else {
let tx_clone = tx.clone();
create_ws_client(&exchange, market_type, MessageType::Candlestick, tx_clone).await
};
{
// fire and forget
let ws_client_clone = ws_client.clone();
tokio::task::spawn(async move {
ws_client_clone.subscribe_candlestick(&symbol_interval_list).await;
});
}
tokio::task::spawn(async move {
ws_client.run().await;
ws_client.close().await;
})
}
pub(crate) async fn crawl_candlestick_ext(
exchange: &str,
market_type: MarketType,
symbol_interval_list: Option<&[(String, usize)]>,
tx: Sender<Message>,
) {
let num_topics_per_connection = get_num_subscriptions_per_connection(exchange, market_type);
let is_empty = match symbol_interval_list {
Some(list) => {
if list.is_empty() {
true
} else {
let symbols: Vec<String> = list.iter().map(|t| t.0.clone()).collect();
tokio::task::block_in_place(move || check_args(exchange, market_type, &symbols));
false
}
}
None => true,
};
let automatic_symbol_discovery = is_empty;
let symbol_interval_list: Vec<(String, usize)> = if is_empty {
let symbols =
tokio::task::block_in_place(move || fetch_symbols_retry(exchange, market_type));
let intervals = get_candlestick_intervals(exchange, market_type);
symbols
.iter()
.flat_map(|symbol| {
intervals.clone().into_iter().map(move |interval| (symbol.clone(), interval))
})
.collect::<Vec<(String, usize)>>()
} else {
symbol_interval_list.unwrap().to_vec()
};
if symbol_interval_list.is_empty() {
error!("symbol_interval_list is empty due to fetch_symbols_retry() failure");
return;
}
let real_symbols: Vec<String> = symbol_interval_list.iter().map(|t| t.0.clone()).collect();
let real_intervals: Vec<usize> = symbol_interval_list.iter().map(|t| t.1).collect();
// The stop channel is used by all tokio tasks
let (stop_ch_tx, stop_ch_rx) = tokio::sync::broadcast::channel::<EmptyStruct>(1);
// create a thread to discover new symbols
let (tx_symbols, rx_symbols) = tokio::sync::mpsc::channel::<Vec<String>>(4);
let symbol_discovery_thread = if automatic_symbol_discovery {
let thread = create_symbol_discovery_thread(
exchange.to_string(),
market_type,
real_symbols,
stop_ch_rx,
tx_symbols,
);
Some(thread)
} else {
None
};
if symbol_interval_list.len() <= num_topics_per_connection {
let ws_client = create_ws_client(exchange, market_type, MessageType::Candlestick, tx).await;
ws_client.subscribe_candlestick(&symbol_interval_list).await;
if automatic_symbol_discovery {
create_new_symbol_receiver_thread_candlestick(
real_intervals,
rx_symbols,
ws_client.clone(),
);
}
ws_client.run().await;
ws_client.close().await;
} else {
// split to chunks
let mut chunks: Vec<Vec<(String, usize)>> = Vec::new();
{
for i in (0..symbol_interval_list.len()).step_by(num_topics_per_connection) {
let chunk: Vec<(String, usize)> = symbol_interval_list
[i..(std::cmp::min(i + num_topics_per_connection, symbol_interval_list.len()))]
.to_vec();
chunks.push(chunk);
}
}
debug!("{} {} {}", symbol_interval_list.len(), num_topics_per_connection, chunks.len(),);
assert!(chunks.len() > 1);
let mut last_ws_client = None;
let mut handles = Vec::new();
{
let n = chunks.len();
for (i, chunk) in chunks.into_iter().enumerate() {
last_ws_client = if i == (n - 1) {
let tx_clone = tx.clone();
Some(
create_ws_client(exchange, market_type, MessageType::Candlestick, tx_clone)
.await,
)
} else {
None
};
let ret = crawl_candlestick_one_chunk(
exchange.to_string(),
market_type,
last_ws_client.clone(),
chunk,
tx.clone(),
);
handles.push(ret.await);
}
drop(tx);
}
if automatic_symbol_discovery && last_ws_client.is_some() {
create_new_symbol_receiver_thread_candlestick(
real_intervals,
rx_symbols,
last_ws_client.unwrap(),
);
}
for handle in handles {
if let Err(err) = handle.await {
panic!("{}", err); // TODO: use tokio::task::JoinSet or futures::stream::FuturesUnordered
}
}
};
_ = stop_ch_tx.send(EmptyStruct {});
if let Some(thread) = symbol_discovery_thread {
_ = thread.await;
}
}
================================================
FILE: crypto-crawler/src/crawlers/zb.rs
================================================
use std::sync::mpsc::Sender;
use crate::{crawlers::utils::crawl_event, msg::Message};
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use crypto_ws_client::*;
use super::utils::create_conversion_thread;
const EXCHANGE_NAME: &str = "zb";
pub(crate) async fn crawl_ticker(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if market_type == MarketType::LinearSwap && (symbols.is_none() || symbols.unwrap().is_empty()) {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::Ticker,
market_type,
tx,
);
let commands: Vec<String> =
vec![r#"{"action": "subscribe","channel": "All.Ticker"}"#.to_string()];
let ws_client = ZbSwapWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
} else {
crawl_event(EXCHANGE_NAME, MessageType::Ticker, market_type, symbols, tx).await;
}
}
================================================
FILE: crypto-crawler/src/crawlers/zbg.rs
================================================
use std::sync::mpsc::Sender;
use crate::{crawlers::utils::crawl_event, msg::Message};
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use crypto_ws_client::*;
use super::utils::create_conversion_thread;
const EXCHANGE_NAME: &str = "zbg";
pub(crate) async fn crawl_ticker(
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
if symbols.is_none() || symbols.unwrap().is_empty() {
if market_type == MarketType::Spot {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::Ticker,
market_type,
tx,
);
let commands: Vec<String> =
vec![r#"{"action":"ADD", "dataType":"ALL_TRADE_STATISTIC_24H"}"#.to_string()];
let ws_client = ZbgSpotWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
} else {
let tx = create_conversion_thread(
EXCHANGE_NAME.to_string(),
MessageType::Ticker,
market_type,
tx,
);
let commands: Vec<String> =
vec![r#"{"action":"sub", "topic":"future_all_indicator"}"#.to_string()];
let ws_client = ZbgSwapWSClient::new(tx, None).await;
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
} else {
crawl_event(EXCHANGE_NAME, MessageType::Ticker, market_type, symbols, tx).await;
}
}
================================================
FILE: crypto-crawler/src/lib.rs
================================================
//! A rock-solid cryprocurrency crawler.
//!
//! ## Crawl realtime trades
//!
//! ```rust
//! use crypto_crawler::{crawl_trade, MarketType};
//!
//! #[tokio::main(flavor = "multi_thread")]
//! async fn main() {
//! let (tx, rx) = std::sync::mpsc::channel();
//! tokio::task::spawn(async move {
//! // Crawl realtime trades for all symbols of binance inverse_swap markets
//! crawl_trade("binance", MarketType::InverseSwap, None, tx).await;
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! }
//! ```
//!
//! ## Crawl realtime level2 orderbook incremental updates
//!
//! ```rust
//! use crypto_crawler::{crawl_l2_event, MarketType};
//!
//! #[tokio::main(flavor = "multi_thread")]
//! async fn main() {
//! let (tx, rx) = std::sync::mpsc::channel();
//! tokio::task::spawn(async move {
//! // Crawl realtime level2 incremental updates for all symbols of binance inverse_swap markets
//! crawl_l2_event("binance", MarketType::InverseSwap, None, tx).await;
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! }
//! ```
//!
//! ## Crawl level2 orderbook full snapshots from RESTful API
//!
//! ```rust
//! use crypto_crawler::{crawl_l2_snapshot, MarketType};
//!
//! let (tx, rx) = std::sync::mpsc::channel();
//! std::thread::spawn(move || {
//! // Crawl level2 full snapshots for all symbols of binance inverse_swap markets
//! crawl_l2_snapshot("binance", MarketType::InverseSwap, None, tx);
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! ```
//!
//! ## Crawl realtime level2 orderbook top-K snapshots
//!
//! ```rust
//! use crypto_crawler::{crawl_l2_topk, MarketType};
//!
//! #[tokio::main(flavor = "multi_thread")]
//! async fn main() {
//! let (tx, rx) = std::sync::mpsc::channel();
//! tokio::task::spawn(async move {
//! // Crawl realtime level2 top-k snapshots for all symbols of binance inverse_swap markets
//! crawl_l2_topk("binance", MarketType::InverseSwap, None, tx).await;
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! }
//! ```
//!
//! ## Crawl realtime level3 orderbook incremental updates
//!
//! ```rust
//! use crypto_crawler::{crawl_l3_event, MarketType};
//!
//! #[tokio::main(flavor = "multi_thread")]
//! async fn main() {
//! let (tx, rx) = std::sync::mpsc::channel();
//! tokio::task::spawn(async move {
//! // Crawl realtime level3 updates for all symbols of CoinbasePro spot market
//! crawl_l3_event("coinbase_pro", MarketType::Spot, None, tx).await;
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! }
//! ```
//!
//! ## Crawl level3 orderbook full snapshots from RESTful API
//!
//! ```rust
//! use crypto_crawler::{crawl_l3_snapshot, MarketType};
//!
//! let (tx, rx) = std::sync::mpsc::channel();
//! std::thread::spawn(move || {
//! // Crawl level3 orderbook full snapshots for all symbols of CoinbasePro spot markets
//! crawl_l3_snapshot("coinbase_pro", MarketType::Spot, None, tx);
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! ```
//!
//! ## Crawl realtime BBO
//!
//! ```rust
//! use crypto_crawler::{crawl_bbo, MarketType};
//!
//! #[tokio::main(flavor = "multi_thread")]
//! async fn main() {
//! let (tx, rx) = std::sync::mpsc::channel();
//! tokio::task::spawn(async move {
//! // Crawl realtime best bid and ask messages for all symbols of binance COIN-margined perpetual markets
//! crawl_bbo("binance", MarketType::InverseSwap, None, tx).await;
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! }
//! ```
//!
//! ## Crawl 24hr rolling window tickers
//!
//! ```rust
//! use crypto_crawler::{crawl_ticker, MarketType};
//!
//! #[tokio::main(flavor = "multi_thread")]
//! async fn main() {
//! let (tx, rx) = std::sync::mpsc::channel();
//! tokio::task::spawn(async move {
//! // Crawl 24hr rolling window tickers for all symbols of binance COIN-margined perpetual markets
//! crawl_ticker("binance", MarketType::InverseSwap, None, tx).await;
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! }
//! ```
//!
//! ## Crawl candlesticks(i.e., OHLCV)
//!
//! ```rust
//! use crypto_crawler::{crawl_candlestick, MarketType};
//!
//! #[tokio::main(flavor = "multi_thread")]
//! async fn main() {
//! let (tx, rx) = std::sync::mpsc::channel();
//! tokio::task::spawn(async move {
//! // Crawl candlesticks from 1 minute to 3 minutes for all symbols of binance COIN-margined perpetual markets
//! crawl_candlestick("binance", MarketType::InverseSwap, None, tx).await;
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! }
//! ```
//!
//! ## Crawl funding rates
//!
//! ```rust
//! use crypto_crawler::{crawl_funding_rate, MarketType};
//!
//! #[tokio::main(flavor = "multi_thread")]
//! async fn main() {
//! let (tx, rx) = std::sync::mpsc::channel();
//! tokio::task::spawn(async move {
//! // Crawl funding rates for all symbols of binance COIN-margined perpetual markets
//! crawl_funding_rate("binance", MarketType::InverseSwap, None, tx).await;
//! });
//!
//! let mut messages = Vec::new();
//! for msg in rx {
//! messages.push(msg);
//! break;
//! }
//! assert!(!messages.is_empty());
//! }
//! ```
mod crawlers;
mod msg;
mod utils;
use std::sync::mpsc::Sender;
pub use crawlers::fetch_symbols_retry;
pub use crypto_market_type::MarketType;
pub use crypto_msg_type::MessageType;
pub use msg::*;
pub use utils::get_hot_spot_symbols;
/// Crawl realtime trades.
///
/// If `symbols` is None or empty, this API will crawl realtime trades for all
/// symbols in the `market_type` market, and launch a thread to discover new
/// symbols every hour. And so forth for all other APIs.
pub async fn crawl_trade(
exchange: &str,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
match exchange {
"binance" => crawlers::binance::crawl_trade(market_type, symbols, tx).await,
"bitmex" => crawlers::bitmex::crawl_trade(market_type, symbols, tx).await,
"deribit" => crawlers::deribit::crawl_trade(market_type, symbols, tx).await,
"bitfinex" | "bitget" | "bithumb" | "bitstamp" | "bitz" | "bybit" | "coinbase_pro"
| "dydx" | "ftx" | "gate" | "huobi" | "kraken" | "kucoin" | "mexc" | "okx" | "zb"
| "zbg" => {
crawlers::crawl_event(exchange, MessageType::Trade, market_type, symbols, tx).await
}
_ => panic!("{exchange} does NOT have the trade websocket channel"),
}
}
/// Crawl level2 orderbook update events.
pub async fn crawl_l2_event(
exchange: &str,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
match exchange {
"bitmex" => crawlers::bitmex::crawl_l2_event(market_type, symbols, tx).await,
"huobi" => crawlers::huobi::crawl_l2_event(market_type, symbols, tx).await,
"binance" | "bitfinex" | "bitget" | "bithumb" | "bitstamp" | "bitz" | "bybit"
| "coinbase_pro" | "deribit" | "dydx" | "ftx" | "gate" | "kraken" | "kucoin" | "mexc"
| "okx" | "zb" | "zbg" => {
crawlers::crawl_event(exchange, MessageType::L2Event, market_type, symbols, tx).await
}
_ => panic!("{exchange} does NOT have the incremental level2 websocket channel"),
}
}
/// Crawl level3 orderbook update events.
pub async fn crawl_l3_event(
exchange: &str,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
match exchange {
"bitfinex" | "bitstamp" | "coinbase_pro" | "kucoin" => {
crawlers::crawl_event(exchange, MessageType::L3Event, market_type, symbols, tx).await
}
_ => panic!("{exchange} does NOT have the incremental level3 websocket channel"),
}
}
/// Crawl level2 orderbook snapshots through RESTful APIs.
pub fn crawl_l2_snapshot(
exchange: &str,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
crawlers::crawl_snapshot(exchange, market_type, MessageType::L2Snapshot, symbols, tx);
}
/// Crawl best bid and ask.
pub async fn crawl_bbo(
exchange: &str,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
match exchange {
"binance" => crawlers::binance::crawl_bbo(market_type, symbols, tx).await,
"bitmex" => crawlers::bitmex::crawl_bbo(market_type, symbols, tx).await,
"kucoin" => crawlers::kucoin::crawl_bbo(market_type, symbols, tx).await,
"deribit" | "ftx" | "gate" | "huobi" | "kraken" | "okx" => {
crawlers::crawl_event(exchange, MessageType::BBO, market_type, symbols, tx).await
}
_ => panic!("{exchange} does NOT have BBO websocket channel"),
}
}
/// Crawl level2 orderbook top-k snapshots through websocket.
pub async fn crawl_l2_topk(
exchange: &str,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
match exchange {
"bitmex" => crawlers::bitmex::crawl_l2_topk(market_type, symbols, tx).await,
"binance" | "bitget" | "bybit" | "bitstamp" | "deribit" | "gate" | "huobi" | "kucoin"
| "mexc" | "okx" | "zb" => {
crawlers::crawl_event(exchange, MessageType::L2TopK, market_type, symbols, tx).await
}
_ => panic!("{exchange} does NOT have the level2 top-k snapshot websocket channel"),
}
}
/// Crawl level3 orderbook snapshots through RESTful APIs.
pub fn crawl_l3_snapshot(
exchange: &str,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
crawlers::crawl_snapshot(exchange, market_type, MessageType::L3Snapshot, symbols, tx)
}
/// Crawl 24hr rolling window ticker.
///
/// If `symbols` is None, it means all trading symbols in the `market_type`,
/// and updates the latest symbols every hour.
pub async fn crawl_ticker(
exchange: &str,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
match exchange {
"binance" => crawlers::binance::crawl_ticker(market_type, symbols, tx).await,
"bitfinex" | "bitget" | "bithumb" | "bitz" | "bybit" | "coinbase_pro" | "deribit"
| "gate" | "huobi" | "kraken" | "kucoin" | "mexc" | "okx" => {
crawlers::crawl_event(exchange, MessageType::Ticker, market_type, symbols, tx).await
}
"zb" => crawlers::zb::crawl_ticker(market_type, symbols, tx).await,
"zbg" => crawlers::zbg::crawl_ticker(market_type, symbols, tx).await,
_ => panic!("{exchange} does NOT have the ticker websocket channel"),
}
}
/// Crawl perpetual swap funding rates.
pub async fn crawl_funding_rate(
exchange: &str,
market_type: MarketType,
symbols: Option<&[String]>,
tx: Sender<Message>,
) {
match exchange {
"binance" => crawlers::binance::crawl_funding_rate(market_type, symbols, tx).await,
"bitmex" => crawlers::bitmex::crawl_funding_rate(market_type, symbols, tx).await,
"huobi" => crawlers::huobi::crawl_funding_rate(market_type, symbols, tx).await,
"okx" => crawlers::okx::crawl_funding_rate(market_type, symbols, tx).await,
_ => panic!("{exchange} does NOT have perpetual swap market"),
}
}
/// Crawl candlestick(i.e., OHLCV) data.
///
/// If `symbol_interval_list` is None or empty, this API will crawl candlesticks
/// from 10 seconds to 3 minutes(if available) for all symbols.
pub async fn crawl_candlestick(
exchange: &str,
market_type: MarketType,
symbol_interval_list: Option<&[(String, usize)]>,
tx: Sender<Message>,
) {
match exchange {
"bitmex" => {
crawlers::bitmex::crawl_candlestick(market_type, symbol_interval_list, tx).await
}
"binance" | "bitfinex" | "bitget" | "bitz" | "bybit" | "deribit" | "gate" | "huobi"
| "kraken" | "kucoin" | "mexc" | "okx" | "zb" | "zbg" => {
crawlers::crawl_candlestick_ext(exchange, market_type, symbol_interval_list, tx).await
}
_ => panic!("{exchange} does NOT have the candlestick websocket channel"),
};
}
/// Crawl all open interest.
pub fn crawl_open_interest(exchange: &str, market_type: MarketType, tx: Sender<Message>) {
crawlers::crawl_open_interest(exchange, market_type, tx);
}
/// Subscribe to multiple message types of one symbol.
///
/// This API is suitable for client applications such as APP, website, etc.
///
/// String messages in `tx` are already parsed by `crypto-msg-parser`.
pub async fn subscribe_symbol(
exchange: &str,
market_type: MarketType,
symbol: &str,
msg_types: &[MessageType],
tx: Sender<String>,
) {
let ws_client = crawlers::create_ws_client_symbol(exchange, market_type, tx).await;
let symbols = vec![symbol.to_string()];
let commands = crypto_msg_type::get_ws_commands(exchange, msg_types, &symbols, true, None);
ws_client.send(&commands).await;
ws_client.run().await;
ws_client.close().await;
}
================================================
FILE: crypto-crawler/src/msg.rs
================================================
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use serde::{Deserialize, Serialize};
use std::{
convert::TryInto,
str::FromStr,
time::{SystemTime, UNIX_EPOCH},
};
/// Message represents messages received by crawlers.
#[derive(Serialize, Deserialize)]
pub struct Message {
/// The exchange name, unique for each exchage
pub exchange: String,
/// Market type
pub market_type: MarketType,
/// Message type
pub msg_type: MessageType,
#[serde(skip_serializing_if = "Option::is_none")]
pub symbol: Option<String>,
/// Unix timestamp in milliseconds
pub received_at: u64,
/// the original message
pub json: String,
}
impl Message {
pub fn new(
exchange: String,
market_type: MarketType,
msg_type: MessageType,
json: String,
) -> Self {
Message {
exchange,
market_type,
msg_type,
symbol: None,
received_at: SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis()
.try_into()
.unwrap(),
json: json.trim().to_string(),
}
}
pub fn new_with_symbol(
exchange: String,
market_type: MarketType,
msg_type: MessageType,
symbol: String,
json: String,
) -> Self {
let mut msg = Self::new(exchange, market_type, msg_type, json);
msg.symbol = Some(symbol);
msg
}
/// Convert to a TSV string.
///
/// The `exchange`, `market_type` and `msg_type` fields are not included to
/// save some disk space.
pub fn to_tsv_string(&self) -> String {
let symbol = if let Some(symbol) = self.symbol.clone() { symbol } else { "".to_string() };
format!("{}\t{}\t{}", self.received_at, symbol, self.json)
}
/// Convert from a TSV string.
pub fn from_tsv_string(exchange: &str, market_type: &str, msg_type: &str, s: &str) -> Self {
let v: Vec<&str> = s.split('\t').collect();
assert_eq!(3, v.len());
let market_type = MarketType::from_str(market_type).unwrap();
let msg_type = MessageType::from_str(msg_type).unwrap();
let symbol = if v[1].is_empty() { None } else { Some(v[1].to_string()) };
Message {
exchange: exchange.to_string(),
market_type,
msg_type,
symbol,
received_at: v[0].parse::<u64>().unwrap(),
json: v[2].to_string(),
}
}
}
impl std::fmt::Display for Message {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", serde_json::to_string(self).unwrap())
}
}
================================================
FILE: crypto-crawler/src/utils/cmc_rank.rs
================================================
use reqwest::header;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use once_cell::sync::Lazy;
pub(super) static CMC_RANKS: Lazy<HashMap<String, u64>> = Lazy::new(|| {
// offline data, in case the network is down
let offline: HashMap<String, u64> = vec![
("BTC", 1),
("ETH", 2),
("USDT", 3),
("BNB", 4),
("USDC", 5),
("XRP", 6),
("ADA", 7),
("BUSD", 8),
("MATIC", 9),
("DOGE", 10),
("SOL", 11),
("DOT", 12),
("SHIB", 13),
("LTC", 14),
("TRX", 15),
("AVAX", 16),
("DAI", 17),
("UNI", 18),
("WBTC", 19),
("LINK", 20),
("ATOM", 21),
("LEO", 22),
("OKB", 23),
("ETC", 24),
("TON", 25),
("XMR", 26),
("FIL", 27),
("BCH", 28),
("LDO", 29),
("XLM", 30),
("APT", 31),
("CRO", 32),
("NEAR", 33),
("VET", 34),
("HBAR", 35),
("APE", 36),
("ALGO", 37),
("ICP", 38),
("QNT", 39),
("GRT", 40),
("FTM", 41),
("FLOW", 42),
("EGLD", 43),
("MANA", 44),
("THETA", 45),
("EOS", 46),
("BIT", 47),
("AAVE", 48),
("XTZ", 49),
("AXS", 50),
("SAND", 51),
("STX", 52),
("TUSD", 53),
("LUNC", 54),
("RPL", 55),
("KLAY", 56),
("CHZ", 57),
("USDP", 58),
("NEO", 59),
("HT", 60),
("KCS", 61),
("BSV", 62),
("IMX", 63),
("MINA", 64),
("DASH", 65),
("CAKE", 66),
("FXS", 67),
("MKR", 68),
("CRV", 69),
("ZEC", 70),
("USDD", 71),
("MIOTA", 72),
("OP", 73),
("XEC", 74),
("BTT", 75),
("SNX", 76),
("GMX", 77),
("GUSD", 78),
("CFX", 79),
("GT", 80),
("TWT", 81),
("RUNE", 82),
("ZIL", 83),
("PAXG", 84),
("AGIX", 85),
("LRC", 86),
("ENJ", 87),
("OSMO", 88),
("1INCH", 89),
("FLR", 90),
("DYDX", 91),
("BAT", 92),
("SSV", 94),
("BONE", 95),
("CVX", 96),
("FEI", 97),
("ANKR", 98),
("CSPR", 99),
("ETHW", 100),
("BNX", 101),
("NEXO", 102),
("ROSE", 103),
("RVN", 104),
("LUNA", 105),
("CELO", 106),
("HNT", 107),
("COMP", 108),
("TFUEL", 109),
("XEM", 110),
("XDC", 111),
("KAVA", 112),
("RNDR", 113),
("HOT", 114),
("WOO", 115),
("YFI", 116),
("FET", 117),
("QTUM", 118),
("MOB", 119),
("DCR", 120),
("MAGIC", 121),
("T", 122),
("AR", 123),
("BLUR", 124),
("AUDIO", 125),
("KSM", 126),
("BAL", 127),
("ASTR", 128),
("ENS", 129),
("BTG", 130),
("SUSHI", 131),
("JASMY", 132),
("ONE", 133),
("GALA", 134),
("WAVES", 135),
("GNO", 136),
("USTC", 137),
("GLM", 138),
("IOTX", 139),
("INJ", 140),
("JST", 141),
("GLMR", 142),
("XCH", 143),
("MASK", 144),
("BAND", 145),
("AMP", 146),
("KDA", 147),
("OCEAN", 148),
("ICX", 149),
("OMG", 150),
("RSR", 151),
("ELON", 152),
("SC", 153),
("FLUX", 154),
("GMT", 155),
("ZRX", 156),
("CHSB", 157),
("ONT", 158),
("BICO", 159),
("XCN", 160),
("IOST", 161),
("XYM", 162),
("HIVE", 163),
("DAO", 164),
("LPT", 165),
("SKL", 166),
("ACH", 167),
("CKB", 168),
("SYN", 169),
("BORA", 170),
("WAXP", 171),
("SFP", 172),
("DGB", 173),
("STORJ", 174),
("SXP", 175),
("POLY", 176),
("EVER", 177),
("STG", 178),
("ZEN", 179),
("ILV", 180),
("KEEP", 181),
("ELF", 182),
("RLC", 183),
("LSK", 184),
("UMA", 185),
("KNC", 186),
("METIS", 187),
("CELR", 188),
("MC", 189),
("SLP", 190),
("PUNDIX", 191),
("BTRST", 192),
("RIF", 193),
("TRAC", 194),
("PLA", 195),
("EWT", 196),
("MED", 197),
("SYS", 198),
("SCRT", 199),
("NFT", 200),
("HEX", 201),
("WTRX", 202),
("stETH", 203),
("BTCB", 204),
("TMG", 205),
("WBNB", 206),
("FRAX", 207),
("HBTC", 208),
("BTTOLD", 209),
("TNC", 210),
("WEMIX", 211),
("BGB", 212),
("FTT", 213),
("XRD", 214),
("XAUT", 215),
("FLOKI", 216),
("NXM", 217),
("BabyDoge", 218),
("USDJ", 219),
("ASTRAFER", 220),
("LN", 221),
("DFI", 222),
("BRISE", 223),
("MV", 224),
("LUSD", 225),
("EDGT", 226),
("ANY", 227),
("ALI", 228),
("WEVER", 229),
("COCOS", 230),
("TEL", 231),
("LYXe", 232),
("MULTI", 233),
("KAS", 234),
("BDX", 235),
("CORE", 236),
("RON", 237),
("VVS", 238),
("PEOPLE", 239),
("HFT", 240),
("EURS", 241),
("MX", 242),
("API3", 243),
("AXL", 244),
("VGX", 245),
("GTC", 246),
("RBN", 247),
("CHR", 248),
("XNO", 249),
("DENT", 250),
("CVC", 251),
("LQTY", 252),
("CEL", 253),
("POLYX", 254),
("HOOK", 255),
("XTN", 256),
]
.into_iter()
.map(|x| (x.0.to_string(), x.1))
.collect();
let online = get_cmc_ranks(1024);
if online.is_empty() { offline } else { online }
});
fn http_get(url: &str) -> Result<String, reqwest::Error> {
let mut headers = header::HeaderMap::new();
headers.insert(header::CONTENT_TYPE, header::HeaderValue::from_static("application/json"));
let client = reqwest::blocking::Client::builder()
.default_headers(headers)
.user_agent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36")
.gzip(true)
.build()?;
let response = client.get(url).send()?;
match response.error_for_status() {
Ok(resp) => Ok(resp.text()?),
Err(error) => Err(error),
}
}
// Returns a map of coin to cmcRank.
fn get_cmc_ranks(limit: i64) -> HashMap<String, u64> {
let mut mapping: HashMap<String, u64> = HashMap::new();
let url = format!(
"https://api.coinmarketcap.com/data-api/v3/cryptocurrency/listing?start=1&limit={limit}&sortBy=market_cap&sortType=desc&convert=USD&cryptoType=all&tagType=all&audited=false"
);
if let Ok(txt) = http_get(&url) {
if let Ok(json_obj) = serde_json::from_str::<HashMap<String, Value>>(&txt) {
if let Some(data) = json_obj.get("data") {
#[derive(Serialize, Deserialize)]
#[allow(non_snake_case)]
struct Currency {
id: i64,
name: String,
symbol: String,
cmcRank: u64,
}
let arr = data["cryptoCurrencyList"].as_array().unwrap();
for currency in arr {
let currency: Currency = serde_json::from_value(currency.clone()).unwrap();
mapping.insert(currency.symbol, currency.cmcRank);
}
}
}
}
mapping
}
pub(crate) fn sort_by_cmc_rank(exchange: &str, symbols: &mut [String]) {
symbols.sort_by_key(|symbol| {
if let Some(pair) = crypto_pair::normalize_pair(symbol, exchange) {
let base = pair.split('/').next().unwrap();
*CMC_RANKS.get(base).unwrap_or(&u64::max_value())
} else {
u64::max_value()
}
});
}
#[cfg(test)]
mod tests {
use crypto_market_type::MarketType;
#[test]
fn test_get_cmc_ranks() {
let mapping = super::get_cmc_ranks(256);
let mut v = Vec::from_iter(mapping);
v.sort_by(|&(_, a), &(_, b)| a.cmp(&b));
for (coin, rank) in v {
println!("(\"{coin}\", {rank}),");
}
}
#[test]
fn test_sort_by_cmc_rank() {
let mut binance_linear_swap =
crypto_markets::fetch_symbols("binance", MarketType::LinearSwap).unwrap();
super::sort_by_cmc_rank("binance", &mut binance_linear_swap);
assert_eq!("BTCUSDT", binance_linear_swap[0]);
assert_eq!("BTCBUSD", binance_linear_swap[1]);
assert_eq!("ETHUSDT", binance_linear_swap[2]);
assert_eq!("ETHBUSD", binance_linear_swap[3]);
}
}
================================================
FILE: crypto-crawler/src/utils/lock.rs
================================================
use std::{collections::HashMap, sync::Arc};
use crypto_market_type::MarketType;
use fslock::LockFile;
use once_cell::sync::Lazy;
const EXCHANGES: &[&str] = &[
"binance",
"bitfinex",
"bitget",
"bithumb",
"bitmex",
"bitstamp",
"bitz",
"bybit",
"coinbase_pro",
"deribit",
"dydx",
"ftx",
"gate",
"huobi",
"kraken",
"kucoin",
"mexc",
"okx",
"zb",
"zbg",
];
const EXCHANGES_WS: &[&str] = &["bitfinex", "bitz", "kucoin", "okx"];
#[allow(clippy::type_complexity)]
pub(crate) static REST_LOCKS: Lazy<
HashMap<String, HashMap<MarketType, Arc<std::sync::Mutex<LockFile>>>>,
> = Lazy::new(create_all_lock_files_rest);
#[allow(clippy::type_complexity)]
pub(crate) static WS_LOCKS: Lazy<
HashMap<String, HashMap<MarketType, Arc<tokio::sync::Mutex<LockFile>>>>,
> = Lazy::new(create_all_lock_files_ws);
/// Markets with the same endpoint will have the same file name.
fn get_lock_file_name(exchange: &str, market_type: MarketType, prefix: &str) -> String {
let filename = match exchange {
"binance" => match market_type {
MarketType::InverseSwap | MarketType::InverseFuture => {
"binance_inverse.lock".to_string()
}
MarketType::LinearSwap | MarketType::LinearFuture => "binance_linear.lock".to_string(),
MarketType::Spot => "binance_spot.lock".to_string(),
MarketType::EuropeanOption => "binance_option.lock".to_string(),
_ => panic!("Unknown market_type {market_type} of {exchange}"),
},
"bitfinex" => "bitfinex.lock".to_string(),
"bitget" => match market_type {
MarketType::InverseFuture | MarketType::InverseSwap | MarketType::LinearSwap => {
"bitget_swap.lock".to_string()
}
MarketType::Spot => "bitget_spot.lock".to_string(),
_ => panic!("Unknown market_type {market_type} of {exchange}"),
},
"bitmex" => "bitmex.lock".to_string(),
"bitz" => match market_type {
MarketType::InverseSwap | MarketType::LinearSwap => "bitz_swap.lock".to_string(),
MarketType::Spot => "bitz_spot.lock".to_string(),
_ => panic!("Unknown market_type {market_type} of {exchange}"),
},
"bybit" => {
if prefix == "rest" {
"bybit.lock".to_string()
} else {
match market_type {
MarketType::InverseSwap | MarketType::InverseFuture => {
"bybit_inverse.lock".to_string()
}
MarketType::LinearSwap => "bybit_linear.lock".to_string(),
_ => panic!("Unknown market_type {market_type} of {exchange}"),
}
}
}
"deribit" => "deribit.lock".to_string(),
"ftx" => "ftx.lock".to_string(),
"gate" => match market_type {
MarketType::InverseSwap | MarketType::LinearSwap => "gate_swap.lock".to_string(),
MarketType::InverseFuture | MarketType::LinearFuture => "gate_future.lock".to_string(),
MarketType::Spot => "gate_spot.lock".to_string(),
_ => panic!("Unknown market_type {market_type} of {exchange}"),
},
"kucoin" => {
if prefix == "ws" {
"kucoin.lock".to_string()
} else {
match market_type {
MarketType::InverseSwap
| MarketType::LinearSwap
| MarketType::InverseFuture => "kucoin_swap.lock".to_string(),
MarketType::Spot => "kucoin_spot.lock".to_string(),
MarketType::Unknown => "kucoin_unknown.lock".to_string(), // for OpenInterest
_ => panic!("Unknown market_type {market_type} of {exchange}"),
}
}
}
"mexc" => match market_type {
MarketType::InverseSwap | MarketType::LinearSwap => "mexc_swap.lock".to_string(),
MarketType::Spot => "mexc_spot.lock".to_string(),
_ => panic!("Unknown market_type {market_type} of {exchange}"),
},
"okx" => "okx.lock".to_string(),
"zb" => match market_type {
MarketType::LinearSwap => "zb_swap.lock".to_string(),
MarketType::Spot => "zb_spot.lock".to_string(),
_ => panic!("Unknown market_type {market_type} of {exchange}"),
},
"zbg" => match market_type {
MarketType::InverseSwap | MarketType::LinearSwap => "zbg_swap.lock".to_string(),
MarketType::Spot => "zbg_spot.lock".to_string(),
_ => panic!("Unknown market_type {market_type} of {exchange}"),
},
_ => format!("{exchange}.{market_type}.lock"),
};
format!("{prefix}.{filename}")
}
fn create_lock_file(filename: &str) -> LockFile {
let dir = if std::env::var("DATA_DIR").is_ok() {
std::path::Path::new(std::env::var("DATA_DIR").unwrap().as_str()).join("locks")
} else {
std::env::temp_dir().join("locks")
};
let _ = std::fs::create_dir_all(&dir);
let file_path = dir.join(filename);
LockFile::open(file_path.as_path())
.unwrap_or_else(|_| panic!("{}", file_path.to_str().unwrap().to_string()))
}
fn create_all_lock_files_rest()
-> HashMap<String, HashMap<MarketType, Arc<std::sync::Mutex<LockFile>>>> {
let prefix = "rest";
// filename -> lock
let mut cache: HashMap<String, Arc<std::sync::Mutex<LockFile>>> = HashMap::new();
let mut result: HashMap<String, HashMap<MarketType, Arc<std::sync::Mutex<LockFile>>>> =
HashMap::new();
for exchange in EXCHANGES.iter() {
let m = result.entry(exchange.to_string()).or_insert_with(HashMap::new);
let mut market_types = crypto_market_type::get_market_types(exchange);
if *exchange == "bitmex" {
market_types.push(MarketType::Unknown);
}
if *exchange == "deribit" {
market_types.push(MarketType::Unknown);
}
if prefix == "rest" && (*exchange == "ftx" || *exchange == "kucoin") {
market_types.push(MarketType::Unknown); // for OpenInterest
}
for market_type in market_types {
let filename = get_lock_file_name(exchange, market_type, prefix);
let lock_file = cache
.entry(filename.clone())
.or_insert_with(|| Arc::new(std::sync::Mutex::new(create_lock_file(&filename))));
m.insert(market_type, lock_file.clone());
}
}
result
}
fn create_all_lock_files_ws()
-> HashMap<String, HashMap<MarketType, Arc<tokio::sync::Mutex<LockFile>>>> {
let prefix = "ws";
// filename -> lock
let mut cache: HashMap<String, Arc<tokio::sync::Mutex<LockFile>>> = HashMap::new();
let mut result: HashMap<String, HashMap<MarketType, Arc<tokio::sync::Mutex<LockFile>>>> =
HashMap::new();
for exchange in EXCHANGES_WS.iter() {
let m = result.entry(exchange.to_string()).or_insert_with(HashMap::new);
let mut market_types = crypto_market_type::get_market_types(exchange);
if *exchange == "bitmex" {
market_types.push(MarketType::Unknown);
}
if prefix == "rest" && (*exchange == "ftx" || *exchange == "kucoin") {
market_types.push(MarketType::Unknown); // for OpenInterest
}
for market_type in market_types {
let filename = get_lock_file_name(exchange, market_type, prefix);
let lock_file = cache
.entry(filename.clone())
.or_insert_with(|| Arc::new(tokio::sync::Mutex::new(create_lock_file(&filename))));
m.insert(market_type, lock_file.clone());
}
}
result
}
================================================
FILE: crypto-crawler/src/utils/mod.rs
================================================
pub(crate) mod cmc_rank;
mod lock;
pub(crate) mod spot_symbols;
pub(crate) use lock::{REST_LOCKS, WS_LOCKS};
pub use spot_symbols::get_hot_spot_symbols;
================================================
FILE: crypto-crawler/src/utils/spot_symbols.rs
================================================
use std::collections::HashSet;
use crypto_market_type::MarketType;
pub fn get_hot_spot_symbols(exchange: &str, spot_symbols: &[String]) -> Vec<String> {
let market_types = crypto_market_type::get_market_types(exchange);
let cmc_ranks = &super::cmc_rank::CMC_RANKS;
let contract_base_coins = {
let mut contract_base_coins = HashSet::<String>::new();
for market_type in market_types.iter().filter(|m| *m != &MarketType::Spot) {
let symbols = crypto_markets::fetch_symbols(exchange, *market_type).unwrap_or_default();
for symbol in symbols {
let pair = crypto_pair::normalize_pair(&symbol, exchange).unwrap();
let base_coin = pair.split('/').next().unwrap();
contract_base_coins.insert(base_coin.to_string());
}
}
contract_base_coins
};
let is_hot = |symbol: &str| {
let pair = crypto_pair::normalize_pair(symbol, exchange).unwrap();
let base_coin = pair.split('/').next().unwrap();
contract_base_coins.contains(base_coin)
|| *cmc_ranks.get(base_coin).unwrap_or(&u64::max_value()) <= 100
};
spot_symbols.iter().cloned().filter(|symbol| is_hot(symbol)).collect()
}
#[cfg(test)]
mod tests {
use crypto_market_type::MarketType;
use super::get_hot_spot_symbols;
#[test]
fn test_binance() {
let spot_symbols = crypto_markets::fetch_symbols("binance", MarketType::Spot).unwrap();
let symbols = get_hot_spot_symbols("binance", &spot_symbols);
assert!(!symbols.is_empty());
}
#[test]
fn test_huobi() {
let spot_symbols = crypto_markets::fetch_symbols("huobi", MarketType::Spot).unwrap();
let symbols = get_hot_spot_symbols("huobi", &spot_symbols);
assert!(!symbols.is_empty());
}
#[test]
fn test_okx() {
let spot_symbols = crypto_markets::fetch_symbols("okx", MarketType::Spot).unwrap();
let symbols = get_hot_spot_symbols("okx", &spot_symbols);
assert!(!symbols.is_empty());
}
}
================================================
FILE: crypto-crawler/tests/binance.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "binance";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::LinearFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTCUSDT")]
#[test_case(MarketType::InverseFuture, "BTCUSD_221230")]
#[test_case(MarketType::LinearFuture, "BTCUSDT_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_PERP")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
// #[test_case(MarketType::EuropeanOption, "BTC-220610-30000-C"; "ignore")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTCUSDT")]
#[test_case(MarketType::InverseFuture, "BTCUSD_221230")]
#[test_case(MarketType::LinearFuture, "BTCUSDT_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_PERP")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
// #[test_case(MarketType::EuropeanOption, "BTC-220610-30000-C"; "ignore")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "BTCUSDT")]
#[test_case(MarketType::InverseFuture, "BTCUSD_221230")]
#[test_case(MarketType::LinearFuture, "BTCUSDT_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_PERP")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
// #[test_case(MarketType::EuropeanOption, "BTC-220610-30000-C"; "ignore")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_bbo, EXCHANGE_NAME, market_type, symbol, MessageType::BBO)
}
#[test_case(MarketType::Spot, "BTCUSDT")]
#[test_case(MarketType::InverseFuture, "BTCUSD_221230")]
#[test_case(MarketType::LinearFuture, "BTCUSDT_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_PERP")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
// #[test_case(MarketType::EuropeanOption, "BTC-220610-30000-C"; "ignore")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_topk, EXCHANGE_NAME, market_type, symbol, MessageType::L2TopK)
}
#[test_case(MarketType::Spot, "BTCUSDT")]
#[test_case(MarketType::InverseFuture, "BTCUSD_221230")]
#[test_case(MarketType::LinearFuture, "BTCUSDT_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_PERP")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
// #[test_case(MarketType::EuropeanOption, "BTC-220610-30000-C")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::LinearFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
// #[test_case(MarketType::EuropeanOption)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "BTCUSDT")]
#[test_case(MarketType::InverseFuture, "BTCUSD_221230")]
#[test_case(MarketType::LinearFuture, "BTCUSDT_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_PERP")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
// #[test_case(MarketType::EuropeanOption, "BTC-220610-30000-C"; "ignore")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::InverseSwap, "BTCUSD_PERP")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_funding_rate(market_type: MarketType, symbol: &str) {
test_one_symbol!(
crawl_funding_rate,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::FundingRate
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::LinearFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
// #[test_case(MarketType::Spot, "BTCUSDT")]
// #[test_case(MarketType::InverseFuture, "BTCUSD_221230")]
// #[test_case(MarketType::LinearFuture, "BTCUSDT_221230")]
// #[test_case(MarketType::InverseSwap, "BTCUSD_PERP")]
// #[test_case(MarketType::LinearSwap, "BTCUSDT")]
// #[test_case(MarketType::EuropeanOption, "BTC-220610-30000-C"; "ignore")]
// #[tokio::test(flavor = "multi_thread")]
// async fn test_subscribe_symbol(market_type: MarketType, symbol: &str) {
// gen_test_subscribe_symbol!(EXCHANGE_NAME, market_type, symbol)
// }
================================================
FILE: crypto-crawler/tests/bitfinex.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "bitfinex";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "tBTCUSD")]
#[test_case(MarketType::LinearSwap, "tBTCF0:USTF0")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "tBTCUSD")]
#[test_case(MarketType::LinearSwap, "tBTCF0:USTF0")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "tBTCUSD")]
#[test_case(MarketType::LinearSwap, "tBTCF0:USTF0")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "tBTCUSD")]
#[test_case(MarketType::LinearSwap, "tBTCF0:USTF0")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l3_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l3_event, EXCHANGE_NAME, market_type, symbol, MessageType::L3Event)
}
#[test_case(MarketType::Spot, "tBTCUSD")]
#[test_case(MarketType::LinearSwap, "tBTCF0:USTF0")]
fn test_crawl_l3_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l3_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L3Snapshot
)
}
#[test_case(MarketType::Spot, "tBTCUSD")]
#[test_case(MarketType::LinearSwap, "tBTCF0:USTF0")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
================================================
FILE: crypto-crawler/tests/bitget.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "bitget";
// #[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
// #[test_case(MarketType::InverseFuture, "BTCUSD_DMCBL_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_DMCBL")]
#[test_case(MarketType::LinearSwap, "BTCUSDT_UMCBL")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
// #[test_case(MarketType::InverseFuture, "BTCUSD_DMCBL_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_DMCBL")]
#[test_case(MarketType::LinearSwap, "BTCUSDT_UMCBL")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
// #[test_case(MarketType::InverseFuture, "BTCUSD_DMCBL_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_DMCBL")]
#[test_case(MarketType::LinearSwap, "BTCUSDT_UMCBL")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_topk, EXCHANGE_NAME, market_type, symbol, MessageType::L2TopK)
}
#[test_case(MarketType::Spot, "BTCUSDT_SPBL")]
#[test_case(MarketType::InverseFuture, "BTCUSD_DMCBL_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_DMCBL")]
#[test_case(MarketType::LinearSwap, "BTCUSDT_UMCBL")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
// #[test_case(MarketType::InverseFuture, "BTCUSD_DMCBL_221230")]
#[test_case(MarketType::InverseSwap, "BTCUSD_DMCBL")]
#[test_case(MarketType::LinearSwap, "BTCUSDT_UMCBL")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
// #[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 16)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
================================================
FILE: crypto-crawler/tests/bithumb.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "bithumb";
#[test_case(MarketType::Spot)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
================================================
FILE: crypto-crawler/tests/bitmex.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "bitmex";
async fn crawl_all(msg_type: MessageType) {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
match msg_type {
MessageType::Trade => {
crawl_trade(EXCHANGE_NAME, MarketType::Unknown, None, tx).await;
}
MessageType::L2Event => {
crawl_l2_event(EXCHANGE_NAME, MarketType::Unknown, None, tx).await;
}
MessageType::L2Snapshot => {
tokio::task::block_in_place(move || {
crawl_l2_snapshot(EXCHANGE_NAME, MarketType::Unknown, None, tx);
});
}
MessageType::BBO => {
crawl_bbo(EXCHANGE_NAME, MarketType::Unknown, None, tx).await;
}
MessageType::L2TopK => {
crawl_l2_topk(EXCHANGE_NAME, MarketType::Unknown, None, tx).await;
}
MessageType::FundingRate => {
crawl_funding_rate(EXCHANGE_NAME, MarketType::Unknown, None, tx).await;
}
_ => panic!("unsupported message type {msg_type}"),
};
});
let msg = rx.recv().unwrap();
assert_eq!(msg.exchange, EXCHANGE_NAME.to_string());
assert_eq!(msg.market_type, MarketType::Unknown);
assert_eq!(msg.msg_type, msg_type);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade_all() {
crawl_all(MessageType::Trade).await;
}
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event_all() {
crawl_all(MessageType::L2Event).await;
}
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_bbo_all() {
crawl_all(MessageType::BBO).await;
}
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk_all() {
crawl_all(MessageType::L2TopK).await;
}
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_snapshot_all() {
crawl_all(MessageType::L2Snapshot).await;
}
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_funding_rate_all() {
crawl_all(MessageType::FundingRate).await;
}
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_candlestick_rate_all() {
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
crawl_candlestick(EXCHANGE_NAME, MarketType::Unknown, None, tx).await;
});
let msg = rx.recv().unwrap();
assert_eq!(msg.exchange, EXCHANGE_NAME.to_string());
assert_eq!(msg.market_type, MarketType::Unknown);
assert_eq!(msg.msg_type, MessageType::Candlestick);
}
#[test_case(MarketType::InverseSwap, "XBTUSD")]
#[test_case(MarketType::QuantoSwap, "ETHUSD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
// #[test_case(MarketType::InverseSwap, "XBTUSD")]
// fn test_subscribe_symbol(market_type: MarketType, symbol: &str) {
// gen_test_subscribe_symbol!(EXCHANGE_NAME, market_type, symbol)
// }
================================================
FILE: crypto-crawler/tests/bitstamp.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "bitstamp";
#[test_case(MarketType::Spot)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "btcusd")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "btcusd")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "btcusd")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_topk, EXCHANGE_NAME, market_type, symbol, MessageType::L2TopK)
}
#[test_case(MarketType::Spot, "btcusd")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "btcusd")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l3_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l3_event, EXCHANGE_NAME, market_type, symbol, MessageType::L3Event)
}
#[test_case(MarketType::Spot, "btcusd")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l3_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l3_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L3Snapshot
)
}
================================================
FILE: crypto-crawler/tests/bitz.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "bitz";
#[test_case(MarketType::Spot, "btc_usdt"; "inconclusive")]
// #[test_case(MarketType::InverseSwap, "BTC_USD")]
// #[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "btc_usdt"; "inconclusive")]
// #[test_case(MarketType::InverseSwap, "BTC_USD")]
// #[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "btc_usdt"; "inconclusive spot")]
#[test_case(MarketType::InverseSwap, "BTC_USD"; "inconclusive inverse_swap")]
#[test_case(MarketType::LinearSwap, "BTC_USDT"; "inconclusive linear_swap")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot; "inconclusive spot")]
#[test_case(MarketType::InverseSwap; "inconclusive inverse_swap")]
#[test_case(MarketType::LinearSwap; "inconclusive linear_swap")]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "btc_usdt"; "inconclusive")]
// #[test_case(MarketType::InverseSwap, "BTC_USD")]
// #[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::Spot; "inconclusive")]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
================================================
FILE: crypto-crawler/tests/bybit.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "bybit";
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::InverseFuture, "BTCUSDZ22")]
#[test_case(MarketType::InverseSwap, "BTCUSD")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::InverseFuture, "BTCUSDZ22")]
#[test_case(MarketType::InverseSwap, "BTCUSD")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::InverseFuture, "BTCUSDZ22")]
#[test_case(MarketType::InverseSwap, "BTCUSD")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::InverseFuture, "BTCUSDZ22")]
#[test_case(MarketType::InverseSwap, "BTCUSD")]
#[test_case(MarketType::LinearSwap, "BTCUSDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
// #[test_case(MarketType::InverseFuture, "BTCUSDZ22")]
// #[test_case(MarketType::InverseSwap, "BTCUSD")]
// #[test_case(MarketType::LinearSwap, "BTCUSDT")]
// fn test_subscribe_symbol(market_type: MarketType, symbol: &str) {
// gen_test_subscribe_symbol!(EXCHANGE_NAME, market_type, symbol)
// }
================================================
FILE: crypto-crawler/tests/coinbase_pro.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "coinbase_pro";
#[test_case(MarketType::Spot)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC-USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC-USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "BTC-USD")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "BTC-USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l3_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l3_event, EXCHANGE_NAME, market_type, symbol, MessageType::L3Event)
}
#[test_case(MarketType::Spot, "BTC-USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l3_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l3_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L3Snapshot
)
}
#[test_case(MarketType::Spot, "BTC-USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
================================================
FILE: crypto-crawler/tests/deribit.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "deribit";
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::EuropeanOption)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::InverseSwap, "BTC-PERPETUAL")]
// #[test_case(MarketType::InverseFuture, "BTC-30DEC22")]
// #[test_case(MarketType::EuropeanOption, "BTC-30DEC22-25000-C")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::InverseSwap, "BTC-PERPETUAL")]
#[test_case(MarketType::InverseFuture, "BTC-30DEC22")]
#[test_case(MarketType::EuropeanOption, "BTC-30DEC22-25000-C")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::InverseSwap, "BTC-PERPETUAL")]
#[test_case(MarketType::InverseFuture, "BTC-30DEC22")]
#[test_case(MarketType::EuropeanOption, "BTC-30DEC22-25000-C")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_bbo, EXCHANGE_NAME, market_type, symbol, MessageType::BBO)
}
#[test_case(MarketType::InverseSwap, "BTC-PERPETUAL")]
#[test_case(MarketType::InverseFuture, "BTC-30DEC22")]
#[test_case(MarketType::EuropeanOption, "BTC-30DEC22-25000-C")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_topk, EXCHANGE_NAME, market_type, symbol, MessageType::L2TopK)
}
#[test_case(MarketType::InverseSwap, "BTC-PERPETUAL")]
#[test_case(MarketType::InverseFuture, "BTC-30DEC22")]
#[test_case(MarketType::EuropeanOption, "BTC-30DEC22-25000-C")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::EuropeanOption; "inconclusive")]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::InverseSwap, "BTC-PERPETUAL")]
#[test_case(MarketType::InverseFuture, "BTC-30DEC22")]
#[test_case(MarketType::EuropeanOption, "BTC-30DEC22-25000-C")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::EuropeanOption)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
// #[test_case(MarketType::InverseSwap, "BTC-PERPETUAL")]
// #[test_case(MarketType::InverseFuture, "BTC-30DEC22")]
// #[test_case(MarketType::EuropeanOption, "BTC-30DEC22-25000-C")]
// fn test_subscribe_symbol(market_type: MarketType, symbol: &str) {
// gen_test_subscribe_symbol!(EXCHANGE_NAME, market_type, symbol)
// }
================================================
FILE: crypto-crawler/tests/dydx.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "dydx";
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::LinearSwap, "BTC-USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::LinearSwap, "BTC-USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::LinearSwap)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
================================================
FILE: crypto-crawler/tests/ftx.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "ftx";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::LinearFuture)]
// #[test_case(MarketType::Move)]
// #[test_case(MarketType::BVOL)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC/USD")]
#[test_case(MarketType::LinearSwap, "BTC-PERP")]
#[test_case(MarketType::LinearFuture, "BTC-1230")]
// #[test_case(MarketType::Move, "BTC-MOVE-2022Q4")]
// #[test_case(MarketType::BVOL, "BVOL/USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC/USD")]
#[test_case(MarketType::LinearSwap, "BTC-PERP")]
#[test_case(MarketType::LinearFuture, "BTC-1230")]
#[test_case(MarketType::Move, "BTC-MOVE-2022Q4")]
#[test_case(MarketType::BVOL, "BVOL/USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "BTC/USD")]
#[test_case(MarketType::LinearSwap, "BTC-PERP")]
#[test_case(MarketType::LinearFuture, "BTC-1230")]
#[test_case(MarketType::Move, "BTC-MOVE-2022Q4")]
#[test_case(MarketType::BVOL, "BVOL/USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_bbo, EXCHANGE_NAME, market_type, symbol, MessageType::BBO)
}
#[test_case(MarketType::Spot, "BTC/USD")]
#[test_case(MarketType::LinearSwap, "BTC-PERP")]
#[test_case(MarketType::LinearFuture, "BTC-1230")]
#[test_case(MarketType::Move, "BTC-MOVE-2022Q4")]
#[test_case(MarketType::BVOL, "BVOL/USD")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::LinearFuture)]
#[test_case(MarketType::Move)]
#[test_case(MarketType::BVOL)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
// #[test_case(MarketType::Spot, "BTC/USD")]
// #[test_case(MarketType::LinearSwap, "BTC-PERP")]
// #[test_case(MarketType::LinearFuture, "BTC-1230")]
// fn test_subscribe_symbol(market_type: MarketType, symbol: &str) {
// gen_test_subscribe_symbol!(EXCHANGE_NAME, market_type, symbol)
// }
================================================
FILE: crypto-crawler/tests/gate.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "gate";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
// #[test_case(MarketType::InverseFuture)]
// #[test_case(MarketType::LinearFuture)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC_USDT")]
// #[test_case(MarketType::InverseSwap, "BTC_USD")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
// #[test_case(MarketType::InverseFuture, "BTC_USD_20221230"; "ignore")]
// #[test_case(MarketType::LinearFuture, "BTC_USDT_20221230"; "ignore")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC_USDT")]
#[test_case(MarketType::InverseSwap, "BTC_USD")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[test_case(MarketType::InverseFuture, "BTC_USD_20221230")]
#[test_case(MarketType::LinearFuture, "BTC_USDT_20221230")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "BTC_USDT")]
#[test_case(MarketType::InverseSwap, "BTC_USD")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_bbo, EXCHANGE_NAME, market_type, symbol, MessageType::BBO)
}
#[test_case(MarketType::Spot, "BTC_USDT")]
#[test_case(MarketType::InverseSwap, "BTC_USD")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[test_case(MarketType::InverseFuture, "BTC_USD_20221230")]
#[test_case(MarketType::LinearFuture, "BTC_USDT_20221230")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::LinearFuture)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "BTC_USDT")]
#[test_case(MarketType::InverseSwap, "BTC_USD")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
// #[test_case(MarketType::InverseFuture, "BTC_USD_20221230")]
#[test_case(MarketType::LinearFuture, "BTC_USDT_20221230")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
// #[test_case(MarketType::Spot; "inconclusive due to too many symbols")]
#[test_case(MarketType::InverseSwap)]
// #[test_case(MarketType::LinearSwap)] // always timeout in Github workflow
// #[test_case(MarketType::InverseFuture)]
// #[test_case(MarketType::LinearFuture)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
================================================
FILE: crypto-crawler/tests/huobi.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "huobi";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "btcusdt")]
#[test_case(MarketType::InverseFuture, "BTC_CQ")]
#[test_case(MarketType::InverseSwap, "BTC-USD")]
#[test_case(MarketType::LinearSwap, "BTC-USDT")]
#[test_case(MarketType::EuropeanOption, "BTC-USDT-210625-P-27000"; "inconclusive")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "btcusdt")]
#[test_case(MarketType::InverseFuture, "BTC_CQ")]
#[test_case(MarketType::InverseSwap, "BTC-USD")]
#[test_case(MarketType::LinearSwap, "BTC-USDT")]
#[test_case(MarketType::EuropeanOption, "BTC-USDT-210625-P-27000"; "inconclusive")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "btcusdt")]
#[test_case(MarketType::InverseFuture, "BTC_CQ")]
#[test_case(MarketType::InverseSwap, "BTC-USD")]
#[test_case(MarketType::LinearSwap, "BTC-USDT")]
#[test_case(MarketType::EuropeanOption, "BTC-USDT-210625-P-27000"; "inconclusive")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_bbo, EXCHANGE_NAME, market_type, symbol, MessageType::BBO)
}
#[test_case(MarketType::Spot, "btcusdt")]
#[test_case(MarketType::InverseFuture, "BTC_CQ")]
#[test_case(MarketType::InverseSwap, "BTC-USD")]
#[test_case(MarketType::LinearSwap, "BTC-USDT")]
#[test_case(MarketType::EuropeanOption, "BTC-USDT-210625-P-27000"; "inconclusive")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_topk, EXCHANGE_NAME, market_type, symbol, MessageType::L2TopK)
}
#[test_case(MarketType::Spot, "btcusdt")]
#[test_case(MarketType::InverseFuture, "BTC_CQ")]
#[test_case(MarketType::InverseSwap, "BTC-USD")]
#[test_case(MarketType::LinearSwap, "BTC-USDT")]
#[test_case(MarketType::EuropeanOption, "BTC-USDT-210625-P-27000"; "inconclusive")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::EuropeanOption; "inconclusive")]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::InverseSwap, "BTC-USD")]
#[test_case(MarketType::LinearSwap, "BTC-USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_funding_rate(market_type: MarketType, symbol: &str) {
test_one_symbol!(
crawl_funding_rate,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::FundingRate
)
}
#[test_case(MarketType::Spot, "btcusdt")]
#[test_case(MarketType::InverseFuture, "BTC_CQ")]
#[test_case(MarketType::InverseSwap, "BTC-USD")]
#[test_case(MarketType::LinearSwap, "BTC-USDT")]
#[test_case(MarketType::EuropeanOption, "BTC-USDT-210625-P-27000"; "inconclusive")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::EuropeanOption; "inconclusive")]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
// #[test_case(MarketType::Spot, "btcusdt")]
// #[test_case(MarketType::InverseFuture, "BTC_CQ")]
// #[test_case(MarketType::InverseSwap, "BTC-USD")]
// #[test_case(MarketType::LinearSwap, "BTC-USDT")]
// fn test_subscribe_symbol(market_type: MarketType, symbol: &str) {
// gen_test_subscribe_symbol!(EXCHANGE_NAME, market_type, symbol)
// }
================================================
FILE: crypto-crawler/tests/kraken.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "kraken";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "XBT/USD")]
#[test_case(MarketType::InverseFuture, "FI_XBTUSD_221230")]
#[test_case(MarketType::InverseSwap, "PI_XBTUSD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "XBT/USD")]
#[test_case(MarketType::InverseFuture, "FI_XBTUSD_221230")]
#[test_case(MarketType::InverseSwap, "PI_XBTUSD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "XBT/USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_bbo, EXCHANGE_NAME, market_type, symbol, MessageType::BBO)
}
#[test_case(MarketType::Spot, "XBT/USD")]
#[test_case(MarketType::InverseFuture, "FI_XBTUSD_221230")]
#[test_case(MarketType::InverseSwap, "PI_XBTUSD")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::InverseSwap)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "XBT/USD")]
#[test_case(MarketType::InverseFuture, "FI_XBTUSD_221230")]
#[test_case(MarketType::InverseSwap, "PI_XBTUSD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::Spot)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
================================================
FILE: crypto-crawler/tests/kucoin.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "kucoin";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
// #[test_case(MarketType::InverseSwap, "XBTUSDM")]
#[test_case(MarketType::LinearSwap, "XBTUSDTM")]
// #[test_case(MarketType::InverseFuture, "XBTMZ22"; "ignore")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseSwap, "XBTUSDM")]
#[test_case(MarketType::LinearSwap, "XBTUSDTM")]
#[test_case(MarketType::InverseFuture, "XBTMZ22")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseSwap, "XBTUSDM")]
#[test_case(MarketType::LinearSwap, "XBTUSDTM")]
#[test_case(MarketType::InverseFuture, "XBTMZ22")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_bbo, EXCHANGE_NAME, market_type, symbol, MessageType::BBO)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseSwap, "XBTUSDM")]
#[test_case(MarketType::LinearSwap, "XBTUSDTM")]
#[test_case(MarketType::InverseFuture, "XBTMZ22")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_topk, EXCHANGE_NAME, market_type, symbol, MessageType::L2TopK)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseSwap, "XBTUSDM")]
#[test_case(MarketType::LinearSwap, "XBTUSDTM")]
#[test_case(MarketType::InverseFuture, "XBTMZ22")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::InverseFuture)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
// #[test_case(MarketType::Spot, "BTC-USDT"; "ignore")]
#[test_case(MarketType::InverseSwap, "XBTUSDM")]
#[test_case(MarketType::LinearSwap, "XBTUSDTM")]
#[test_case(MarketType::InverseFuture, "XBTMZ22")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l3_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l3_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L3Snapshot
)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseSwap, "XBTUSDM")]
#[test_case(MarketType::LinearSwap, "XBTUSDTM")]
#[test_case(MarketType::InverseFuture, "XBTMZ22")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
// #[test_case(MarketType::InverseFuture)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
================================================
FILE: crypto-crawler/tests/mexc.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "mexc";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC_USDT")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[test_case(MarketType::InverseSwap, "BTC_USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC_USDT")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[test_case(MarketType::InverseSwap, "BTC_USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "BTC_USDT")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[test_case(MarketType::InverseSwap, "BTC_USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_topk, EXCHANGE_NAME, market_type, symbol, MessageType::L2TopK)
}
#[test_case(MarketType::Spot, "BTC_USDT")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[test_case(MarketType::InverseSwap, "BTC_USD")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::InverseSwap)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[test_case(MarketType::InverseSwap, "BTC_USD")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::InverseSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
================================================
FILE: crypto-crawler/tests/okx.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "okx";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::LinearFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::EuropeanOption)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseFuture, "BTC-USD-221230")]
#[test_case(MarketType::LinearFuture, "BTC-USDT-221230")]
#[test_case(MarketType::InverseSwap, "BTC-USD-SWAP")]
#[test_case(MarketType::LinearSwap, "BTC-USDT-SWAP")]
// #[test_case(MarketType::EuropeanOption, "BTC-USD-221230-10000-P"; "ignore")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseFuture, "BTC-USD-221230")]
#[test_case(MarketType::LinearFuture, "BTC-USDT-221230")]
#[test_case(MarketType::InverseSwap, "BTC-USD-SWAP")]
#[test_case(MarketType::LinearSwap, "BTC-USDT-SWAP")]
#[test_case(MarketType::EuropeanOption, "BTC-USD-221230-10000-P")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseFuture, "BTC-USD-221230")]
#[test_case(MarketType::LinearFuture, "BTC-USDT-221230")]
#[test_case(MarketType::InverseSwap, "BTC-USD-SWAP")]
#[test_case(MarketType::LinearSwap, "BTC-USDT-SWAP")]
#[test_case(MarketType::EuropeanOption, "BTC-USD-221230-10000-P")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_topk, EXCHANGE_NAME, market_type, symbol, MessageType::L2TopK)
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseFuture, "BTC-USD-221230")]
#[test_case(MarketType::LinearFuture, "BTC-USDT-221230")]
#[test_case(MarketType::InverseSwap, "BTC-USD-SWAP")]
#[test_case(MarketType::LinearSwap, "BTC-USDT-SWAP")]
#[test_case(MarketType::EuropeanOption, "BTC-USD-221230-10000-P")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::LinearFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::EuropeanOption)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::InverseSwap, "BTC-USD-SWAP")]
#[test_case(MarketType::LinearSwap, "BTC-USDT-SWAP")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_funding_rate(market_type: MarketType, symbol: &str) {
test_one_symbol!(
crawl_funding_rate,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::FundingRate
)
}
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::LinearFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::EuropeanOption)]
fn test_crawl_open_interest(market_type: MarketType) {
let (tx, rx) = std::sync::mpsc::channel();
std::thread::spawn(move || {
crawl_open_interest(EXCHANGE_NAME, market_type, tx);
});
let msg = rx.recv().unwrap();
assert_eq!(msg.exchange, EXCHANGE_NAME.to_string());
assert_eq!(msg.market_type, market_type);
assert_eq!(msg.msg_type, MessageType::OpenInterest);
assert!(parse(msg));
}
#[test_case(MarketType::Spot, "BTC-USDT")]
#[test_case(MarketType::InverseFuture, "BTC-USD-221230")]
#[test_case(MarketType::LinearFuture, "BTC-USDT-221230")]
#[test_case(MarketType::InverseSwap, "BTC-USD-SWAP")]
#[test_case(MarketType::LinearSwap, "BTC-USDT-SWAP")]
#[test_case(MarketType::EuropeanOption, "BTC-USD-221230-10000-P")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseFuture)]
#[test_case(MarketType::LinearFuture)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
#[test_case(MarketType::EuropeanOption)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
// #[test_case(MarketType::Spot, "BTC-USDT")]
// #[test_case(MarketType::InverseFuture, "BTC-USD-221230")]
// #[test_case(MarketType::LinearFuture, "BTC-USDT-221230")]
// #[test_case(MarketType::InverseSwap, "BTC-USD-SWAP")]
// #[test_case(MarketType::LinearSwap, "BTC-USDT-SWAP")]
// #[test_case(MarketType::EuropeanOption, "BTC-USD-221230-10000-P")]
// fn test_subscribe_symbol(market_type: MarketType, symbol: &str) {
// gen_test_subscribe_symbol!(EXCHANGE_NAME, market_type, symbol)
// }
================================================
FILE: crypto-crawler/tests/utils/mod.rs
================================================
use crypto_crawler::Message;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
pub(crate) fn parse(msg: Message) -> bool {
let skipped_exchanges = vec!["bitget", "zb"];
if skipped_exchanges.contains(&msg.exchange.as_str()) {
return true;
}
match msg.msg_type {
MessageType::Trade => {
crypto_msg_parser::parse_trade(&msg.exchange, msg.market_type, &msg.json).is_ok()
}
MessageType::L2Event => {
match msg.market_type {
// crypto-msg-parser doesn't support quanto contracts
MarketType::QuantoSwap | MarketType::QuantoFuture => true,
_ => crypto_msg_parser::parse_l2(
&msg.exchange,
msg.market_type,
&msg.json,
Some(msg.received_at as i64),
)
.is_ok(),
}
}
MessageType::FundingRate => crypto_msg_parser::parse_funding_rate(
&msg.exchange,
msg.market_type,
&msg.json,
Some(msg.received_at as i64),
)
.is_ok(),
_ => true,
}
}
#[allow(unused_macros)]
macro_rules! test_one_symbol {
($crawl_func:ident, $exchange:expr, $market_type:expr, $symbol:expr, $msg_type:expr) => {{
let (tx, rx) = std::sync::mpsc::channel();
let symbols = vec![$symbol.to_string()];
tokio::task::spawn(async move {
$crawl_func($exchange, $market_type, Some(&symbols), tx).await;
});
let msg = rx.recv().unwrap();
assert_eq!(msg.exchange, $exchange.to_string());
assert_eq!(msg.market_type, $market_type);
assert_eq!(msg.msg_type, $msg_type);
assert!(tokio::task::block_in_place(move || parse(msg)));
}};
}
#[allow(unused_macros)]
macro_rules! test_all_symbols {
($crawl_func:ident, $exchange:expr, $market_type:expr, $msg_type:expr) => {{
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
$crawl_func($exchange, $market_type, None, tx).await;
});
let msg = rx.recv().unwrap();
assert_eq!(msg.exchange, $exchange.to_string());
assert_eq!(msg.market_type, $market_type);
assert_eq!(msg.msg_type, $msg_type);
assert!(tokio::task::block_in_place(move || parse(msg)));
}};
}
#[allow(unused_macros)]
macro_rules! test_crawl_restful {
($crawl_func:ident, $exchange:expr, $market_type:expr, $symbol:expr, $msg_type:expr) => {{
let (tx, rx) = std::sync::mpsc::channel();
let symbols = vec![$symbol.to_string()];
std::thread::spawn(move || {
$crawl_func($exchange, $market_type, Some(&symbols), tx);
});
let msg = rx.recv().unwrap();
assert_eq!(msg.exchange, $exchange.to_string());
assert_eq!(msg.market_type, $market_type);
assert_eq!(msg.msg_type, $msg_type);
assert!(parse(msg));
}};
}
#[allow(unused_macros)]
macro_rules! test_crawl_restful_all_symbols {
($crawl_func:ident, $exchange:expr, $market_type:expr, $msg_type:expr) => {{
let (tx, rx) = std::sync::mpsc::channel();
std::thread::spawn(move || {
$crawl_func($exchange, $market_type, None, tx);
});
let msg = rx.recv().unwrap();
assert_eq!(msg.exchange, $exchange.to_string());
assert_eq!(msg.market_type, $market_type);
assert_eq!(msg.msg_type, $msg_type);
assert!(parse(msg));
}};
}
#[allow(unused_macros)]
macro_rules! gen_test_crawl_candlestick {
($exchange:expr, $market_type:expr) => {{
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
crawl_candlestick($exchange, $market_type, None, tx).await;
});
let msg = rx.recv().unwrap();
assert_eq!(msg.exchange, $exchange.to_string());
assert_eq!(msg.market_type, $market_type);
assert_eq!(msg.msg_type, MessageType::Candlestick);
assert!(tokio::task::block_in_place(move || parse(msg)));
}};
}
#[allow(unused_macros)]
macro_rules! gen_test_subscribe_symbol {
($exchange:expr, $market_type:expr, $symbol:expr) => {{
let (tx, rx) = std::sync::mpsc::channel();
tokio::task::spawn(async move {
let msg_types = vec![MessageType::Trade, MessageType::L2Event];
subscribe_symbol($exchange, $market_type, $symbol, &msg_types, tx).await;
});
let mut messages = Vec::new();
for msg in rx {
messages.push(msg);
break;
}
assert!(!messages.is_empty());
}};
}
================================================
FILE: crypto-crawler/tests/zb.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "zb";
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "btc_usdt")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
// #[test_case(MarketType::Spot, "btc_usdt")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "btc_usdt")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_topk, EXCHANGE_NAME, market_type, symbol, MessageType::L2TopK)
}
#[test_case(MarketType::Spot, "btc_usdt")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "btc_usdt")]
#[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
================================================
FILE: crypto-crawler/tests/zbg.rs
================================================
#[macro_use]
mod utils;
use test_case::test_case;
use crypto_crawler::*;
use crypto_market_type::MarketType;
use crypto_msg_type::MessageType;
use utils::parse;
const EXCHANGE_NAME: &str = "zbg";
#[test_case(MarketType::Spot)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_trade_all(market_type: MarketType) {
test_all_symbols!(crawl_trade, EXCHANGE_NAME, market_type, MessageType::Trade)
}
#[test_case(MarketType::Spot, "btc_usdt")]
// #[test_case(MarketType::InverseSwap, "BTC_USD-R")]
// #[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_trade, EXCHANGE_NAME, market_type, symbol, MessageType::Trade)
}
#[test_case(MarketType::Spot, "btc_usdt")]
// #[test_case(MarketType::InverseSwap, "BTC_USD-R")]
// #[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_l2_event, EXCHANGE_NAME, market_type, symbol, MessageType::L2Event)
}
#[test_case(MarketType::Spot, "btc_usdt")]
// #[test_case(MarketType::InverseSwap, "BTC_USD-R")]
// #[test_case(MarketType::LinearSwap, "BTC_USDT")]
fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
test_crawl_restful!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
symbol,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot)]
#[test_case(MarketType::InverseSwap)]
#[test_case(MarketType::LinearSwap)]
fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
test_crawl_restful_all_symbols!(
crawl_l2_snapshot,
EXCHANGE_NAME,
market_type,
MessageType::L2Snapshot
)
}
#[test_case(MarketType::Spot, "btc_usdt")]
// #[test_case(MarketType::InverseSwap, "BTC_USD-R")]
// #[test_case(MarketType::LinearSwap, "BTC_USDT")]
#[tokio::test(flavor = "multi_thread")]
async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
test_one_symbol!(crawl_ticker, EXCHANGE_NAME, market_type, symbol, MessageType::Ticker)
}
#[test_case(MarketType::Spot)]
// #[test_case(MarketType::InverseSwap)]
// #[test_case(MarketType::LinearSwap)]
#[tokio::test(flavor = "multi_thread", worker_threads = 8)]
async fn test_crawl_candlestick(market_type: MarketType) {
gen_test_crawl_candlestick!(EXCHANGE_NAME, market_type)
}
================================================
FILE: crypto-market-type/Cargo.toml
================================================
[package]
name = "crypto-market-type"
version = "1.1.5"
authors = ["soulmachine <soulmachine@gmail.com>"]
edition = "2021"
description = "Cryptocurrenty market type"
license = "Apache-2.0"
repository = "https://github.com/crypto-crawler/crypto-crawler-rs/tree/main/crypto-market-type"
keywords = ["cryptocurrency", "blockchain", "trading"]
[dependencies]
serde = { version = "1", features = ["derive"] }
strum = "0.24"
strum_macros = "0.24"
================================================
FILE: crypto-market-type/include/crypto_market_type.h
================================================
/* Licensed under Apache-2.0 */
#ifndef CRYPTO_MARKET_TYPE_H_
#define CRYPTO_MARKET_TYPE_H_
/**
* Market type.
*
* * In spot market, cryptocurrencies are traded for immediate delivery, see
* https://en.wikipedia.org/wiki/Spot_market.
* * In futures market, delivery is set at a specified time in the future, see
* https://en.wikipedia.org/wiki/Futures_exchange.
* * Swap market is a variant of futures market with no expiry date.
*
* ## Margin
*
* A market can have margin enabled or disabled.
*
* * All contract markets are margin enabled, including future, swap and option.
* * Most spot markets don't have margin enabled, only a few exchanges have spot
* market with margin enabled.
*
* ## Linear VS. Inverse
*
* A market can be inverse or linear.
* * Linear means USDT-margined, i.e., you can use USDT as collateral
* * Inverse means coin-margined, i.e., you can use BTC as collateral.
* * Spot market is always linear.
*
* **
gitextract_sqwwf4gd/ ├── .config/ │ └── nextest.toml ├── .editorconfig ├── .github/ │ ├── CODEOWNERS │ └── workflows/ │ └── ci.yml ├── .gitignore ├── Cargo.toml ├── LICENSE ├── README.md ├── crypto-client/ │ ├── Cargo.toml │ ├── README.md │ └── src/ │ └── lib.rs ├── crypto-crawler/ │ ├── Cargo.toml │ ├── README.md │ ├── src/ │ │ ├── crawlers/ │ │ │ ├── binance.rs │ │ │ ├── bitmex.rs │ │ │ ├── deribit.rs │ │ │ ├── huobi.rs │ │ │ ├── kucoin.rs │ │ │ ├── mod.rs │ │ │ ├── okx.rs │ │ │ ├── utils.rs │ │ │ ├── zb.rs │ │ │ └── zbg.rs │ │ ├── lib.rs │ │ ├── msg.rs │ │ └── utils/ │ │ ├── cmc_rank.rs │ │ ├── lock.rs │ │ ├── mod.rs │ │ └── spot_symbols.rs │ └── tests/ │ ├── binance.rs │ ├── bitfinex.rs │ ├── bitget.rs │ ├── bithumb.rs │ ├── bitmex.rs │ ├── bitstamp.rs │ ├── bitz.rs │ ├── bybit.rs │ ├── coinbase_pro.rs │ ├── deribit.rs │ ├── dydx.rs │ ├── ftx.rs │ ├── gate.rs │ ├── huobi.rs │ ├── kraken.rs │ ├── kucoin.rs │ ├── mexc.rs │ ├── okx.rs │ ├── utils/ │ │ └── mod.rs │ ├── zb.rs │ └── zbg.rs ├── crypto-market-type/ │ ├── Cargo.toml │ ├── include/ │ │ └── crypto_market_type.h │ └── src/ │ └── lib.rs ├── crypto-markets/ │ ├── Cargo.toml │ ├── README.md │ ├── src/ │ │ ├── error.rs │ │ ├── exchanges/ │ │ │ ├── binance/ │ │ │ │ ├── binance_inverse.rs │ │ │ │ ├── binance_linear.rs │ │ │ │ ├── binance_option.rs │ │ │ │ ├── binance_spot.rs │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── bitfinex.rs │ │ │ ├── bitget/ │ │ │ │ ├── bitget_spot.rs │ │ │ │ ├── bitget_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── bithumb.rs │ │ │ ├── bitmex.rs │ │ │ ├── bitstamp.rs │ │ │ ├── bitz/ │ │ │ │ ├── bitz_spot.rs │ │ │ │ ├── bitz_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── bybit.rs │ │ │ ├── coinbase_pro.rs │ │ │ ├── deribit/ │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── dydx/ │ │ │ │ ├── dydx_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── ftx.rs │ │ │ ├── gate/ │ │ │ │ ├── gate_future.rs │ │ │ │ ├── gate_spot.rs │ │ │ │ ├── gate_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── huobi/ │ │ │ │ ├── huobi_future.rs │ │ │ │ ├── huobi_inverse_swap.rs │ │ │ │ ├── huobi_linear_swap.rs │ │ │ │ ├── huobi_option.rs │ │ │ │ ├── huobi_spot.rs │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── kraken/ │ │ │ │ ├── kraken_futures.rs │ │ │ │ ├── kraken_spot.rs │ │ │ │ └── mod.rs │ │ │ ├── kucoin/ │ │ │ │ ├── kucoin_spot.rs │ │ │ │ ├── kucoin_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── mexc/ │ │ │ │ ├── mexc_spot.rs │ │ │ │ ├── mexc_swap.rs │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── mod.rs │ │ │ ├── okx.rs │ │ │ ├── utils.rs │ │ │ ├── zb/ │ │ │ │ ├── mod.rs │ │ │ │ ├── zb_spot.rs │ │ │ │ └── zb_swap.rs │ │ │ └── zbg/ │ │ │ ├── mod.rs │ │ │ ├── zbg_spot.rs │ │ │ └── zbg_swap.rs │ │ ├── lib.rs │ │ ├── main.rs │ │ └── market.rs │ └── tests/ │ ├── binance.rs │ ├── bitfinex.rs │ ├── bitget.rs │ ├── bithumb.rs │ ├── bitmex.rs │ ├── bitstamp.rs │ ├── bitz.rs │ ├── bybit.rs │ ├── coinbase_pro.rs │ ├── deribit.rs │ ├── dydx.rs │ ├── ftx.rs │ ├── gate.rs │ ├── huobi.rs │ ├── kraken.rs │ ├── kucoin.rs │ ├── mexc.rs │ ├── okx.rs │ ├── utils/ │ │ └── mod.rs │ ├── zb.rs │ └── zbg.rs ├── crypto-msg-type/ │ ├── Cargo.toml │ ├── include/ │ │ └── crypto_msg_type.h │ └── src/ │ ├── exchanges/ │ │ ├── binance.rs │ │ ├── bitfinex.rs │ │ ├── bitmex.rs │ │ ├── bybit.rs │ │ ├── deribit.rs │ │ ├── ftx.rs │ │ ├── huobi.rs │ │ ├── mod.rs │ │ ├── okex.rs │ │ └── okx.rs │ └── lib.rs ├── crypto-rest-client/ │ ├── Cargo.toml │ ├── README.md │ ├── src/ │ │ ├── error.rs │ │ ├── exchanges/ │ │ │ ├── binance/ │ │ │ │ ├── binance_inverse.rs │ │ │ │ ├── binance_linear.rs │ │ │ │ ├── binance_option.rs │ │ │ │ ├── binance_spot.rs │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── bitfinex.rs │ │ │ ├── bitget/ │ │ │ │ ├── bitget_spot.rs │ │ │ │ ├── bitget_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── bithumb.rs │ │ │ ├── bitmex.rs │ │ │ ├── bitstamp.rs │ │ │ ├── bitz/ │ │ │ │ ├── bitz_spot.rs │ │ │ │ ├── bitz_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── bybit.rs │ │ │ ├── coinbase_pro.rs │ │ │ ├── deribit.rs │ │ │ ├── dydx/ │ │ │ │ ├── dydx_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── ftx.rs │ │ │ ├── gate/ │ │ │ │ ├── gate_future.rs │ │ │ │ ├── gate_spot.rs │ │ │ │ ├── gate_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── huobi/ │ │ │ │ ├── huobi_future.rs │ │ │ │ ├── huobi_inverse_swap.rs │ │ │ │ ├── huobi_linear_swap.rs │ │ │ │ ├── huobi_option.rs │ │ │ │ ├── huobi_spot.rs │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── kraken/ │ │ │ │ ├── kraken_futures.rs │ │ │ │ ├── kraken_spot.rs │ │ │ │ └── mod.rs │ │ │ ├── kucoin/ │ │ │ │ ├── kucoin_spot.rs │ │ │ │ ├── kucoin_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── mexc/ │ │ │ │ ├── mexc_spot.rs │ │ │ │ ├── mexc_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── mod.rs │ │ │ ├── okx.rs │ │ │ ├── utils.rs │ │ │ ├── zb/ │ │ │ │ ├── mod.rs │ │ │ │ ├── zb_spot.rs │ │ │ │ └── zb_swap.rs │ │ │ └── zbg/ │ │ │ ├── mod.rs │ │ │ ├── zbg_spot.rs │ │ │ └── zbg_swap.rs │ │ └── lib.rs │ └── tests/ │ ├── binance_inverse.rs │ ├── binance_linear.rs │ ├── binance_option.rs │ ├── binance_spot.rs │ ├── bitfinex.rs │ ├── bitget_spot.rs │ ├── bitget_swap.rs │ ├── bithumb.rs │ ├── bitmex.rs │ ├── bitstamp.rs │ ├── bitz_spot.rs │ ├── bitz_swap.rs │ ├── bybit.rs │ ├── coinbase_pro.rs │ ├── deribit.rs │ ├── dydx.rs │ ├── ftx.rs │ ├── gate.rs │ ├── huobi.rs │ ├── kraken.rs │ ├── kucoin.rs │ ├── mexc.rs │ ├── okx.rs │ ├── zb.rs │ └── zbg.rs ├── crypto-ws-client/ │ ├── Cargo.toml │ ├── README.md │ ├── src/ │ │ ├── clients/ │ │ │ ├── binance.rs │ │ │ ├── binance_option.rs │ │ │ ├── bitfinex.rs │ │ │ ├── bitget/ │ │ │ │ ├── bitget_spot.rs │ │ │ │ ├── bitget_swap.rs │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── bithumb.rs │ │ │ ├── bitmex.rs │ │ │ ├── bitstamp.rs │ │ │ ├── bitz/ │ │ │ │ ├── bitz_spot.rs │ │ │ │ └── mod.rs │ │ │ ├── bybit/ │ │ │ │ ├── bybit_inverse.rs │ │ │ │ ├── bybit_linear_swap.rs │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── coinbase_pro.rs │ │ │ ├── common_traits.rs │ │ │ ├── deribit.rs │ │ │ ├── dydx/ │ │ │ │ ├── dydx_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── ftx.rs │ │ │ ├── gate/ │ │ │ │ ├── gate_future.rs │ │ │ │ ├── gate_spot.rs │ │ │ │ ├── gate_swap.rs │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── huobi.rs │ │ │ ├── kraken/ │ │ │ │ ├── kraken_futures.rs │ │ │ │ ├── kraken_spot.rs │ │ │ │ └── mod.rs │ │ │ ├── kucoin/ │ │ │ │ ├── kucoin_spot.rs │ │ │ │ ├── kucoin_swap.rs │ │ │ │ ├── mod.rs │ │ │ │ └── utils.rs │ │ │ ├── mexc/ │ │ │ │ ├── mexc_spot.rs │ │ │ │ ├── mexc_swap.rs │ │ │ │ └── mod.rs │ │ │ ├── mod.rs │ │ │ ├── okx.rs │ │ │ ├── zb/ │ │ │ │ ├── mod.rs │ │ │ │ ├── zb_spot.rs │ │ │ │ └── zb_swap.rs │ │ │ └── zbg/ │ │ │ ├── mod.rs │ │ │ ├── utils.rs │ │ │ ├── zbg_spot.rs │ │ │ └── zbg_swap.rs │ │ ├── common/ │ │ │ ├── command_translator.rs │ │ │ ├── connect_async.rs │ │ │ ├── message_handler.rs │ │ │ ├── mod.rs │ │ │ ├── utils.rs │ │ │ ├── ws_client.rs │ │ │ └── ws_client_internal.rs │ │ └── lib.rs │ └── tests/ │ ├── binance.rs │ ├── binance_option.rs │ ├── bitfinex.rs │ ├── bitget.rs │ ├── bithumb.rs │ ├── bitmex.rs │ ├── bitstamp.rs │ ├── bitz.rs │ ├── bybit.rs │ ├── coinbase_pro.rs │ ├── deribit.rs │ ├── dydx.rs │ ├── ftx.rs │ ├── gate.rs │ ├── huobi.rs │ ├── kraken.rs │ ├── kucoin.rs │ ├── mexc.rs │ ├── okx.rs │ ├── utils/ │ │ └── mod.rs │ ├── zb.rs │ └── zbg.rs └── rustfmt.toml
SYMBOL INDEX (1969 symbols across 271 files)
FILE: crypto-client/src/lib.rs
type CryptoClient (line 2) | pub struct CryptoClient {
function it_works (line 10) | fn it_works() {
FILE: crypto-crawler/src/crawlers/binance.rs
constant EXCHANGE_NAME (line 14) | const EXCHANGE_NAME: &str = "binance";
function crawl_trade (line 16) | pub(crate) async fn crawl_trade(
function crawl_bbo (line 45) | pub(crate) async fn crawl_bbo(
function crawl_ticker (line 90) | pub(crate) async fn crawl_ticker(
function crawl_funding_rate (line 142) | pub(crate) async fn crawl_funding_rate(
FILE: crypto-crawler/src/crawlers/bitmex.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "bitmex";
function crawl_all (line 13) | async fn crawl_all(msg_type: MessageType, tx: Sender<Message>) {
function crawl_trade (line 33) | pub(crate) async fn crawl_trade(
function crawl_l2_event (line 46) | pub(crate) async fn crawl_l2_event(
function crawl_bbo (line 59) | pub(crate) async fn crawl_bbo(
function crawl_l2_topk (line 72) | pub(crate) async fn crawl_l2_topk(
function crawl_funding_rate (line 86) | pub(crate) async fn crawl_funding_rate(
function crawl_candlestick (line 137) | pub(crate) async fn crawl_candlestick(
FILE: crypto-crawler/src/crawlers/deribit.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "deribit";
function crawl_trade (line 10) | pub(crate) async fn crawl_trade(
FILE: crypto-crawler/src/crawlers/huobi.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "huobi";
function crawl_l2_event (line 14) | pub(crate) async fn crawl_l2_event(
function crawl_funding_rate (line 50) | pub(crate) async fn crawl_funding_rate(
FILE: crypto-crawler/src/crawlers/kucoin.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "kucoin";
function crawl_bbo (line 11) | pub(crate) async fn crawl_bbo(
FILE: crypto-crawler/src/crawlers/okx.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "okx";
function crawl_funding_rate (line 11) | pub(crate) async fn crawl_funding_rate(
function crawl_open_interest (line 44) | pub(crate) async fn crawl_open_interest(
FILE: crypto-crawler/src/crawlers/utils.rs
function fetch_symbols_retry (line 15) | pub fn fetch_symbols_retry(exchange: &str, market_type: MarketType) -> V...
function check_args (line 56) | pub(super) fn check_args(exchange: &str, market_type: MarketType, symbol...
function get_cooldown_time_per_request (line 76) | fn get_cooldown_time_per_request(exchange: &str, market_type: MarketType...
function crawl_snapshot (line 106) | pub(crate) fn crawl_snapshot(
function crawl_open_interest (line 206) | pub(crate) fn crawl_open_interest(exchange: &str, market_type: MarketTyp...
function subscribe_with_lock (line 318) | async fn subscribe_with_lock(
function get_connection_interval_ms (line 336) | fn get_connection_interval_ms(exchange: &str, _market_type: MarketType) ...
function get_num_subscriptions_per_connection (line 348) | fn get_num_subscriptions_per_connection(exchange: &str, market_type: Mar...
function create_ws_client_internal (line 370) | async fn create_ws_client_internal(
function create_ws_client (line 470) | async fn create_ws_client(
function create_ws_client_symbol (line 507) | pub(crate) async fn create_ws_client_symbol(
type EmptyStruct (line 517) | struct EmptyStruct {}
function create_symbol_discovery_thread (line 519) | fn create_symbol_discovery_thread(
function create_new_symbol_receiver_thread (line 567) | fn create_new_symbol_receiver_thread(
function create_new_symbol_receiver_thread_candlestick (line 589) | fn create_new_symbol_receiver_thread_candlestick(
function create_conversion_thread (line 608) | pub(crate) fn create_conversion_thread(
function create_parser_thread (line 627) | fn create_parser_thread(
function crawl_event_one_chunk (line 669) | async fn crawl_event_one_chunk(
function crawl_event (line 700) | pub(crate) async fn crawl_event(
function get_candlestick_intervals (line 828) | fn get_candlestick_intervals(exchange: &str, market_type: MarketType) ->...
function crawl_candlestick_one_chunk (line 852) | async fn crawl_candlestick_one_chunk(
function crawl_candlestick_ext (line 880) | pub(crate) async fn crawl_candlestick_ext(
FILE: crypto-crawler/src/crawlers/zb.rs
constant EXCHANGE_NAME (line 10) | const EXCHANGE_NAME: &str = "zb";
function crawl_ticker (line 12) | pub(crate) async fn crawl_ticker(
FILE: crypto-crawler/src/crawlers/zbg.rs
constant EXCHANGE_NAME (line 10) | const EXCHANGE_NAME: &str = "zbg";
function crawl_ticker (line 12) | pub(crate) async fn crawl_ticker(
FILE: crypto-crawler/src/lib.rs
function crawl_trade (line 233) | pub async fn crawl_trade(
function crawl_l2_event (line 253) | pub async fn crawl_l2_event(
function crawl_l3_event (line 272) | pub async fn crawl_l3_event(
function crawl_l2_snapshot (line 287) | pub fn crawl_l2_snapshot(
function crawl_bbo (line 297) | pub async fn crawl_bbo(
function crawl_l2_topk (line 315) | pub async fn crawl_l2_topk(
function crawl_l3_snapshot (line 332) | pub fn crawl_l3_snapshot(
function crawl_ticker (line 345) | pub async fn crawl_ticker(
function crawl_funding_rate (line 364) | pub async fn crawl_funding_rate(
function crawl_candlestick (line 383) | pub async fn crawl_candlestick(
function crawl_open_interest (line 402) | pub fn crawl_open_interest(exchange: &str, market_type: MarketType, tx: ...
function subscribe_symbol (line 411) | pub async fn subscribe_symbol(
FILE: crypto-crawler/src/msg.rs
type Message (line 12) | pub struct Message {
method new (line 28) | pub fn new(
method new_with_symbol (line 49) | pub fn new_with_symbol(
method to_tsv_string (line 65) | pub fn to_tsv_string(&self) -> String {
method from_tsv_string (line 71) | pub fn from_tsv_string(exchange: &str, market_type: &str, msg_type: &s...
method fmt (line 91) | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
FILE: crypto-crawler/src/utils/cmc_rank.rs
function http_get (line 275) | fn http_get(url: &str) -> Result<String, reqwest::Error> {
function get_cmc_ranks (line 293) | fn get_cmc_ranks(limit: i64) -> HashMap<String, u64> {
function sort_by_cmc_rank (line 320) | pub(crate) fn sort_by_cmc_rank(exchange: &str, symbols: &mut [String]) {
function test_get_cmc_ranks (line 336) | fn test_get_cmc_ranks() {
function test_sort_by_cmc_rank (line 346) | fn test_sort_by_cmc_rank() {
FILE: crypto-crawler/src/utils/lock.rs
constant EXCHANGES (line 7) | const EXCHANGES: &[&str] = &[
constant EXCHANGES_WS (line 30) | const EXCHANGES_WS: &[&str] = &["bitfinex", "bitz", "kucoin", "okx"];
function get_lock_file_name (line 43) | fn get_lock_file_name(exchange: &str, market_type: MarketType, prefix: &...
function create_lock_file (line 124) | fn create_lock_file(filename: &str) -> LockFile {
function create_all_lock_files_rest (line 136) | fn create_all_lock_files_rest()
function create_all_lock_files_ws (line 166) | fn create_all_lock_files_ws()
FILE: crypto-crawler/src/utils/spot_symbols.rs
function get_hot_spot_symbols (line 5) | pub fn get_hot_spot_symbols(exchange: &str, spot_symbols: &[String]) -> ...
function test_binance (line 37) | fn test_binance() {
function test_huobi (line 44) | fn test_huobi() {
function test_okx (line 51) | fn test_okx() {
FILE: crypto-crawler/tests/binance.rs
constant EXCHANGE_NAME (line 12) | const EXCHANGE_NAME: &str = "binance";
function test_crawl_trade_all (line 20) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 31) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 42) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_bbo (line 53) | async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
function test_crawl_l2_topk (line 64) | async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 74) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 90) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 106) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_funding_rate (line 113) | async fn test_crawl_funding_rate(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 129) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/bitfinex.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "bitfinex";
function test_crawl_trade_all (line 16) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 23) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 30) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 36) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 48) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_l3_event (line 60) | async fn test_crawl_l3_event(market_type: MarketType, symbol: &str) {
function test_crawl_l3_snapshot (line 66) | fn test_crawl_l3_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_ticker (line 79) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 86) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/bitget.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "bitget";
function test_crawl_trade_all (line 17) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 25) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 33) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_topk (line 41) | async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 49) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 63) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 76) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 84) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/bithumb.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "bithumb";
function test_crawl_trade_all (line 15) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 21) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 27) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 32) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 43) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 54) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
FILE: crypto-crawler/tests/bitmex.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "bitmex";
function crawl_all (line 13) | async fn crawl_all(msg_type: MessageType) {
function test_crawl_trade_all (line 49) | async fn test_crawl_trade_all() {
function test_crawl_l2_event_all (line 54) | async fn test_crawl_l2_event_all() {
function test_crawl_bbo_all (line 59) | async fn test_crawl_bbo_all() {
function test_crawl_l2_topk_all (line 64) | async fn test_crawl_l2_topk_all() {
function test_crawl_l2_snapshot_all (line 69) | async fn test_crawl_l2_snapshot_all() {
function test_crawl_funding_rate_all (line 74) | async fn test_crawl_funding_rate_all() {
function test_crawl_candlestick_rate_all (line 79) | async fn test_crawl_candlestick_rate_all() {
function test_crawl_l2_event (line 95) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
FILE: crypto-crawler/tests/bitstamp.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "bitstamp";
function test_crawl_trade_all (line 15) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 21) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 27) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_topk (line 33) | async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 38) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 49) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_l3_event (line 60) | async fn test_crawl_l3_event(market_type: MarketType, symbol: &str) {
function test_crawl_l3_snapshot (line 66) | async fn test_crawl_l3_snapshot(market_type: MarketType, symbol: &str) {
FILE: crypto-crawler/tests/bitz.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "bitz";
function test_crawl_trade (line 17) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 25) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 32) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 45) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 58) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 64) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/bybit.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "bybit";
function test_crawl_trade_all (line 17) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 25) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 33) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 40) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 53) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 66) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 74) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/coinbase_pro.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "coinbase_pro";
function test_crawl_trade_all (line 15) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 21) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 27) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 32) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 43) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_l3_event (line 54) | async fn test_crawl_l3_event(market_type: MarketType, symbol: &str) {
function test_crawl_l3_snapshot (line 60) | async fn test_crawl_l3_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_ticker (line 72) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
FILE: crypto-crawler/tests/deribit.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "deribit";
function test_crawl_trade_all (line 17) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 25) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 33) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_bbo (line 41) | async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
function test_crawl_l2_topk (line 49) | async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 56) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 69) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 82) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 90) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/dydx.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "dydx";
function test_crawl_trade_all (line 15) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 21) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 27) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 32) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
FILE: crypto-crawler/tests/ftx.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "ftx";
function test_crawl_trade_all (line 19) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 29) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 39) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_bbo (line 49) | async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 58) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 73) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
FILE: crypto-crawler/tests/gate.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "gate";
function test_crawl_trade_all (line 19) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 29) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 39) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_bbo (line 47) | async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 56) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 71) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 86) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 96) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/huobi.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "huobi";
function test_crawl_trade_all (line 18) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 28) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 38) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_bbo (line 48) | async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
function test_crawl_l2_topk (line 58) | async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 67) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 82) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_funding_rate (line 94) | async fn test_crawl_funding_rate(market_type: MarketType, symbol: &str) {
function test_crawl_ticker (line 110) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 120) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/kraken.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "kraken";
function test_crawl_trade_all (line 17) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 25) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 33) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_bbo (line 39) | async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 46) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 59) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 72) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 78) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/kucoin.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "kucoin";
function test_crawl_trade_all (line 17) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 26) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 35) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_bbo (line 44) | async fn test_crawl_bbo(market_type: MarketType, symbol: &str) {
function test_crawl_l2_topk (line 53) | async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 61) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 75) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_l3_snapshot (line 89) | async fn test_crawl_l3_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_ticker (line 104) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 113) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/mexc.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "mexc";
function test_crawl_trade_all (line 17) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 25) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 33) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_topk (line 41) | async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 48) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 61) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 73) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 81) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/okx.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "okx";
function test_crawl_trade_all (line 20) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 31) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 42) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_topk (line 53) | async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 63) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 79) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_funding_rate (line 91) | async fn test_crawl_funding_rate(market_type: MarketType, symbol: &str) {
function test_crawl_open_interest (line 106) | fn test_crawl_open_interest(market_type: MarketType) {
function test_crawl_ticker (line 128) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 139) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/utils/mod.rs
function parse (line 5) | pub(crate) fn parse(msg: Message) -> bool {
FILE: crypto-crawler/tests/zb.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "zb";
function test_crawl_trade_all (line 16) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 23) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 30) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_topk (line 37) | async fn test_crawl_l2_topk(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 43) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 55) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 67) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 74) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-crawler/tests/zbg.rs
constant EXCHANGE_NAME (line 11) | const EXCHANGE_NAME: &str = "zbg";
function test_crawl_trade_all (line 15) | async fn test_crawl_trade_all(market_type: MarketType) {
function test_crawl_trade (line 23) | async fn test_crawl_trade(market_type: MarketType, symbol: &str) {
function test_crawl_l2_event (line 31) | async fn test_crawl_l2_event(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot (line 38) | fn test_crawl_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_crawl_l2_snapshot_without_symbol (line 51) | fn test_crawl_l2_snapshot_without_symbol(market_type: MarketType) {
function test_crawl_ticker (line 64) | async fn test_crawl_ticker(market_type: MarketType, symbol: &str) {
function test_crawl_candlestick (line 72) | async fn test_crawl_candlestick(market_type: MarketType) {
FILE: crypto-market-type/include/crypto_market_type.h
type MarketType (line 31) | typedef enum {
FILE: crypto-market-type/src/lib.rs
type MarketType (line 32) | pub enum MarketType {
function get_market_types (line 53) | pub fn get_market_types(exchange: &str) -> Vec<MarketType> {
FILE: crypto-markets/src/error.rs
type Result (line 3) | pub(crate) type Result<T> = std::result::Result<T, Error>;
type Error (line 6) | pub struct Error(pub String);
method fmt (line 9) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method from (line 17) | fn from(err: reqwest::Error) -> Self {
method from (line 23) | fn from(err: serde_json::Error) -> Self {
FILE: crypto-markets/src/exchanges/binance/binance_inverse.rs
type BinanceResponse (line 9) | struct BinanceResponse<T: Sized> {
type FutureMarket (line 15) | struct FutureMarket {
function fetch_inverse_markets_raw (line 43) | fn fetch_inverse_markets_raw() -> Result<Vec<FutureMarket>> {
function fetch_inverse_future_symbols (line 51) | pub(super) fn fetch_inverse_future_symbols() -> Result<Vec<String>> {
function fetch_inverse_swap_symbols (line 60) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_future_markets_internal (line 69) | fn fetch_future_markets_internal() -> Result<Vec<Market>> {
function fetch_inverse_future_markets (line 117) | pub(super) fn fetch_inverse_future_markets() -> Result<Vec<Market>> {
function fetch_inverse_swap_markets (line 125) | pub(super) fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/binance/binance_linear.rs
type BinanceResponse (line 9) | struct BinanceResponse<T: Sized> {
type LinearSwapMarket (line 15) | struct LinearSwapMarket {
function fetch_linear_markets_raw (line 41) | fn fetch_linear_markets_raw() -> Result<Vec<LinearSwapMarket>> {
function fetch_linear_swap_symbols (line 49) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_future_symbols (line 58) | pub(super) fn fetch_linear_future_symbols() -> Result<Vec<String>> {
function fetch_linear_markets (line 67) | fn fetch_linear_markets() -> Result<Vec<Market>> {
function fetch_linear_swap_markets (line 115) | pub(super) fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
function fetch_linear_future_markets (line 122) | pub(super) fn fetch_linear_future_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/binance/binance_option.rs
type BinanceResponse (line 8) | struct BinanceResponse<T: Sized> {
type OptionMarket (line 14) | struct OptionMarket {
function fetch_option_markets_raw (line 33) | fn fetch_option_markets_raw() -> Result<Vec<OptionMarket>> {
function fetch_option_symbols (line 56) | pub(super) fn fetch_option_symbols() -> Result<Vec<String>> {
function fetch_option_markets (line 62) | pub(super) fn fetch_option_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/binance/binance_spot.rs
type BinanceResponse (line 9) | struct BinanceResponse<T: Sized> {
type SpotMarket (line 15) | struct SpotMarket {
function fetch_spot_markets_raw (line 31) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 37) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 46) | pub(super) fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/binance/mod.rs
function fetch_symbols (line 9) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 21) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/binance/utils.rs
function check_code_in_body (line 7) | fn check_code_in_body(resp: String) -> Result<String> {
function binance_http_get (line 25) | pub(super) fn binance_http_get(url: &str) -> Result<String> {
function parse_filter (line 33) | pub(super) fn parse_filter<'a>(
FILE: crypto-markets/src/exchanges/bitfinex.rs
function fetch_symbols (line 12) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
type RawMarket (line 21) | struct RawMarket {
function fetch_raw_markets (line 34) | fn fetch_raw_markets() -> Result<Vec<RawMarket>> {
function fetch_markets (line 43) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
function fetch_spot_symbols (line 109) | fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_symbols (line 121) | fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function _fetch_symbols (line 141) | fn _fetch_symbols(url: &str) -> Result<Vec<String>> {
function _fetch_spot_symbols (line 153) | fn _fetch_spot_symbols() -> Result<Vec<String>> {
function _fetch_linear_swap_symbols (line 157) | fn _fetch_linear_swap_symbols() -> Result<Vec<String>> {
function test_spot_symbols (line 162) | fn test_spot_symbols() {
function test_linear_swap_symbols (line 180) | fn test_linear_swap_symbols() {
FILE: crypto-markets/src/exchanges/bitget/bitget_spot.rs
type SpotMarket (line 16) | struct SpotMarket {
type Response (line 34) | struct Response {
function fetch_spot_markets_raw (line 44) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 60) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 66) | pub(super) fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/bitget/bitget_swap.rs
type SwapMarket (line 17) | struct SwapMarket {
type Response (line 38) | struct Response {
function fetch_swap_markets_raw (line 49) | fn fetch_swap_markets_raw(product_type: &str) -> Result<Vec<SwapMarket>> {
function fetch_inverse_swap_symbols (line 59) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_inverse_future_symbols (line 68) | pub(super) fn fetch_inverse_future_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_symbols (line 77) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function fetch_inverse_swap_markets (line 87) | pub(super) fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
function fetch_inverse_future_markets (line 96) | pub(super) fn fetch_inverse_future_markets() -> Result<Vec<Market>> {
function fetch_linear_swap_markets (line 105) | pub(super) fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
function to_market (line 111) | fn to_market(m: SwapMarket) -> Market {
FILE: crypto-markets/src/exchanges/bitget/mod.rs
constant EXCHANGE_NAME (line 6) | pub(super) const EXCHANGE_NAME: &str = "bitget";
function fetch_symbols (line 8) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 18) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/bithumb.rs
function fetch_symbols (line 12) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 19) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
type CoinConfig (line 28) | struct CoinConfig {
type PercentPrice (line 44) | struct PercentPrice {
type SpotConfig (line 51) | struct SpotConfig {
type Data (line 63) | struct Data {
type Response (line 69) | struct Response {
function fetch_spot_coing (line 77) | fn fetch_spot_coing() -> Result<Data> {
function fetch_spot_symbols (line 83) | fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 89) | fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/bitmex.rs
function fetch_symbols (line 15) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 20) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
type Instrument (line 79) | struct Instrument {
function fetch_instruments (line 157) | fn fetch_instruments(market_type: MarketType) -> Result<Vec<Instrument>> {
FILE: crypto-markets/src/exchanges/bitstamp.rs
function fetch_symbols (line 8) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 15) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
type SpotMarket (line 23) | struct SpotMarket {
function fetch_spot_markets_raw (line 36) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 42) | fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 48) | fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/bitz/bitz_spot.rs
type SpotMarket (line 11) | struct SpotMarket {
type Response (line 29) | struct Response {
function fetch_spot_markets_raw (line 39) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 51) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
FILE: crypto-markets/src/exchanges/bitz/bitz_swap.rs
type SwapMarket (line 11) | struct SwapMarket {
type Response (line 40) | struct Response {
function fetch_swap_markets_raw (line 50) | fn fetch_swap_markets_raw() -> Result<Vec<SwapMarket>> {
function fetch_inverse_swap_symbols (line 61) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_symbols (line 70) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
FILE: crypto-markets/src/exchanges/bitz/mod.rs
function fetch_symbols (line 6) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 15) | pub(crate) fn fetch_markets(_market_type: MarketType) -> Result<Vec<Mark...
FILE: crypto-markets/src/exchanges/bybit.rs
function fetch_symbols (line 10) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 19) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
type LeverageFilter (line 29) | struct LeverageFilter {
type PriceFilter (line 36) | struct PriceFilter {
type LotSizeFilter (line 43) | struct LotSizeFilter {
type BybitMarket (line 50) | struct BybitMarket {
type Response (line 67) | struct Response {
function fetch_markets_raw (line 76) | fn fetch_markets_raw() -> Result<Vec<BybitMarket>> {
function fetch_inverse_swap_symbols (line 83) | fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_symbols (line 92) | fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function fetch_inverse_future_symbols (line 101) | fn fetch_inverse_future_symbols() -> Result<Vec<String>> {
function to_market (line 112) | fn to_market(raw_market: &BybitMarket) -> Market {
function fetch_inverse_swap_markets (line 189) | fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
function fetch_linear_swap_markets (line 198) | fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
function fetch_inverse_future_markets (line 207) | fn fetch_inverse_future_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/coinbase_pro.rs
function fetch_symbols (line 9) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 16) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
type SpotMarket (line 24) | struct SpotMarket {
function fetch_spot_markets_raw (line 45) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 51) | fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 60) | fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/deribit/mod.rs
function fetch_symbols (line 5) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 14) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/deribit/utils.rs
function check_error_in_body (line 13) | fn check_error_in_body(body: String) -> Result<String> {
function deribit_http_get (line 18) | pub(super) fn deribit_http_get(url: &str) -> Result<String> {
type DeribitResponse (line 28) | struct DeribitResponse<T> {
type Instrument (line 42) | struct Instrument {
function fetch_instruments (line 74) | fn fetch_instruments(currency: &str, kind: &str) -> Result<Vec<Instrumen...
function fetch_raw_markets (line 83) | fn fetch_raw_markets(kind: &str) -> Result<Vec<Instrument>> {
function fetch_symbols (line 109) | fn fetch_symbols(kind: &str) -> Result<Vec<String>> {
function fetch_inverse_future_symbols (line 115) | pub(super) fn fetch_inverse_future_symbols() -> Result<Vec<String>> {
function fetch_inverse_swap_symbols (line 123) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_option_symbols (line 131) | pub(super) fn fetch_option_symbols() -> Result<Vec<String>> {
function to_market (line 135) | fn to_market(raw_market: &Instrument) -> Market {
function fetch_inverse_future_markets (line 183) | pub(super) fn fetch_inverse_future_markets() -> Result<Vec<Market>> {
function fetch_inverse_swap_markets (line 193) | pub(super) fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
function fetch_option_markets (line 203) | pub(super) fn fetch_option_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/dydx/dydx_swap.rs
constant BASE_URL (line 10) | const BASE_URL: &str = "https://api.dydx.exchange";
type PerpetualMarket (line 14) | struct PerpetualMarket {
type MarketsResponse (line 30) | struct MarketsResponse {
function fetch_markets_raw (line 35) | fn fetch_markets_raw() -> Result<Vec<PerpetualMarket>> {
function fetch_linear_swap_symbols (line 46) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_markets (line 52) | pub(super) fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/dydx/mod.rs
function fetch_symbols (line 5) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 12) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/ftx.rs
function fetch_symbols (line 10) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 21) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
type FtxMarket (line 34) | struct FtxMarket {
type Response (line 51) | struct Response {
function fetch_markets_raw (line 56) | fn fetch_markets_raw() -> Result<Vec<FtxMarket>> {
function fetch_spot_symbols (line 64) | fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_symbols (line 74) | fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_future_symbols (line 84) | fn fetch_linear_future_symbols() -> Result<Vec<String>> {
function fetch_move_symbols (line 100) | fn fetch_move_symbols() -> Result<Vec<String>> {
function fetch_bvol_symbols (line 110) | fn fetch_bvol_symbols() -> Result<Vec<String>> {
function to_market (line 120) | fn to_market(raw_market: &FtxMarket) -> Market {
function fetch_spot_markets (line 197) | fn fetch_spot_markets() -> Result<Vec<Market>> {
function fetch_linear_swap_markets (line 206) | fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
function fetch_linear_future_markets (line 216) | fn fetch_linear_future_markets() -> Result<Vec<Market>> {
function fetch_move_markets (line 231) | fn fetch_move_markets() -> Result<Vec<Market>> {
function fetch_bvol_markets (line 240) | fn fetch_bvol_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/gate/gate_future.rs
type FutureMarket (line 13) | struct FutureMarket {
function fetch_future_markets_raw (line 38) | fn fetch_future_markets_raw(settle: &str) -> Result<Vec<FutureMarket>> {
function fetch_inverse_future_symbols (line 47) | pub(super) fn fetch_inverse_future_symbols() -> Result<Vec<String>> {
function fetch_linear_future_symbols (line 53) | pub(super) fn fetch_linear_future_symbols() -> Result<Vec<String>> {
function to_market (line 59) | fn to_market(raw_market: &FutureMarket) -> Market {
function fetch_inverse_future_markets (line 119) | pub(super) fn fetch_inverse_future_markets() -> Result<Vec<Market>> {
function fetch_linear_future_markets (line 127) | pub(super) fn fetch_linear_future_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/gate/gate_spot.rs
type SpotMarket (line 13) | struct SpotMarket {
function fetch_spot_markets_raw (line 28) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 34) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 40) | pub(super) fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/gate/gate_swap.rs
type SwapMarket (line 13) | struct SwapMarket {
function fetch_swap_markets_raw (line 35) | fn fetch_swap_markets_raw(settle: &str) -> Result<Vec<SwapMarket>> {
function fetch_inverse_swap_symbols (line 44) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_symbols (line 50) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function to_market (line 56) | fn to_market(raw_market: &SwapMarket) -> Market {
function fetch_inverse_swap_markets (line 116) | pub(super) fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
function fetch_linear_swap_markets (line 122) | pub(super) fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/gate/mod.rs
function fetch_symbols (line 7) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 18) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/huobi/huobi_future.rs
type FutureMarket (line 16) | struct FutureMarket {
type Response (line 32) | struct Response {
function fetch_future_markets_raw (line 39) | fn fetch_future_markets_raw() -> Result<Vec<FutureMarket>> {
function fetch_inverse_future_symbols (line 47) | pub(super) fn fetch_inverse_future_symbols() -> Result<Vec<String>> {
function fetch_inverse_future_markets (line 64) | pub(super) fn fetch_inverse_future_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/huobi/huobi_inverse_swap.rs
type InverseSwapMarket (line 14) | struct InverseSwapMarket {
type Response (line 28) | struct Response {
function fetch_inverse_swap_markets_raw (line 35) | fn fetch_inverse_swap_markets_raw() -> Result<Vec<InverseSwapMarket>> {
function fetch_inverse_swap_symbols (line 43) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_inverse_swap_markets (line 51) | pub(super) fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/huobi/huobi_linear_swap.rs
type LinearSwapMarket (line 14) | struct LinearSwapMarket {
type Response (line 28) | struct Response {
function fetch_linear_swap_markets_raw (line 35) | fn fetch_linear_swap_markets_raw() -> Result<Vec<LinearSwapMarket>> {
function fetch_linear_swap_symbols (line 43) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_markets (line 51) | pub(super) fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/huobi/huobi_option.rs
type OptionMarket (line 9) | struct OptionMarket {
type Response (line 28) | struct Response {
function fetch_option_markets_raw (line 35) | fn fetch_option_markets_raw() -> Result<Vec<OptionMarket>> {
function fetch_option_symbols (line 43) | pub(super) fn fetch_option_symbols() -> Result<Vec<String>> {
FILE: crypto-markets/src/exchanges/huobi/huobi_spot.rs
type SpotMarket (line 15) | struct SpotMarket {
type Response (line 38) | struct Response {
function fetch_spot_markets_raw (line 44) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 51) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 56) | pub(super) fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/huobi/mod.rs
function fetch_symbols (line 11) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 22) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/huobi/utils.rs
function check_status_in_body (line 7) | fn check_status_in_body(resp: String) -> Result<String> {
function huobi_http_get (line 25) | pub(super) fn huobi_http_get(url: &str) -> Result<String> {
FILE: crypto-markets/src/exchanges/kraken/kraken_futures.rs
type FuturesMarketPartial (line 14) | struct FuturesMarketPartial {
type FuturesMarket (line 25) | struct FuturesMarket {
type Response (line 40) | struct Response<T: Sized> {
function check_error_in_body (line 45) | fn check_error_in_body(resp: String) -> Result<String> {
function kraken_http_get (line 58) | pub(super) fn kraken_http_get(url: &str) -> Result<String> {
function fetch_futures_markets_raw (line 67) | fn fetch_futures_markets_raw() -> Result<Vec<FuturesMarket>> {
function fetch_inverse_future_symbols (line 82) | pub(super) fn fetch_inverse_future_symbols() -> Result<Vec<String>> {
function fetch_inverse_swap_symbols (line 91) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_inverse_future_markets (line 100) | pub(super) fn fetch_inverse_future_markets() -> Result<Vec<Market>> {
function fetch_inverse_swap_markets (line 108) | pub(super) fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
function fetch_futures_markets (line 116) | fn fetch_futures_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/kraken/kraken_spot.rs
type SpotMarket (line 13) | struct SpotMarket {
type Response (line 33) | struct Response {
function check_error_in_body (line 37) | fn check_error_in_body(resp: String) -> Result<String> {
function kraken_http_get (line 52) | pub(super) fn kraken_http_get(url: &str) -> Result<String> {
function fetch_spot_markets_raw (line 61) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 76) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 82) | pub(super) fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/kraken/mod.rs
function fetch_symbols (line 6) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 15) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/kucoin/kucoin_spot.rs
type SpotMarket (line 15) | struct SpotMarket {
type Response (line 37) | struct Response {
function fetch_spot_markets_raw (line 43) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 55) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 61) | pub(super) fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/kucoin/kucoin_swap.rs
type SwapMarket (line 15) | struct SwapMarket {
type Response (line 53) | struct Response {
function fetch_swap_markets_raw (line 59) | fn fetch_swap_markets_raw() -> Result<Vec<SwapMarket>> {
function fetch_inverse_swap_symbols (line 71) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_symbols (line 81) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function fetch_inverse_future_symbols (line 91) | pub(super) fn fetch_inverse_future_symbols() -> Result<Vec<String>> {
function to_market (line 101) | fn to_market(raw_market: &SwapMarket) -> Market {
function fetch_inverse_swap_markets (line 145) | pub(super) fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
function fetch_linear_swap_markets (line 154) | pub(super) fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
function fetch_inverse_future_markets (line 163) | pub(super) fn fetch_inverse_future_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/kucoin/mod.rs
function fetch_symbols (line 6) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 16) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/mexc/mexc_spot.rs
type SpotMarket (line 10) | struct SpotMarket {
type Response (line 25) | struct Response {
function fetch_spot_markets_raw (line 31) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 37) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 42) | pub(super) fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/mexc/mexc_swap.rs
type SwapMarket (line 11) | struct SwapMarket {
type Response (line 44) | struct Response {
function fetch_swap_markets_raw (line 51) | fn fetch_swap_markets_raw() -> Result<Vec<SwapMarket>> {
function fetch_linear_swap_symbols (line 57) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function fetch_inverse_swap_symbols (line 66) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function to_market (line 75) | fn to_market(raw_market: &SwapMarket) -> Market {
function fetch_linear_swap_markets (line 118) | pub(super) fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
function fetch_inverse_swap_markets (line 127) | pub(super) fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/mexc/mod.rs
constant EXCHANGE_NAME (line 8) | pub(super) const EXCHANGE_NAME: &str = "mexc";
function fetch_symbols (line 10) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 19) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/mexc/utils.rs
function check_code_in_body (line 7) | fn check_code_in_body(resp: String) -> Result<String> {
function mexc_http_get (line 22) | pub(super) fn mexc_http_get(url: &str) -> Result<String> {
FILE: crypto-markets/src/exchanges/okx.rs
function fetch_symbols (line 15) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 27) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
type RawMarket (line 42) | struct RawMarket {
method to_market (line 72) | fn to_market(&self) -> Market {
function fetch_raw_markets_raw (line 148) | fn fetch_raw_markets_raw(inst_type: &str) -> Result<Vec<RawMarket>> {
function fetch_spot_symbols (line 185) | fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_inverse_future_symbols (line 191) | fn fetch_inverse_future_symbols() -> Result<Vec<String>> {
function fetch_linear_future_symbols (line 200) | fn fetch_linear_future_symbols() -> Result<Vec<String>> {
function fetch_inverse_swap_symbols (line 209) | fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_symbols (line 218) | fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function fetch_option_symbols (line 227) | fn fetch_option_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 233) | fn fetch_spot_markets() -> Result<Vec<Market>> {
function fetch_inverse_future_markets (line 239) | fn fetch_inverse_future_markets() -> Result<Vec<Market>> {
function fetch_linear_future_markets (line 248) | fn fetch_linear_future_markets() -> Result<Vec<Market>> {
function fetch_inverse_swap_markets (line 257) | fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
function fetch_linear_swap_markets (line 266) | fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
function fetch_option_markets (line 275) | fn fetch_option_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/utils.rs
function http_get (line 6) | pub(super) fn http_get(url: &str, params: Option<&HashMap<String, String...
function precision_from_string (line 38) | fn precision_from_string(s: &str) -> i64 {
function use_system_socks_proxy (line 62) | fn use_system_socks_proxy() {
function use_system_https_proxy (line 71) | fn use_system_https_proxy() {
function test_calc_precision (line 79) | fn test_calc_precision() {
FILE: crypto-markets/src/exchanges/zb/mod.rs
function fetch_symbols (line 6) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 14) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/zb/zb_spot.rs
type SpotMarket (line 12) | struct SpotMarket {
function fetch_spot_markets_raw (line 24) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 35) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 41) | pub(super) fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/zb/zb_swap.rs
type SwapMarket (line 15) | struct SwapMarket {
type Response (line 33) | struct Response {
function fetch_swap_markets_internal (line 39) | fn fetch_swap_markets_internal(url: &str) -> Result<Vec<SwapMarket>> {
function fetch_swap_markets_raw (line 53) | fn fetch_swap_markets_raw() -> Result<Vec<SwapMarket>> {
function fetch_linear_swap_symbols (line 65) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function to_market (line 70) | fn to_market(raw_market: &SwapMarket) -> Market {
function fetch_linear_swap_markets (line 112) | pub(super) fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/zbg/mod.rs
function fetch_symbols (line 6) | pub(crate) fn fetch_symbols(market_type: MarketType) -> Result<Vec<Strin...
function fetch_markets (line 15) | pub(crate) fn fetch_markets(market_type: MarketType) -> Result<Vec<Marke...
FILE: crypto-markets/src/exchanges/zbg/zbg_spot.rs
type SpotMarket (line 15) | struct SpotMarket {
type ResMsg (line 31) | struct ResMsg {
type Response (line 39) | struct Response {
function fetch_spot_markets_raw (line 45) | fn fetch_spot_markets_raw() -> Result<Vec<SpotMarket>> {
function fetch_spot_symbols (line 57) | pub(super) fn fetch_spot_symbols() -> Result<Vec<String>> {
function fetch_spot_markets (line 63) | pub(super) fn fetch_spot_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/exchanges/zbg/zbg_swap.rs
type SwapMarket (line 15) | struct SwapMarket {
type ResMsg (line 32) | struct ResMsg {
type Response (line 40) | struct Response {
function fetch_swap_markets_raw (line 46) | fn fetch_swap_markets_raw() -> Result<Vec<SwapMarket>> {
function fetch_inverse_swap_symbols (line 52) | pub(super) fn fetch_inverse_swap_symbols() -> Result<Vec<String>> {
function fetch_linear_swap_symbols (line 61) | pub(super) fn fetch_linear_swap_symbols() -> Result<Vec<String>> {
function to_market (line 70) | fn to_market(raw_market: &SwapMarket) -> Market {
function fetch_inverse_swap_markets (line 125) | pub(super) fn fetch_inverse_swap_markets() -> Result<Vec<Market>> {
function fetch_linear_swap_markets (line 134) | pub(super) fn fetch_linear_swap_markets() -> Result<Vec<Market>> {
FILE: crypto-markets/src/lib.rs
function fetch_symbols (line 25) | pub fn fetch_symbols(exchange: &str, market_type: MarketType) -> Result<...
function fetch_markets (line 67) | pub fn fetch_markets(exchange: &str, market_type: MarketType) -> Result<...
FILE: crypto-markets/src/main.rs
function main (line 5) | fn main() {
FILE: crypto-markets/src/market.rs
type Fees (line 6) | pub struct Fees {
type Precision (line 12) | pub struct Precision {
type QuantityLimit (line 20) | pub struct QuantityLimit {
type Market (line 37) | pub struct Market {
FILE: crypto-markets/tests/binance.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "binance";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 17) | fn fetch_spot_symbols() {
function fetch_inverse_future_symbols (line 27) | fn fetch_inverse_future_symbols() {
function fetch_linear_future_symbols (line 42) | fn fetch_linear_future_symbols() {
function fetch_inverse_swap_symbols (line 57) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 68) | fn fetch_linear_swap_symbols() {
function fetch_option_symbols (line 80) | fn fetch_option_symbols() {
function fetch_spot_markets (line 91) | fn fetch_spot_markets() {
function fetch_inverse_future_markets (line 105) | fn fetch_inverse_future_markets() {
function fetch_inverse_swap_markets (line 119) | fn fetch_inverse_swap_markets() {
function fetch_linear_swap_markets (line 133) | fn fetch_linear_swap_markets() {
function fetch_option_markets (line 148) | fn fetch_option_markets() {
function test_contract_values (line 166) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/bitfinex.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "bitfinex";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 17) | fn fetch_spot_symbols() {
function fetch_linear_swap_symbols (line 27) | fn fetch_linear_swap_symbols() {
function fetch_spot_markets (line 42) | fn fetch_spot_markets() {
function fetch_linear_swap_markets (line 55) | fn fetch_linear_swap_markets() {
function test_contract_values (line 68) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/bitget.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "bitget";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 17) | fn fetch_spot_symbols() {
function fetch_inverse_swap_symbols (line 31) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 41) | fn fetch_linear_swap_symbols() {
function fetch_inverse_future_symbols (line 51) | fn fetch_inverse_future_symbols() {
function fetch_spot_markets (line 62) | fn fetch_spot_markets() {
function fetch_inverse_swap_markets (line 75) | fn fetch_inverse_swap_markets() {
function fetch_linear_swap_markets (line 89) | fn fetch_linear_swap_markets() {
function fetch_inverse_future_markets (line 103) | fn fetch_inverse_future_markets() {
FILE: crypto-markets/tests/bithumb.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "bithumb";
function fetch_all_symbols (line 11) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 16) | fn fetch_spot_symbols() {
function fetch_spot_markets (line 28) | fn fetch_spot_markets() {
FILE: crypto-markets/tests/bitmex.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "bitmex";
function fetch_all_symbols (line 11) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 18) | fn fetch_spot_symbols() {
function fetch_inverse_swap_symbols (line 29) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 41) | fn fetch_linear_swap_symbols() {
function fetch_quanto_swap_symbols (line 52) | fn fetch_quanto_swap_symbols() {
function fetch_inverse_future_symbols (line 63) | fn fetch_inverse_future_symbols() {
function fetch_quanto_future_symbols (line 81) | fn fetch_quanto_future_symbols() {
function fetch_linear_future_symbols (line 101) | fn fetch_linear_future_symbols() {
function fetch_inverse_swap_markets (line 112) | fn fetch_inverse_swap_markets() {
function test_contract_values (line 124) | fn test_contract_values() {
FILE: crypto-markets/tests/bitstamp.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "bitstamp";
function fetch_all_symbols (line 11) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 16) | fn fetch_spot_symbols() {
function fetch_spot_markets (line 25) | fn fetch_spot_markets() {
FILE: crypto-markets/tests/bitz.rs
constant EXCHANGE_NAME (line 7) | const EXCHANGE_NAME: &str = "bitz";
function fetch_all_symbols (line 11) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 17) | fn fetch_spot_symbols() {
function fetch_inverse_swap_symbols (line 27) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 37) | fn fetch_linear_swap_symbols() {
FILE: crypto-markets/tests/bybit.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "bybit";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_inverse_swap_symbols (line 17) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 27) | fn fetch_linear_swap_symbols() {
function fetch_inverse_future_symbols (line 37) | fn fetch_inverse_future_symbols() {
function fetch_inverse_swap_markets (line 48) | fn fetch_inverse_swap_markets() {
function fetch_linear_swap_markets (line 64) | fn fetch_linear_swap_markets() {
function fetch_inverse_future_markets (line 80) | fn fetch_inverse_future_markets() {
function test_contract_values (line 98) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/coinbase_pro.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "coinbase_pro";
function fetch_all_symbols (line 11) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 16) | fn fetch_spot_symbols() {
function fetch_spot_markets (line 28) | fn fetch_spot_markets() {
FILE: crypto-markets/tests/deribit.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "deribit";
function fetch_inverse_future_symbols (line 12) | fn fetch_inverse_future_symbols() {
function fetch_inverse_swap_symbols (line 27) | fn fetch_inverse_swap_symbols() {
function fetch_option_symbols (line 38) | fn fetch_option_symbols() {
function fetch_inverse_future_markets (line 61) | fn fetch_inverse_future_markets() {
function fetch_inverse_swap_markets (line 75) | fn fetch_inverse_swap_markets() {
function fetch_option_markets (line 89) | fn fetch_option_markets() {
function test_contract_values (line 105) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/dydx.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "dydx";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_linear_swap_symbols (line 17) | fn fetch_linear_swap_symbols() {
function fetch_linear_swap_markets (line 28) | fn fetch_linear_swap_markets() {
function test_contract_values (line 41) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/ftx.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "ftx";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 18) | fn fetch_spot_symbols() {
function fetch_linear_swap_symbols (line 30) | fn fetch_linear_swap_symbols() {
function fetch_linear_future_symbols (line 41) | fn fetch_linear_future_symbols() {
function fetch_move_symbols (line 53) | fn fetch_move_symbols() {
function fetch_bvol_symbols (line 64) | fn fetch_bvol_symbols() {
function fetch_spot_markets (line 75) | fn fetch_spot_markets() {
function fetch_linear_swap_markets (line 88) | fn fetch_linear_swap_markets() {
function fetch_linear_future_markets (line 101) | fn fetch_linear_future_markets() {
function fetch_move_markets (line 115) | fn fetch_move_markets() {
function fetch_bvol_markets (line 129) | fn fetch_bvol_markets() {
FILE: crypto-markets/tests/gate.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "gate";
function fetch_all_symbols (line 11) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 16) | fn fetch_spot_symbols() {
function fetch_inverse_swap_symbols (line 30) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 39) | fn fetch_linear_swap_symbols() {
function fetch_inverse_future_symbols (line 48) | fn fetch_inverse_future_symbols() {
function fetch_linear_future_symbols (line 58) | fn fetch_linear_future_symbols() {
function fetch_spot_markets (line 69) | fn fetch_spot_markets() {
function fetch_inverse_swap_markets (line 84) | fn fetch_inverse_swap_markets() {
function fetch_linear_swap_markets (line 99) | fn fetch_linear_swap_markets() {
function fetch_inverse_future_markets (line 115) | fn fetch_inverse_future_markets() {
function fetch_linear_future_markets (line 131) | fn fetch_linear_future_markets() {
function test_contract_values (line 151) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/huobi.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "huobi";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 17) | fn fetch_spot_symbols() {
function fetch_inverse_future_symbols (line 27) | fn fetch_inverse_future_symbols() {
function fetch_inverse_swap_symbols (line 42) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 52) | fn fetch_linear_swap_symbols() {
function fetch_option_symbols (line 63) | fn fetch_option_symbols() {
function fetch_spot_markets (line 73) | fn fetch_spot_markets() {
function fetch_inverse_future_markets (line 86) | fn fetch_inverse_future_markets() {
function fetch_inverse_swap_markets (line 97) | fn fetch_inverse_swap_markets() {
function fetch_linear_swap_markets (line 108) | fn fetch_linear_swap_markets() {
function test_contract_values (line 121) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/kraken.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "kraken";
function fetch_all_symbols (line 11) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 16) | fn fetch_spot_symbols() {
function fetch_inverse_future_symbols (line 26) | fn fetch_inverse_future_symbols() {
function fetch_inverse_swap_symbols (line 38) | fn fetch_inverse_swap_symbols() {
function fetch_spot_markets (line 49) | fn fetch_spot_markets() {
function fetch_inverse_future_markets (line 62) | fn fetch_inverse_future_markets() {
function fetch_inverse_swap_markets (line 75) | fn fetch_inverse_swap_markets() {
FILE: crypto-markets/tests/kucoin.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "kucoin";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 17) | fn fetch_spot_symbols() {
function fetch_inverse_swap_symbols (line 28) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 38) | fn fetch_linear_swap_symbols() {
function fetch_inverse_future_symbols (line 48) | fn fetch_inverse_future_symbols() {
function fetch_spot_markets (line 58) | fn fetch_spot_markets() {
function fetch_inverse_future_markets (line 73) | fn fetch_inverse_future_markets() {
function fetch_inverse_swap_markets (line 86) | fn fetch_inverse_swap_markets() {
function fetch_linear_swap_markets (line 99) | fn fetch_linear_swap_markets() {
function test_contract_values (line 114) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/mexc.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "mexc";
function fetch_spot_symbols (line 12) | fn fetch_spot_symbols() {
function fetch_linear_swap_symbols (line 24) | fn fetch_linear_swap_symbols() {
function fetch_inverse_swap_symbols (line 34) | fn fetch_inverse_swap_symbols() {
function fetch_spot_markets (line 44) | fn fetch_spot_markets() {
function fetch_inverse_swap_markets (line 59) | fn fetch_inverse_swap_markets() {
function fetch_linear_swap_markets (line 74) | fn fetch_linear_swap_markets() {
function test_contract_values (line 90) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/okx.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "okx";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 17) | fn fetch_spot_symbols() {
function fetch_inverse_future_symbols (line 27) | fn fetch_inverse_future_symbols() {
function fetch_linear_future_symbols (line 40) | fn fetch_linear_future_symbols() {
function fetch_inverse_swap_symbols (line 53) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 63) | fn fetch_linear_swap_symbols() {
function fetch_option_symbols (line 73) | fn fetch_option_symbols() {
function fetch_spot_markets (line 83) | fn fetch_spot_markets() {
function fetch_inverse_future_markets (line 96) | fn fetch_inverse_future_markets() {
function fetch_linear_future_markets (line 109) | fn fetch_linear_future_markets() {
function fetch_inverse_swap_markets (line 122) | fn fetch_inverse_swap_markets() {
function fetch_linear_swap_markets (line 135) | fn fetch_linear_swap_markets() {
function fetch_option_markets (line 148) | fn fetch_option_markets() {
function test_contract_values (line 165) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/zb.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "zb";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 17) | fn fetch_spot_symbols() {
function fetch_linear_swap_symbols (line 34) | fn fetch_linear_swap_symbols() {
function fetch_spot_markets (line 45) | fn fetch_spot_markets() {
function fetch_linear_swap_markets (line 60) | fn fetch_linear_swap_markets() {
function test_contract_values (line 75) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-markets/tests/zbg.rs
constant EXCHANGE_NAME (line 9) | const EXCHANGE_NAME: &str = "zbg";
function fetch_all_symbols (line 12) | fn fetch_all_symbols() {
function fetch_spot_symbols (line 17) | fn fetch_spot_symbols() {
function fetch_inverse_swap_symbols (line 28) | fn fetch_inverse_swap_symbols() {
function fetch_linear_swap_symbols (line 38) | fn fetch_linear_swap_symbols() {
function fetch_spot_markets (line 48) | fn fetch_spot_markets() {
function fetch_inverse_swap_markets (line 63) | fn fetch_inverse_swap_markets() {
function fetch_linear_swap_markets (line 76) | fn fetch_linear_swap_markets() {
function test_contract_values (line 90) | fn test_contract_values(market_type: MarketType) {
FILE: crypto-msg-type/include/crypto_msg_type.h
type MessageType (line 11) | typedef enum {
FILE: crypto-msg-type/src/exchanges/binance.rs
function msg_type_to_channel (line 5) | fn msg_type_to_channel(msg_type: MessageType) -> &'static str {
function channel_symbol_to_topic (line 17) | fn channel_symbol_to_topic(
function topics_to_command (line 29) | fn topics_to_command(topics: &[String], subscribe: bool) -> String {
function get_ws_commands (line 40) | pub(crate) fn get_ws_commands(
function single_msg_type_multiple_symbols (line 61) | fn single_msg_type_multiple_symbols() {
function multiple_msg_types_single_symbol (line 76) | fn multiple_msg_types_single_symbol() {
function candlestick (line 91) | fn candlestick() {
FILE: crypto-msg-type/src/exchanges/bitfinex.rs
function msg_type_symbol_to_command (line 5) | fn msg_type_symbol_to_command(
function get_ws_commands (line 36) | pub(crate) fn get_ws_commands(
function single_msg_type_multiple_symbols (line 57) | fn single_msg_type_multiple_symbols() {
function multiple_msg_types_single_symbol (line 70) | fn multiple_msg_types_single_symbol() {
function candlestick (line 86) | fn candlestick() {
FILE: crypto-msg-type/src/exchanges/bitmex.rs
function msg_type_to_channel (line 5) | fn msg_type_to_channel(msg_type: MessageType) -> &'static str {
function channel_symbol_to_topic (line 16) | fn channel_symbol_to_topic(
function topics_to_command (line 28) | fn topics_to_command(topics: &[String], subscribe: bool) -> String {
function get_ws_commands (line 36) | pub(crate) fn get_ws_commands(
function single_msg_type_multiple_symbols (line 57) | fn single_msg_type_multiple_symbols() {
function multiple_msg_types_single_symbol (line 69) | fn multiple_msg_types_single_symbol() {
function candlestick (line 84) | fn candlestick() {
FILE: crypto-msg-type/src/exchanges/bybit.rs
function msg_type_to_channel (line 5) | fn msg_type_to_channel(msg_type: MessageType) -> &'static str {
function channel_symbol_to_topic (line 15) | fn channel_symbol_to_topic(
function topics_to_command (line 32) | fn topics_to_command(topics: &[String], subscribe: bool) -> String {
function get_ws_commands (line 40) | pub(crate) fn get_ws_commands(
function single_msg_type_multiple_symbols (line 61) | fn single_msg_type_multiple_symbols() {
function multiple_msg_types_single_symbol (line 73) | fn multiple_msg_types_single_symbol() {
function candlestick (line 88) | fn candlestick() {
FILE: crypto-msg-type/src/exchanges/deribit.rs
function msg_type_symbol_to_topic (line 5) | fn msg_type_symbol_to_topic(
function topics_to_command (line 23) | fn topics_to_command(topics: &[String], subscribe: bool) -> String {
function get_ws_commands (line 31) | pub(crate) fn get_ws_commands(
function single_msg_type_multiple_symbols (line 51) | fn single_msg_type_multiple_symbols() {
function multiple_msg_types_single_symbol (line 66) | fn multiple_msg_types_single_symbol() {
function candlestick (line 81) | fn candlestick() {
FILE: crypto-msg-type/src/exchanges/ftx.rs
function msg_type_to_channel (line 5) | fn msg_type_to_channel(msg_type: MessageType) -> &'static str {
function channel_symbol_to_command (line 14) | fn channel_symbol_to_command(channel: &str, symbol: &str, subscribe: boo...
function get_ws_commands (line 23) | pub(crate) fn get_ws_commands(
function single_msg_type_multiple_symbols (line 43) | fn single_msg_type_multiple_symbols() {
function multiple_msg_types_single_symbol (line 57) | fn multiple_msg_types_single_symbol() {
FILE: crypto-msg-type/src/exchanges/huobi.rs
function msg_type_symbol_to_topic (line 5) | fn msg_type_symbol_to_topic(
function topic_to_command (line 39) | fn topic_to_command(topic: &str, subscribe: bool) -> String {
function get_ws_commands (line 55) | pub(crate) fn get_ws_commands(
function single_msg_type_multiple_symbols (line 75) | fn single_msg_type_multiple_symbols() {
function multiple_msg_types_single_symbol (line 88) | fn multiple_msg_types_single_symbol() {
function candlestick (line 104) | fn candlestick() {
FILE: crypto-msg-type/src/exchanges/okex.rs
function get_market_type (line 5) | fn get_market_type(symbol: &str) -> &'static str {
function msg_type_to_channel (line 23) | fn msg_type_to_channel(msg_type: MessageType) -> &'static str {
function channel_symbol_to_topic (line 35) | fn channel_symbol_to_topic(
function topics_to_command (line 48) | fn topics_to_command(topics: &[String], subscribe: bool) -> String {
function get_ws_commands (line 56) | pub(crate) fn get_ws_commands(
function single_msg_type_multiple_symbols (line 77) | fn single_msg_type_multiple_symbols() {
function multiple_msg_types_single_symbol (line 92) | fn multiple_msg_types_single_symbol() {
function candlestick (line 107) | fn candlestick() {
FILE: crypto-msg-type/src/exchanges/okx.rs
function msg_type_to_channel (line 5) | fn msg_type_to_channel(msg_type: MessageType) -> &'static str {
function channel_symbol_to_topic (line 16) | fn channel_symbol_to_topic(
function topics_to_command (line 28) | fn topics_to_command(topics: &[String], subscribe: bool) -> String {
function get_ws_commands (line 48) | pub(crate) fn get_ws_commands(
function single_msg_type_multiple_symbols (line 69) | fn single_msg_type_multiple_symbols() {
function multiple_msg_types_single_symbol (line 84) | fn multiple_msg_types_single_symbol() {
function candlestick (line 99) | fn candlestick() {
FILE: crypto-msg-type/src/lib.rs
type MessageType (line 16) | pub enum MessageType {
function get_ws_commands (line 55) | pub fn get_ws_commands(
FILE: crypto-rest-client/src/error.rs
type Result (line 3) | pub(crate) type Result<T> = std::result::Result<T, Error>;
type Error (line 6) | pub struct Error(pub String);
method fmt (line 9) | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
method from (line 17) | fn from(err: reqwest::Error) -> Self {
method from (line 23) | fn from(err: serde_json::Error) -> Self {
FILE: crypto-rest-client/src/exchanges/binance/binance_inverse.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://dapi.binance.com";
type BinanceInverseRestClient (line 13) | pub struct BinanceInverseRestClient {
method new (line 19) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_agg_trades (line 31) | pub fn fetch_agg_trades(
method fetch_l2_snapshot (line 51) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 64) | pub fn fetch_open_interest(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/binance/binance_linear.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://fapi.binance.com";
type BinanceLinearRestClient (line 13) | pub struct BinanceLinearRestClient {
method new (line 19) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_agg_trades (line 31) | pub fn fetch_agg_trades(
method fetch_l2_snapshot (line 51) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 64) | pub fn fetch_open_interest(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/binance/binance_option.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://vapi.binance.com";
type BinanceOptionRestClient (line 11) | pub struct BinanceOptionRestClient {
method new (line 17) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 26) | pub fn fetch_trades(symbol: &str, start_time: Option<u64>) -> Result<S...
method fetch_l2_snapshot (line 35) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/binance/binance_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.binance.com";
type BinanceSpotRestClient (line 14) | pub struct BinanceSpotRestClient {
method new (line 20) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_agg_trades (line 29) | pub fn fetch_agg_trades(
method fetch_l2_snapshot (line 46) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/binance/mod.rs
function fetch_l2_snapshot (line 12) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
function fetch_open_interest (line 28) | pub(crate) fn fetch_open_interest(market_type: MarketType, symbol: &str)...
FILE: crypto-rest-client/src/exchanges/binance/utils.rs
function check_symbol (line 11) | pub(super) fn check_symbol(symbol: &str) {
function check_code_in_body (line 17) | pub(super) fn check_code_in_body(resp: String) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/bitfinex.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api-pub.bitfinex.com";
type BitfinexRestClient (line 13) | pub struct BitfinexRestClient {
method new (line 19) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 24) | pub fn fetch_trades(
method fetch_l2_snapshot (line 41) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_l3_snapshot (line 51) | pub fn fetch_l3_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/bitget/bitget_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.bitget.com";
type BitgetSpotRestClient (line 11) | pub struct BitgetSpotRestClient {
method new (line 17) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 26) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/bitget/bitget_swap.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.bitget.com";
type BitgetSwapRestClient (line 11) | pub struct BitgetSwapRestClient {
method new (line 17) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 26) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 35) | pub fn fetch_open_interest(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/bitget/mod.rs
function fetch_l2_snapshot (line 10) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
function fetch_open_interest (line 22) | pub(crate) fn fetch_open_interest(market_type: MarketType, symbol: &str)...
FILE: crypto-rest-client/src/exchanges/bithumb.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://global-openapi.bithumb.pro/openapi/v1";
type BithumbRestClient (line 16) | pub struct BithumbRestClient {
method new (line 22) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 29) | pub fn fetch_trades(symbol: &str) -> Result<String> {
method fetch_l2_snapshot (line 36) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/bitmex.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://www.bitmex.com/api/v1";
type BitmexRestClient (line 17) | pub struct BitmexRestClient {
method new (line 23) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 33) | pub fn fetch_trades(symbol: &str, start_time: Option<String>) -> Resul...
method fetch_l2_snapshot (line 44) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/bitstamp.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://www.bitstamp.net/api";
type BitstampRestClient (line 16) | pub struct BitstampRestClient {
method new (line 22) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 34) | pub fn fetch_trades(symbol: &str, time: Option<String>) -> Result<Stri...
method fetch_l2_snapshot (line 43) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_l3_snapshot (line 52) | pub fn fetch_l3_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/bitz/bitz_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://apiv2.bitz.com";
type BitzSpotRestClient (line 13) | pub struct BitzSpotRestClient {
method new (line 19) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 26) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/bitz/bitz_swap.rs
constant BASE_URL (line 8) | const BASE_URL: &str = "https://apiv2.bitz.com";
type BitzSwapRestClient (line 16) | pub struct BitzSwapRestClient {
method new (line 22) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 31) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 43) | pub fn fetch_open_interest(symbol: Option<&str>) -> Result<String> {
type SwapMarket (line 59) | struct SwapMarket {
type Response (line 68) | struct Response {
function get_symbol_id_map (line 77) | fn get_symbol_id_map() -> Result<HashMap<String, String>> {
FILE: crypto-rest-client/src/exchanges/bitz/mod.rs
function fetch_l2_snapshot (line 10) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
function fetch_open_interest (line 22) | pub(crate) fn fetch_open_interest(market_type: MarketType, symbol: Optio...
FILE: crypto-rest-client/src/exchanges/bybit.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.bybit.com/v2";
type BybitRestClient (line 22) | pub struct BybitRestClient {
method new (line 28) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 37) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 48) | pub fn fetch_open_interest(symbol: &str) -> Result<String> {
method fetch_long_short_ratio (line 59) | pub fn fetch_long_short_ratio(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/coinbase_pro.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.exchange.coinbase.com";
type CoinbaseProRestClient (line 16) | pub struct CoinbaseProRestClient {
method new (line 22) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 31) | pub fn fetch_trades(symbol: &str) -> Result<String> {
method fetch_l2_snapshot (line 40) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_l3_snapshot (line 49) | pub fn fetch_l3_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/deribit.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://www.deribit.com/api/v2";
type DeribitRestClient (line 17) | pub struct DeribitRestClient {
method new (line 23) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 32) | pub fn fetch_trades(symbol: &str) -> Result<String> {
method fetch_l2_snapshot (line 43) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 52) | pub fn fetch_open_interest(symbol: Option<&str>) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/dydx/dydx_swap.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.dydx.exchange";
type DydxSwapRestClient (line 13) | pub struct DydxSwapRestClient {
method new (line 19) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 28) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 35) | pub fn fetch_open_interest() -> Result<String> {
FILE: crypto-rest-client/src/exchanges/dydx/mod.rs
function fetch_l2_snapshot (line 6) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
function fetch_open_interest (line 15) | pub(crate) fn fetch_open_interest(market_type: MarketType) -> Result<Str...
FILE: crypto-rest-client/src/exchanges/ftx.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://ftx.com/api";
type FtxRestClient (line 16) | pub struct FtxRestClient {
method new (line 22) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 32) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 40) | pub fn fetch_open_interest() -> Result<String> {
FILE: crypto-rest-client/src/exchanges/gate/gate_future.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.gateio.ws/api/v4";
type GateFutureRestClient (line 11) | pub struct GateFutureRestClient {
method new (line 17) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 29) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/gate/gate_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.gateio.ws/api/v4";
type GateSpotRestClient (line 13) | pub struct GateSpotRestClient {
method new (line 19) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 28) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/gate/gate_swap.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.gateio.ws/api/v4";
type GateSwapRestClient (line 13) | pub struct GateSwapRestClient {
method new (line 19) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 31) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 47) | pub fn fetch_open_interest(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/gate/mod.rs
function fetch_l2_snapshot (line 12) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
function fetch_open_interest (line 27) | pub(crate) fn fetch_open_interest(market_type: MarketType, symbol: &str)...
FILE: crypto-rest-client/src/exchanges/huobi/huobi_future.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.hbdm.com";
type HuobiFutureRestClient (line 14) | pub struct HuobiFutureRestClient {
method fetch_l2_snapshot (line 27) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 34) | pub fn fetch_open_interest(symbol: Option<&str>) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/huobi/huobi_inverse_swap.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.hbdm.com";
type HuobiInverseSwapRestClient (line 16) | pub struct HuobiInverseSwapRestClient {
method fetch_l2_snapshot (line 29) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 36) | pub fn fetch_open_interest(symbol: Option<&str>) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/huobi/huobi_linear_swap.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.hbdm.com";
type HuobiLinearSwapRestClient (line 16) | pub struct HuobiLinearSwapRestClient {
method fetch_l2_snapshot (line 29) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 36) | pub fn fetch_open_interest(symbol: Option<&str>) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/huobi/huobi_option.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.hbdm.com/option-ex";
type HuobiOptionRestClient (line 15) | pub struct HuobiOptionRestClient {
method fetch_l2_snapshot (line 28) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/huobi/huobi_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.huobi.pro";
type HuobiSpotRestClient (line 14) | pub struct HuobiSpotRestClient {
method fetch_l2_snapshot (line 27) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/huobi/mod.rs
function fetch_l2_snapshot (line 13) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
function fetch_open_interest (line 38) | pub(crate) fn fetch_open_interest(market_type: MarketType, symbol: Optio...
FILE: crypto-rest-client/src/exchanges/kraken/kraken_futures.rs
constant BASE_URL (line 6) | const BASE_URL: &str = "https://futures.kraken.com/derivatives/api/v3";
type KrakenFuturesRestClient (line 14) | pub struct KrakenFuturesRestClient {
method new (line 20) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 31) | pub fn fetch_trades(symbol: &str, lastTime: Option<String>) -> Result<...
method fetch_l2_snapshot (line 38) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/kraken/kraken_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.kraken.com";
type KrakenSpotRestClient (line 15) | pub struct KrakenSpotRestClient {
method new (line 21) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 31) | pub fn fetch_trades(symbol: &str, since: Option<String>) -> Result<Str...
method fetch_l2_snapshot (line 47) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/kraken/mod.rs
function fetch_l2_snapshot (line 7) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
FILE: crypto-rest-client/src/exchanges/kucoin/kucoin_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.kucoin.com";
type KuCoinSpotRestClient (line 12) | pub struct KuCoinSpotRestClient {
method new (line 18) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 25) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_l3_snapshot (line 40) | pub fn fetch_l3_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/kucoin/kucoin_swap.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api-futures.kucoin.com";
type KuCoinSwapRestClient (line 12) | pub struct KuCoinSwapRestClient {
method new (line 18) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 27) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_l3_snapshot (line 37) | pub fn fetch_l3_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 45) | pub fn fetch_open_interest() -> Result<String> {
FILE: crypto-rest-client/src/exchanges/kucoin/mod.rs
function fetch_l2_snapshot (line 10) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
function fetch_l3_snapshot (line 22) | pub(crate) fn fetch_l3_snapshot(market_type: MarketType, symbol: &str) -...
function fetch_open_interest (line 34) | pub(crate) fn fetch_open_interest(market_type: MarketType) -> Result<Str...
FILE: crypto-rest-client/src/exchanges/mexc/mexc_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://www.mexc.com";
type MexcSpotRestClient (line 13) | pub struct MexcSpotRestClient {
method new (line 19) | pub fn new(access_key: String, secret_key: Option<String>) -> Self {
method fetch_trades (line 29) | pub fn fetch_trades(symbol: &str) -> Result<String> {
method fetch_l2_snapshot (line 38) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/mexc/mexc_swap.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://contract.mexc.com";
type MexcSwapRestClient (line 11) | pub struct MexcSwapRestClient {
method new (line 17) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 24) | pub fn fetch_trades(symbol: &str) -> Result<String> {
method fetch_l2_snapshot (line 35) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/mexc/mod.rs
function fetch_l2_snapshot (line 7) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
FILE: crypto-rest-client/src/exchanges/okx.rs
constant BASE_URL (line 7) | const BASE_URL: &str = "https://www.okx.com";
type OkxRestClient (line 19) | pub struct OkxRestClient {
method new (line 25) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_trades (line 34) | pub fn fetch_trades(symbol: &str) -> Result<String> {
method fetch_l2_snapshot (line 47) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_option_underlying (line 52) | pub fn fetch_option_underlying() -> Result<Vec<String>> {
method fetch_open_interest (line 71) | pub fn fetch_open_interest(market_type: MarketType, symbol: Option<&st...
FILE: crypto-rest-client/src/exchanges/utils.rs
function http_get_raw (line 7) | pub(super) fn http_get_raw(url: &str, params: &BTreeMap<String, String>)...
function http_get (line 33) | pub(super) fn http_get(url: &str, params: &BTreeMap<String, String>) -> ...
function use_system_socks_proxy (line 68) | fn use_system_socks_proxy() {
function use_system_https_proxy (line 78) | fn use_system_https_proxy() {
FILE: crypto-rest-client/src/exchanges/zb/mod.rs
function fetch_l2_snapshot (line 10) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
FILE: crypto-rest-client/src/exchanges/zb/zb_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://api.zb.com";
type ZbSpotRestClient (line 11) | pub struct ZbSpotRestClient {
method new (line 17) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 26) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/zb/zb_swap.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://fapi.zb.com";
type ZbSwapRestClient (line 11) | pub struct ZbSwapRestClient {
method new (line 17) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 28) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/zbg/mod.rs
function fetch_l2_snapshot (line 10) | pub(crate) fn fetch_l2_snapshot(market_type: MarketType, symbol: &str) -...
function fetch_open_interest (line 22) | pub(crate) fn fetch_open_interest(market_type: MarketType, symbol: &str)...
FILE: crypto-rest-client/src/exchanges/zbg/zbg_spot.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://kline.zbg.com";
type ZbgSpotRestClient (line 11) | pub struct ZbgSpotRestClient {
method new (line 17) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 26) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/exchanges/zbg/zbg_swap.rs
constant BASE_URL (line 5) | const BASE_URL: &str = "https://www.zbg.com";
type ZbgSwapRestClient (line 11) | pub struct ZbgSwapRestClient {
method new (line 17) | pub fn new(api_key: Option<String>, api_secret: Option<String>) -> Self {
method fetch_l2_snapshot (line 26) | pub fn fetch_l2_snapshot(symbol: &str) -> Result<String> {
method fetch_open_interest (line 35) | pub fn fetch_open_interest(symbol: &str) -> Result<String> {
FILE: crypto-rest-client/src/lib.rs
function fetch_l2_snapshot_internal (line 40) | fn fetch_l2_snapshot_internal(
function fetch_l3_snapshot_internal (line 74) | pub fn fetch_l3_snapshot_internal(
function fetch_open_interest (line 95) | pub fn fetch_open_interest(
function fetch_long_short_ratio (line 121) | pub fn fetch_long_short_ratio(
function fetch_l2_snapshot (line 140) | pub fn fetch_l2_snapshot(
function fetch_l3_snapshot (line 153) | pub fn fetch_l3_snapshot(
function retriable (line 164) | fn retriable(
FILE: crypto-rest-client/tests/binance_inverse.rs
function test_agg_trades (line 7) | fn test_agg_trades() {
function test_l2_snapshot (line 14) | fn test_l2_snapshot() {
function test_open_interest (line 21) | fn test_open_interest() {
function test_agg_trades (line 34) | fn test_agg_trades() {
function test_l2_snapshot (line 41) | fn test_l2_snapshot() {
function test_open_interest (line 49) | fn test_open_interest() {
FILE: crypto-rest-client/tests/binance_linear.rs
function test_agg_trades (line 7) | fn test_agg_trades() {
function test_l2_snapshot (line 13) | fn test_l2_snapshot() {
function test_open_interest (line 20) | fn test_open_interest() {
function test_agg_trades (line 32) | fn test_agg_trades() {
function test_l2_snapshot (line 39) | fn test_l2_snapshot() {
function test_open_interest (line 47) | fn test_open_interest() {
FILE: crypto-rest-client/tests/binance_option.rs
function test_agg_trades (line 6) | fn test_agg_trades() {
function test_l2_snapshot (line 13) | fn test_l2_snapshot() {
FILE: crypto-rest-client/tests/binance_spot.rs
function test_agg_trades (line 5) | fn test_agg_trades() {
function test_l2_snapshot (line 11) | fn test_l2_snapshot() {
FILE: crypto-rest-client/tests/bitfinex.rs
function test_trades (line 5) | fn test_trades() {
function test_l2_snapshot (line 11) | fn test_l2_snapshot() {
function test_l3_snapshot (line 17) | fn test_l3_snapshot() {
FILE: crypto-rest-client/tests/bitget_spot.rs
function test_l2_snapshot (line 7) | fn test_l2_snapshot() {
FILE: crypto-rest-client/tests/bitget_swap.rs
function test_l2_snapshot (line 10) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 22) | fn test_open_interest(market_type: MarketType, symbol: &str) {
FILE: crypto-rest-client/tests/bithumb.rs
function test_trades (line 8) | fn test_trades() {
function test_l2_snapshot (line 18) | fn test_l2_snapshot() {
FILE: crypto-rest-client/tests/bitmex.rs
function test_trades (line 5) | fn test_trades() {
function test_l2_snapshot (line 11) | fn test_l2_snapshot() {
FILE: crypto-rest-client/tests/bitstamp.rs
function test_trades (line 5) | fn test_trades() {
function test_l2_snapshot (line 11) | fn test_l2_snapshot() {
function test_l3_snapshot (line 17) | fn test_l3_snapshot() {
FILE: crypto-rest-client/tests/bitz_spot.rs
function test_l2_snapshot (line 9) | fn test_l2_snapshot() {
FILE: crypto-rest-client/tests/bitz_swap.rs
function test_l2_snapshot (line 10) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 23) | fn test_open_interest(market_type: MarketType) {
FILE: crypto-rest-client/tests/bybit.rs
function test_l2_snapshot (line 11) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 24) | fn test_open_interest(market_type: MarketType, symbol: &str) {
function test_long_short_ratio (line 36) | fn test_long_short_ratio(market_type: MarketType, symbol: &str) {
FILE: crypto-rest-client/tests/coinbase_pro.rs
function test_trades (line 5) | fn test_trades() {
function test_l2_snapshot (line 11) | fn test_l2_snapshot() {
function test_l3_snapshot (line 17) | fn test_l3_snapshot() {
FILE: crypto-rest-client/tests/deribit.rs
function test_trades (line 10) | fn test_trades(symbol: &str) {
function test_l2_snapshot (line 22) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 35) | fn test_open_interest(market_type: MarketType) {
FILE: crypto-rest-client/tests/dydx.rs
function test_l2_snapshot (line 8) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 19) | fn test_open_interest(market_type: MarketType) {
FILE: crypto-rest-client/tests/ftx.rs
function test_l2_snapshot (line 13) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 24) | fn test_open_interest() {
FILE: crypto-rest-client/tests/gate.rs
function test_l2_snapshot (line 12) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 25) | fn test_open_interest(market_type: MarketType, symbol: &str) {
FILE: crypto-rest-client/tests/huobi.rs
function test_l2_snapshot (line 12) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 31) | fn test_open_interest(market_type: MarketType) {
function test_trades (line 43) | fn test_trades() {
function test_trades (line 54) | fn test_trades() {
function test_trades (line 65) | fn test_trades() {
function test_trades (line 76) | fn test_trades() {
function test_trades (line 88) | fn test_trades() {
FILE: crypto-rest-client/tests/kraken.rs
function test_trades (line 9) | fn test_trades() {
function test_restful_accepts_two_symbols (line 20) | fn test_restful_accepts_two_symbols() {
function test_l2_snapshot (line 34) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
FILE: crypto-rest-client/tests/kucoin.rs
function test_l2_snapshot (line 11) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_l3_snapshot (line 30) | fn test_l3_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 47) | fn test_open_interest(market_type: MarketType) {
FILE: crypto-rest-client/tests/mexc.rs
function test_trades (line 6) | fn test_trades() {
function test_l2_snapshot (line 12) | fn test_l2_snapshot() {
function test_trades (line 24) | fn test_trades() {
function test_l2_snapshot (line 30) | fn test_l2_snapshot() {
FILE: crypto-rest-client/tests/okx.rs
function test_l2_snapshot (line 13) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 23) | fn test_open_interest(market_type: MarketType, symbol: &str) {
function test_trades (line 38) | fn test_trades() {
function test_option_underlying (line 46) | fn test_option_underlying() {
FILE: crypto-rest-client/tests/zb.rs
function test_spot_l2_snapshot (line 8) | fn test_spot_l2_snapshot() {
function test_swap_l2_snapshot (line 17) | fn test_swap_l2_snapshot() {
FILE: crypto-rest-client/tests/zbg.rs
function test_l2_snapshot (line 11) | fn test_l2_snapshot(market_type: MarketType, symbol: &str) {
function test_open_interest (line 31) | fn test_open_interest(market_type: MarketType, symbol: &str) {
FILE: crypto-ws-client/src/clients/binance.rs
constant EXCHANGE_NAME (line 18) | pub(crate) const EXCHANGE_NAME: &str = "binance";
constant SPOT_WEBSOCKET_URL (line 20) | const SPOT_WEBSOCKET_URL: &str = "wss://stream.binance.com:9443/stream";
constant LINEAR_WEBSOCKET_URL (line 21) | const LINEAR_WEBSOCKET_URL: &str = "wss://fstream.binance.com/stream";
constant INVERSE_WEBSOCKET_URL (line 22) | const INVERSE_WEBSOCKET_URL: &str = "wss://dstream.binance.com/stream";
constant WS_FRAME_SIZE (line 26) | const WS_FRAME_SIZE: usize = 4096;
constant UPLINK_LIMIT (line 35) | const UPLINK_LIMIT: (NonZeroU32, std::time::Duration) =
type BinanceWSClient (line 39) | pub struct BinanceWSClient<const MARKET_TYPE: char> {
type BinanceSpotWSClient (line 48) | pub type BinanceSpotWSClient = BinanceWSClient<'S'>;
type BinanceInverseWSClient (line 54) | pub type BinanceInverseWSClient = BinanceWSClient<'I'>;
type BinanceLinearWSClient (line 60) | pub type BinanceLinearWSClient = BinanceWSClient<'L'>;
function new (line 63) | pub async fn new(tx: std::sync::mpsc::Sender<String>, url: Option<&str>)...
method subscribe_trade (line 94) | async fn subscribe_trade(&self, symbols: &[String]) {
method subscribe_orderbook (line 102) | async fn subscribe_orderbook(&self, symbols: &[String]) {
method subscribe_orderbook_topk (line 110) | async fn subscribe_orderbook_topk(&self, symbols: &[String]) {
method subscribe_l3_orderbook (line 118) | async fn subscribe_l3_orderbook(&self, _symbols: &[String]) {
method subscribe_ticker (line 122) | async fn subscribe_ticker(&self, symbols: &[String]) {
method subscribe_bbo (line 130) | async fn subscribe_bbo(&self, symbols: &[String]) {
method subscribe_candlestick (line 138) | async fn subscribe_candlestick(&self, symbol_interval_list: &[(String, u...
method subscribe (line 144) | async fn subscribe(&self, topics: &[(String, String)]) {
method unsubscribe (line 149) | async fn unsubscribe(&self, topics: &[(String, String)]) {
method send (line 154) | async fn send(&self, commands: &[String]) {
method run (line 158) | async fn run(&self) {
method close (line 162) | async fn close(&self) {
type BinanceMessageHandler (line 167) | struct BinanceMessageHandler {}
type BinanceCommandTranslator (line 168) | struct BinanceCommandTranslator {
method topics_to_command (line 173) | fn topics_to_command(topics: &[(String, String)], subscribe: bool) -> ...
method to_candlestick_raw_channel (line 186) | fn to_candlestick_raw_channel(interval: usize) -> String {
method handle_message (line 210) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 236) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 249) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 267) | fn translate_to_candlestick_commands(
function test_one_topic (line 288) | fn test_one_topic() {
function test_two_topics (line 301) | fn test_two_topics() {
FILE: crypto-ws-client/src/clients/binance_option.rs
constant EXCHANGE_NAME (line 19) | pub(crate) const EXCHANGE_NAME: &str = "binance";
constant WEBSOCKET_URL (line 21) | pub(super) const WEBSOCKET_URL: &str = "wss://stream.opsnest.com/stream";
type BinanceOptionWSClient (line 27) | pub struct BinanceOptionWSClient {
type BinanceOptionMessageHandler (line 52) | struct BinanceOptionMessageHandler {}
type BinanceOptionCommandTranslator (line 53) | struct BinanceOptionCommandTranslator {}
method topics_to_command (line 56) | fn topics_to_command(topics: &[(String, String)], subscribe: bool) -> ...
method to_candlestick_raw_channel (line 69) | fn to_candlestick_raw_channel(interval: usize) -> String {
method handle_message (line 86) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 118) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 129) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 134) | fn translate_to_candlestick_commands(
function test_one_topic (line 155) | fn test_one_topic() {
function test_two_topics (line 170) | fn test_two_topics() {
FILE: crypto-ws-client/src/clients/bitfinex.rs
constant EXCHANGE_NAME (line 23) | pub(super) const EXCHANGE_NAME: &str = "bitfinex";
constant WEBSOCKET_URL (line 25) | const WEBSOCKET_URL: &str = "wss://api-pub.bitfinex.com/ws/2";
type BitfinexWSClient (line 33) | pub struct BitfinexWSClient {
method subscribe_orderbook (line 55) | async fn subscribe_orderbook(&self, symbols: &[String]) {
method subscribe_l3_orderbook (line 70) | async fn subscribe_l3_orderbook(&self, symbols: &[String]) {
type BitfinexMessageHandler (line 85) | struct BitfinexMessageHandler {
type BitfinexCommandTranslator (line 88) | struct BitfinexCommandTranslator {}
method topic_to_command (line 91) | fn topic_to_command(channel: &str, symbol: &str, subscribe: bool) -> S...
method to_candlestick_command (line 99) | fn to_candlestick_command(symbol: &str, interval: usize, subscribe: bo...
method handle_message (line 126) | fn handle_message(&mut self, txt: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 251) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 259) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 266) | fn translate_to_candlestick_commands(
function test_spot_command (line 283) | fn test_spot_command() {
function test_swap_command (line 296) | fn test_swap_command() {
FILE: crypto-ws-client/src/clients/bitget/bitget_spot.rs
constant WEBSOCKET_URL (line 16) | const WEBSOCKET_URL: &str = "wss://ws.bitget.com/spot/v1/stream";
type BitgetSpotWSClient (line 22) | pub struct BitgetSpotWSClient {
method new (line 28) | pub async fn new(tx: std::sync::mpsc::Sender<String>, url: Option<&str...
FILE: crypto-ws-client/src/clients/bitget/bitget_swap.rs
constant WEBSOCKET_URL (line 16) | const WEBSOCKET_URL: &str = "wss://ws.bitget.com/mix/v1/stream";
type BitgetSwapWSClient (line 22) | pub struct BitgetSwapWSClient {
method new (line 28) | pub async fn new(tx: std::sync::mpsc::Sender<String>, url: Option<&str...
FILE: crypto-ws-client/src/clients/bitget/mod.rs
constant EXCHANGE_NAME (line 8) | pub(super) const EXCHANGE_NAME: &str = "bitget";
FILE: crypto-ws-client/src/clients/bitget/utils.rs
constant EXCHANGE_NAME (line 17) | pub(crate) const EXCHANGE_NAME: &str = "bitget";
constant WS_FRAME_SIZE (line 22) | const WS_FRAME_SIZE: usize = 4096;
constant UPLINK_LIMIT (line 27) | pub(super) const UPLINK_LIMIT: (NonZeroU32, std::time::Duration) =
type BitgetMessageHandler (line 31) | pub(super) struct BitgetMessageHandler {}
type BitgetCommandTranslator (line 32) | pub(super) struct BitgetCommandTranslator<const MARKET_TYPE: char> {}
function topics_to_command (line 36) | fn topics_to_command(topics: &[(String, String)], subscribe: bool) -> St...
function to_candlestick_raw_channel (line 70) | fn to_candlestick_raw_channel(interval: usize) -> &'static str {
method handle_message (line 88) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 116) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 123) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 127) | fn translate_to_candlestick_commands(
function test_one_topic (line 148) | fn test_one_topic() {
function test_two_topics (line 161) | fn test_two_topics() {
function test_candlestick (line 179) | fn test_candlestick() {
FILE: crypto-ws-client/src/clients/bithumb.rs
constant EXCHANGE_NAME (line 20) | pub(super) const EXCHANGE_NAME: &str = "bithumb";
constant WEBSOCKET_URL (line 22) | const WEBSOCKET_URL: &str = "wss://global-api.bithumb.pro/message/realti...
type BithumbWSClient (line 30) | pub struct BithumbWSClient {
type BithumbMessageHandler (line 57) | struct BithumbMessageHandler {}
type BithumbCommandTranslator (line 58) | struct BithumbCommandTranslator {}
method topics_to_command (line 94) | fn topics_to_command(topics: &[(String, String)], subscribe: bool) -> ...
method handle_message (line 61) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 88) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 106) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 110) | fn translate_to_candlestick_commands(
function test_two_symbols (line 124) | fn test_two_symbols() {
function test_two_channels (line 142) | fn test_two_channels() {
FILE: crypto-ws-client/src/clients/bitmex.rs
constant EXCHANGE_NAME (line 19) | pub(super) const EXCHANGE_NAME: &str = "bitmex";
constant WEBSOCKET_URL (line 21) | const WEBSOCKET_URL: &str = "wss://www.bitmex.com/realtime";
constant MAX_CHANNELS_PER_COMMAND (line 24) | const MAX_CHANNELS_PER_COMMAND: usize = 20;
type BitmexWSClient (line 32) | pub struct BitmexWSClient {
type BitmexMessageHandler (line 57) | struct BitmexMessageHandler {}
type BitmexCommandTranslator (line 58) | struct BitmexCommandTranslator {}
method topics_to_command (line 61) | fn topics_to_command(topics: &[(String, String)], subscribe: bool) -> ...
method to_candlestick_raw_channel (line 74) | fn to_candlestick_raw_channel(interval: usize) -> String {
method handle_message (line 87) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 134) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 140) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 153) | fn translate_to_candlestick_commands(
function test_one_topic (line 174) | fn test_one_topic() {
function test_multiple_topics (line 184) | fn test_multiple_topics() {
FILE: crypto-ws-client/src/clients/bitstamp.rs
constant EXCHANGE_NAME (line 19) | pub(super) const EXCHANGE_NAME: &str = "bitstamp";
constant WEBSOCKET_URL (line 21) | const WEBSOCKET_URL: &str = "wss://ws.bitstamp.net";
type BitstampWSClient (line 29) | pub struct BitstampWSClient {
type BitstampMessageHandler (line 56) | struct BitstampMessageHandler {}
type BitstampCommandTranslator (line 57) | struct BitstampCommandTranslator {}
method handle_message (line 60) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 87) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 94) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 108) | fn translate_to_candlestick_commands(
function test_one_topic (line 122) | fn test_one_topic() {
function test_two_topics (line 135) | fn test_two_topics() {
FILE: crypto-ws-client/src/clients/bitz/bitz_spot.rs
constant WEBSOCKET_URL (line 25) | const WEBSOCKET_URL: &str = "wss://wsapi.bitz.plus/";
type BitzSpotWSClient (line 31) | pub struct BitzSpotWSClient {
type BitzMessageHandler (line 58) | struct BitzMessageHandler {}
type BitzCommandTranslator (line 59) | struct BitzCommandTranslator {}
method symbol_channels_to_command (line 104) | fn symbol_channels_to_command(pair: &str, channels: &[String], subscri...
method to_candlestick_command (line 114) | fn to_candlestick_command(symbol: &str, interval: usize, subscribe: bo...
method handle_message (line 62) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 97) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 141) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 161) | fn translate_to_candlestick_commands(
FILE: crypto-ws-client/src/clients/bitz/mod.rs
constant EXCHANGE_NAME (line 7) | pub(super) const EXCHANGE_NAME: &str = "bitz";
FILE: crypto-ws-client/src/clients/bybit/bybit_inverse.rs
constant WEBSOCKET_URL (line 13) | const WEBSOCKET_URL: &str = "wss://stream.bybit.com/realtime";
type BybitInverseWSClient (line 24) | pub struct BybitInverseWSClient {
type BybitInverseCommandTranslator (line 51) | struct BybitInverseCommandTranslator {}
method to_candlestick_raw_channel (line 56) | fn to_candlestick_raw_channel(interval: usize) -> String {
method translate_to_commands (line 79) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 83) | fn translate_to_candlestick_commands(
FILE: crypto-ws-client/src/clients/bybit/bybit_linear_swap.rs
constant WEBSOCKET_URL (line 13) | const WEBSOCKET_URL: &str = "wss://stream.bybit.com/realtime_public";
type BybitLinearSwapWSClient (line 19) | pub struct BybitLinearSwapWSClient {
type BybitLinearCommandTranslator (line 46) | struct BybitLinearCommandTranslator {}
method to_candlestick_raw_channel (line 50) | fn to_candlestick_raw_channel(interval: usize) -> String {
method translate_to_commands (line 73) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 77) | fn translate_to_candlestick_commands(
FILE: crypto-ws-client/src/clients/bybit/utils.rs
constant EXCHANGE_NAME (line 9) | pub(super) const EXCHANGE_NAME: &str = "bybit";
function topics_to_command (line 11) | pub(super) fn topics_to_command(topics: &[(String, String)], subscribe: ...
type BybitMessageHandler (line 23) | pub(super) struct BybitMessageHandler {}
method handle_message (line 26) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 51) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
function test_one_channel (line 62) | fn test_one_channel() {
function test_multiple_channels (line 69) | fn test_multiple_channels() {
FILE: crypto-ws-client/src/clients/coinbase_pro.rs
constant EXCHANGE_NAME (line 19) | pub(super) const EXCHANGE_NAME: &str = "coinbase_pro";
constant WEBSOCKET_URL (line 21) | const WEBSOCKET_URL: &str = "wss://ws-feed.exchange.coinbase.com";
type CoinbaseProWSClient (line 29) | pub struct CoinbaseProWSClient {
type CoinbaseProMessageHandler (line 55) | struct CoinbaseProMessageHandler {}
type CoinbaseProCommandTranslator (line 56) | struct CoinbaseProCommandTranslator {}
method handle_message (line 59) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 95) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 101) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 143) | fn translate_to_candlestick_commands(
function test_two_symbols (line 157) | fn test_two_symbols() {
function test_two_channels (line 175) | fn test_two_channels() {
FILE: crypto-ws-client/src/clients/common_traits.rs
type Trade (line 5) | pub(super) trait Trade {
method subscribe_trade (line 6) | async fn subscribe_trade(&self, symbols: &[String]);
type Ticker (line 11) | pub(super) trait Ticker {
method subscribe_ticker (line 12) | async fn subscribe_ticker(&self, symbols: &[String]);
type BBO (line 18) | pub(super) trait BBO {
method subscribe_bbo (line 19) | async fn subscribe_bbo(&self, symbols: &[String]);
type OrderBook (line 24) | pub(super) trait OrderBook {
method subscribe_orderbook (line 25) | async fn subscribe_orderbook(&self, symbols: &[String]);
type OrderBookTopK (line 29) | pub(super) trait OrderBookTopK {
method subscribe_orderbook_topk (line 31) | async fn subscribe_orderbook_topk(&self, symbols: &[String]);
type Level3OrderBook (line 36) | pub(super) trait Level3OrderBook {
method subscribe_l3_orderbook (line 41) | async fn subscribe_l3_orderbook(&self, symbols: &[String]);
type Candlestick (line 45) | pub(super) trait Candlestick {
method subscribe_candlestick (line 50) | async fn subscribe_candlestick(&self, symbol_interval_list: &[(String,...
FILE: crypto-ws-client/src/clients/deribit.rs
constant EXCHANGE_NAME (line 21) | pub(super) const EXCHANGE_NAME: &str = "deribit";
constant WEBSOCKET_URL (line 23) | const WEBSOCKET_URL: &str = "wss://www.deribit.com/ws/api/v2/";
constant WS_FRAME_SIZE (line 27) | const WS_FRAME_SIZE: usize = 32 * 1024;
type DeribitWSClient (line 37) | pub struct DeribitWSClient {
type DeribitMessageHandler (line 66) | struct DeribitMessageHandler {}
type DeribitCommandTranslator (line 67) | struct DeribitCommandTranslator {}
method topics_to_command (line 70) | fn topics_to_command(topics: &[(String, String)], subscribe: bool) -> ...
method to_candlestick_channel (line 79) | fn to_candlestick_channel(interval: usize) -> String {
method handle_message (line 100) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 140) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 146) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 156) | fn translate_to_candlestick_commands(
function test_one_channel (line 174) | fn test_one_channel() {
function test_two_channel (line 193) | fn test_two_channel() {
FILE: crypto-ws-client/src/clients/dydx/dydx_swap.rs
constant WEBSOCKET_URL (line 21) | const WEBSOCKET_URL: &str = "wss://api.dydx.exchange/v3/ws";
type DydxSwapWSClient (line 27) | pub struct DydxSwapWSClient {
type DydxMessageHandler (line 52) | struct DydxMessageHandler {}
type DydxCommandTranslator (line 53) | struct DydxCommandTranslator {}
method topic_to_command (line 96) | fn topic_to_command(topic: &(String, String), subscribe: bool) -> Stri...
method handle_message (line 56) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 87) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 107) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 111) | fn translate_to_candlestick_commands(
function test_one_topic (line 125) | fn test_one_topic() {
function test_two_topic (line 138) | fn test_two_topic() {
FILE: crypto-ws-client/src/clients/dydx/mod.rs
constant EXCHANGE_NAME (line 5) | const EXCHANGE_NAME: &str = "dydx";
FILE: crypto-ws-client/src/clients/ftx.rs
constant EXCHANGE_NAME (line 20) | pub(super) const EXCHANGE_NAME: &str = "ftx";
constant WEBSOCKET_URL (line 22) | const WEBSOCKET_URL: &str = "wss://ftx.com/ws/";
type FtxWSClient (line 30) | pub struct FtxWSClient {
type FtxMessageHandler (line 54) | struct FtxMessageHandler {}
type FtxCommandTranslator (line 55) | struct FtxCommandTranslator {}
method handle_message (line 58) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 88) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 96) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 110) | fn translate_to_candlestick_commands(
function test_one_topic (line 124) | fn test_one_topic() {
function test_two_topic (line 134) | fn test_two_topic() {
FILE: crypto-ws-client/src/clients/gate/gate_future.rs
constant INVERSE_FUTURE_WEBSOCKET_URL (line 12) | const INVERSE_FUTURE_WEBSOCKET_URL: &str = "wss://fx-ws.gateio.ws/v4/ws/...
constant LINEAR_FUTURE_WEBSOCKET_URL (line 13) | const LINEAR_FUTURE_WEBSOCKET_URL: &str = "wss://fx-ws.gateio.ws/v4/ws/d...
type GateInverseFutureWSClient (line 19) | pub struct GateInverseFutureWSClient {
type GateLinearFutureWSClient (line 28) | pub struct GateLinearFutureWSClient {
FILE: crypto-ws-client/src/clients/gate/gate_spot.rs
constant WEBSOCKET_URL (line 12) | const WEBSOCKET_URL: &str = "wss://api.gateio.ws/ws/v4/";
type GateSpotWSClient (line 18) | pub struct GateSpotWSClient {
FILE: crypto-ws-client/src/clients/gate/gate_swap.rs
constant INVERSE_SWAP_WEBSOCKET_URL (line 12) | const INVERSE_SWAP_WEBSOCKET_URL: &str = "wss://fx-ws.gateio.ws/v4/ws/btc";
constant LINEAR_SWAP_WEBSOCKET_URL (line 13) | const LINEAR_SWAP_WEBSOCKET_URL: &str = "wss://fx-ws.gateio.ws/v4/ws/usdt";
type GateInverseSwapWSClient (line 19) | pub struct GateInverseSwapWSClient {
type GateLinearSwapWSClient (line 28) | pub struct GateLinearSwapWSClient {
FILE: crypto-ws-client/src/clients/gate/utils.rs
constant EXCHANGE_NAME (line 12) | pub(super) const EXCHANGE_NAME: &str = "gate";
type GateMessageHandler (line 15) | pub(super) struct GateMessageHandler<const MARKET_TYPE: char> {}
type GateCommandTranslator (line 16) | pub(super) struct GateCommandTranslator<const MARKET_TYPE: char> {}
method handle_message (line 19) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 63) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
function channel_symbols_to_command (line 76) | fn channel_symbols_to_command(
function to_candlestick_command (line 128) | fn to_candlestick_command(symbol: &str, interval: usize, subscribe: bool...
method translate_to_commands (line 153) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 173) | fn translate_to_candlestick_commands(
function test_spot (line 190) | fn test_spot() {
function test_futures (line 240) | fn test_futures() {
FILE: crypto-ws-client/src/clients/huobi.rs
constant EXCHANGE_NAME (line 17) | pub(crate) const EXCHANGE_NAME: &str = "huobi";
constant SPOT_WEBSOCKET_URL (line 20) | const SPOT_WEBSOCKET_URL: &str = "wss://api.huobi.pro/ws";
constant FUTURES_WEBSOCKET_URL (line 25) | const FUTURES_WEBSOCKET_URL: &str = "wss://futures.huobi.com/ws";
constant COIN_SWAP_WEBSOCKET_URL (line 26) | const COIN_SWAP_WEBSOCKET_URL: &str = "wss://futures.huobi.com/swap-ws";
constant USDT_SWAP_WEBSOCKET_URL (line 27) | const USDT_SWAP_WEBSOCKET_URL: &str = "wss://futures.huobi.com/linear-sw...
constant OPTION_WEBSOCKET_URL (line 28) | const OPTION_WEBSOCKET_URL: &str = "wss://futures.huobi.com/option-ws";
type HuobiWSClient (line 31) | pub struct HuobiWSClient<const URL: char> {
type HuobiSpotWSClient (line 40) | pub type HuobiSpotWSClient = HuobiWSClient<'S'>;
type HuobiFutureWSClient (line 46) | pub type HuobiFutureWSClient = HuobiWSClient<'F'>;
type HuobiInverseSwapWSClient (line 54) | pub type HuobiInverseSwapWSClient = HuobiWSClient<'I'>;
type HuobiLinearSwapWSClient (line 62) | pub type HuobiLinearSwapWSClient = HuobiWSClient<'L'>;
type HuobiOptionWSClient (line 69) | pub type HuobiOptionWSClient = HuobiWSClient<'O'>;
function new (line 72) | pub async fn new(tx: std::sync::mpsc::Sender<String>, url: Option<&str>)...
method subscribe_trade (line 107) | async fn subscribe_trade(&self, symbols: &[String]) {
method subscribe_orderbook (line 115) | async fn subscribe_orderbook(&self, symbols: &[String]) {
method subscribe_orderbook_topk (line 131) | async fn subscribe_orderbook_topk(&self, symbols: &[String]) {
method subscribe_l3_orderbook (line 140) | async fn subscribe_l3_orderbook(&self, _symbols: &[String]) {
method subscribe_ticker (line 144) | async fn subscribe_ticker(&self, symbols: &[String]) {
method subscribe_bbo (line 152) | async fn subscribe_bbo(&self, symbols: &[String]) {
method subscribe_candlestick (line 160) | async fn subscribe_candlestick(&self, symbol_interval_list: &[(String, u...
method subscribe (line 166) | async fn subscribe(&self, topics: &[(String, String)]) {
method unsubscribe (line 171) | async fn unsubscribe(&self, topics: &[(String, String)]) {
method send (line 176) | async fn send(&self, commands: &[String]) {
method run (line 180) | async fn run(&self) {
method close (line 184) | async fn close(&self) {
type HuobiMessageHandler (line 189) | struct HuobiMessageHandler {}
type HuobiCommandTranslator (line 190) | struct HuobiCommandTranslator {}
method topic_to_command (line 193) | fn topic_to_command(channel: &str, symbol: &str, subscribe: bool) -> S...
method to_candlestick_raw_channel (line 203) | fn to_candlestick_raw_channel(interval: usize) -> String {
method handle_message (line 221) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 284) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 296) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 305) | fn translate_to_candlestick_commands(
function test_one_topic (line 326) | fn test_one_topic() {
function test_two_topics (line 336) | fn test_two_topics() {
FILE: crypto-ws-client/src/clients/kraken/kraken_futures.rs
constant WEBSOCKET_URL (line 21) | const WEBSOCKET_URL: &str = "wss://futures.kraken.com/ws/v1";
type KrakenFuturesWSClient (line 28) | pub struct KrakenFuturesWSClient {
type KrakenMessageHandler (line 55) | struct KrakenMessageHandler {}
type KrakenCommandTranslator (line 56) | struct KrakenCommandTranslator {}
method channel_symbols_to_command (line 59) | fn channel_symbols_to_command(channel: &str, symbols: &[String], subsc...
method handle_message (line 70) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 101) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 110) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 131) | fn translate_to_candlestick_commands(
function test_one_symbol (line 145) | fn test_one_symbol() {
function test_two_symbols (line 159) | fn test_two_symbols() {
FILE: crypto-ws-client/src/clients/kraken/kraken_spot.rs
constant WEBSOCKET_URL (line 21) | const WEBSOCKET_URL: &str = "wss://ws.kraken.com";
type KrakenSpotWSClient (line 28) | pub struct KrakenSpotWSClient {
type KrakenMessageHandler (line 55) | struct KrakenMessageHandler {}
type KrakenCommandTranslator (line 56) | struct KrakenCommandTranslator {}
method name_symbols_to_command (line 133) | fn name_symbols_to_command(name: &str, symbols: &[String], subscribe: ...
method convert_symbol_interval_list (line 151) | fn convert_symbol_interval_list(
method handle_message (line 59) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 125) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 168) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 188) | fn translate_to_candlestick_commands(
function test_one_symbol (line 233) | fn test_one_symbol() {
function test_two_symbols (line 246) | fn test_two_symbols() {
FILE: crypto-ws-client/src/clients/kraken/mod.rs
constant EXCHANGE_NAME (line 4) | const EXCHANGE_NAME: &str = "kraken";
FILE: crypto-ws-client/src/clients/kucoin/kucoin_spot.rs
type KuCoinSpotWSClient (line 16) | pub struct KuCoinSpotWSClient {
method new (line 28) | pub async fn new(tx: Sender<String>, url: Option<&str>) -> Self {
type KucoinCommandTranslator (line 66) | struct KucoinCommandTranslator {}
method to_candlestick_channel (line 69) | fn to_candlestick_channel(symbol: &str, interval: usize) -> String {
method translate_to_commands (line 93) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 97) | fn translate_to_candlestick_commands(
function test_one_channel (line 117) | fn test_one_channel() {
function test_two_channels (line 144) | fn test_two_channels() {
function test_candlestick (line 186) | fn test_candlestick() {
FILE: crypto-ws-client/src/clients/kucoin/kucoin_swap.rs
type KuCoinSwapWSClient (line 16) | pub struct KuCoinSwapWSClient {
method new (line 28) | pub async fn new(tx: Sender<String>, url: Option<&str>) -> Self {
type KucoinCommandTranslator (line 68) | struct KucoinCommandTranslator {}
method to_candlestick_channel (line 71) | fn to_candlestick_channel(symbol: &str, interval: usize) -> String {
method translate_to_commands (line 84) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 88) | fn translate_to_candlestick_commands(
function test_one_channel (line 112) | fn test_one_channel() {
function test_two_channels (line 141) | fn test_two_channels() {
function test_candlestick (line 183) | fn test_candlestick() {
FILE: crypto-ws-client/src/clients/kucoin/utils.rs
constant EXCHANGE_NAME (line 14) | pub(super) const EXCHANGE_NAME: &str = "kucoin";
constant MAX_TOPICS_PER_COMMAND (line 18) | const MAX_TOPICS_PER_COMMAND: usize = 100;
constant UPLINK_LIMIT (line 21) | pub(super) const UPLINK_LIMIT: (NonZeroU32, std::time::Duration) =
type WebsocketToken (line 24) | pub(super) struct WebsocketToken {
function http_post (line 29) | async fn http_post(url: &str) -> Result<String> {
function fetch_ws_token (line 47) | pub(super) async fn fetch_ws_token() -> WebsocketToken {
function channel_symbols_to_command (line 65) | fn channel_symbols_to_command(channel: &str, symbols: &[String], subscri...
function topics_to_commands (line 74) | pub(super) fn topics_to_commands(topics: &[(String, String)], subscribe:...
type KucoinMessageHandler (line 104) | pub(super) struct KucoinMessageHandler {}
method handle_message (line 107) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 130) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
function fetch_ws_token (line 144) | async fn fetch_ws_token() {
function test_topics_to_commands (line 150) | fn test_topics_to_commands() {
FILE: crypto-ws-client/src/clients/mexc/mexc_spot.rs
constant SPOT_WEBSOCKET_URL (line 20) | pub(super) const SPOT_WEBSOCKET_URL: &str = "wss://wbs.mexc.com/raw/ws";
type MexcSpotWSClient (line 26) | pub struct MexcSpotWSClient {
type MexcMessageHandler (line 53) | struct MexcMessageHandler {}
type MexcCommandTranslator (line 54) | struct MexcCommandTranslator {}
method topic_to_command (line 95) | fn topic_to_command(channel: &str, symbol: &str, subscribe: bool) -> S...
method interval_to_string (line 113) | fn interval_to_string(interval: usize) -> String {
method handle_message (line 57) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 89) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 134) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 143) | fn translate_to_candlestick_commands(
function test_one_topic (line 167) | fn test_one_topic() {
function test_two_topic (line 177) | fn test_two_topic() {
function test_candlestick (line 193) | fn test_candlestick() {
FILE: crypto-ws-client/src/clients/mexc/mexc_swap.rs
constant SWAP_WEBSOCKET_URL (line 21) | pub(super) const SWAP_WEBSOCKET_URL: &str = "wss://contract.mexc.com/ws";
type MexcSwapWSClient (line 27) | pub struct MexcSwapWSClient {
type MexcMessageHandler (line 55) | struct MexcMessageHandler {}
type MexcCommandTranslator (line 56) | struct MexcCommandTranslator {}
method topic_to_command (line 91) | fn topic_to_command(channel: &str, symbol: &str, subscribe: bool) -> S...
method interval_to_string (line 100) | fn interval_to_string(interval: usize) -> String {
method handle_message (line 59) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 84) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 121) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 130) | fn translate_to_candlestick_commands(
function test_one_topic (line 154) | fn test_one_topic() {
function test_two_topic (line 164) | fn test_two_topic() {
function test_candlestick (line 180) | fn test_candlestick() {
FILE: crypto-ws-client/src/clients/mexc/mod.rs
constant EXCHANGE_NAME (line 4) | pub(super) const EXCHANGE_NAME: &str = "mexc";
FILE: crypto-ws-client/src/clients/okx.rs
constant EXCHANGE_NAME (line 25) | pub(crate) const EXCHANGE_NAME: &str = "okx";
constant WEBSOCKET_URL (line 27) | const WEBSOCKET_URL: &str = "wss://ws.okx.com:8443/ws/v5/public";
constant WS_FRAME_SIZE (line 31) | const WS_FRAME_SIZE: usize = 4096;
constant UPLINK_LIMIT (line 35) | const UPLINK_LIMIT: (NonZeroU32, std::time::Duration) =
type OkxWSClient (line 48) | pub struct OkxWSClient {
method new (line 54) | pub async fn new(tx: std::sync::mpsc::Sender<String>, url: Option<&str...
type OkxMessageHandler (line 86) | struct OkxMessageHandler {}
type OkxCommandTranslator (line 87) | struct OkxCommandTranslator {}
method topics_to_command (line 90) | fn topics_to_command(chunk: &[(String, String)], subscribe: bool) -> S...
method to_candlestick_raw_channel (line 109) | fn to_candlestick_raw_channel(interval: usize) -> &'static str {
method handle_message (line 133) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 171) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 178) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 182) | fn translate_to_candlestick_commands(
function test_one_topic (line 203) | fn test_one_topic() {
function test_two_topics (line 216) | fn test_two_topics() {
FILE: crypto-ws-client/src/clients/zb/mod.rs
constant EXCHANGE_NAME (line 7) | const EXCHANGE_NAME: &str = "zb";
FILE: crypto-ws-client/src/clients/zb/zb_spot.rs
constant WEBSOCKET_URL (line 23) | const WEBSOCKET_URL: &str = "wss://api.zb.com/websocket";
type ZbSpotWSClient (line 29) | pub struct ZbSpotWSClient {
type ZbMessageHandler (line 56) | struct ZbMessageHandler {}
type ZbCommandTranslator (line 57) | struct ZbCommandTranslator {}
method to_candlestick_raw_channel (line 87) | fn to_candlestick_raw_channel(&self, symbol: &str, interval: usize) ->...
method handle_message (line 60) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 81) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 111) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 125) | fn translate_to_candlestick_commands(
function test_one_topic (line 148) | async fn test_one_topic() {
function test_two_topic (line 158) | async fn test_two_topic() {
function test_candlestick (line 174) | async fn test_candlestick() {
FILE: crypto-ws-client/src/clients/zb/zb_swap.rs
constant WEBSOCKET_URL (line 23) | const WEBSOCKET_URL: &str = "wss://fapi.zb.com/ws/public/v1";
constant UPLINK_LIMIT (line 29) | const UPLINK_LIMIT: (NonZeroU32, std::time::Duration) =
type ZbSwapWSClient (line 36) | pub struct ZbSwapWSClient {
method new (line 42) | pub async fn new(tx: std::sync::mpsc::Sender<String>, url: Option<&str...
type ZbMessageHandler (line 76) | struct ZbMessageHandler {}
type ZbCommandTranslator (line 77) | struct ZbCommandTranslator {}
method to_candlestick_raw_channel (line 104) | fn to_candlestick_raw_channel(&self, symbol: &str, interval: usize) ->...
method handle_message (line 80) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 97) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 121) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 143) | fn translate_to_candlestick_commands(
function test_one_topic (line 167) | async fn test_one_topic() {
function test_two_topic (line 180) | async fn test_two_topic() {
function test_candlestick (line 202) | async fn test_candlestick() {
FILE: crypto-ws-client/src/clients/zbg/mod.rs
constant EXCHANGE_NAME (line 8) | const EXCHANGE_NAME: &str = "zbg";
FILE: crypto-ws-client/src/clients/zbg/utils.rs
function http_get (line 6) | async fn http_get(url: &str) -> Result<String> {
function fetch_symbol_id_map_spot (line 24) | pub(super) async fn fetch_symbol_id_map_spot() -> HashMap<String, i64> {
function fetch_symbol_contract_id_map_swap (line 60) | pub(super) async fn fetch_symbol_contract_id_map_swap() -> HashMap<Strin...
FILE: crypto-ws-client/src/clients/zbg/zbg_spot.rs
constant WEBSOCKET_URL (line 19) | const WEBSOCKET_URL: &str = "wss://kline.zbg.com/websocket";
type ZbgSpotWSClient (line 25) | pub struct ZbgSpotWSClient {
type ZbgMessageHandler (line 52) | struct ZbgMessageHandler {}
type ZbgCommandTranslator (line 53) | struct ZbgCommandTranslator {
method new (line 68) | async fn new() -> Self {
method to_raw_channel (line 73) | fn to_raw_channel(&self, channel: &str, symbol: &str) -> String {
method to_candlestick_raw_channel (line 85) | fn to_candlestick_raw_channel(&self, symbol: &str, interval: usize) ->...
method handle_message (line 58) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 62) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 108) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 121) | fn translate_to_candlestick_commands(
function test_one_topic (line 144) | async fn test_one_topic() {
function test_two_topic (line 154) | async fn test_two_topic() {
function test_candlestick (line 170) | async fn test_candlestick() {
FILE: crypto-ws-client/src/clients/zbg/zbg_swap.rs
constant WEBSOCKET_URL (line 21) | const WEBSOCKET_URL: &str = "wss://kline.zbg.com/exchange/v1/futurews";
type ZbgSwapWSClient (line 28) | pub struct ZbgSwapWSClient {
type ZbgMessageHandler (line 55) | struct ZbgMessageHandler {}
type ZbgCommandTranslator (line 56) | struct ZbgCommandTranslator {
method new (line 79) | async fn new() -> Self {
method to_raw_channel (line 84) | fn to_raw_channel(&self, channel: &str, symbol: &str) -> String {
method to_candlestick_raw_channel (line 92) | fn to_candlestick_raw_channel(&self, pair: &str, interval: usize) -> S...
method handle_message (line 61) | fn handle_message(&mut self, msg: &str) -> MiscMessage {
method get_ping_msg_and_interval (line 73) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)> {
method translate_to_commands (line 111) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, Stri...
method translate_to_candlestick_commands (line 124) | fn translate_to_candlestick_commands(
function test_one_topic (line 147) | async fn test_one_topic() {
function test_two_topic (line 157) | async fn test_two_topic() {
function test_candlestick (line 173) | async fn test_candlestick() {
FILE: crypto-ws-client/src/common/command_translator.rs
type CommandTranslator (line 7) | pub(crate) trait CommandTranslator {
method translate_to_commands (line 8) | fn translate_to_commands(&self, subscribe: bool, topics: &[(String, St...
method translate_to_candlestick_commands (line 9) | fn translate_to_candlestick_commands(
FILE: crypto-ws-client/src/common/connect_async.rs
function connect_async (line 24) | pub async fn connect_async(
function connect_async_internal (line 59) | async fn connect_async_internal<S: AsyncRead + AsyncWrite + Unpin + Send...
FILE: crypto-ws-client/src/common/message_handler.rs
type MiscMessage (line 4) | pub(crate) enum MiscMessage {
type MessageHandler (line 14) | pub(crate) trait MessageHandler {
method handle_message (line 17) | fn handle_message(&mut self, msg: &str) -> MiscMessage;
method get_ping_msg_and_interval (line 21) | fn get_ping_msg_and_interval(&self) -> Option<(Message, u64)>;
FILE: crypto-ws-client/src/common/utils.rs
function ensure_frame_size (line 3) | pub(crate) fn ensure_frame_size(
function topic_to_raw_channel (line 40) | pub(crate) fn topic_to_raw_channel(topic: &(String, String)) -> String {
FILE: crypto-ws-client/src/common/ws_client.rs
type WSClient (line 5) | pub trait WSClient {
method subscribe_trade (line 16) | async fn subscribe_trade(&self, symbols: &[String]);
method subscribe_bbo (line 30) | async fn subscribe_bbo(&self, symbols: &[String]);
method subscribe_orderbook (line 52) | async fn subscribe_orderbook(&self, symbols: &[String]);
method subscribe_orderbook_topk (line 71) | async fn subscribe_orderbook_topk(&self, symbols: &[String]);
method subscribe_l3_orderbook (line 80) | async fn subscribe_l3_orderbook(&self, symbols: &[String]);
method subscribe_ticker (line 89) | async fn subscribe_ticker(&self, symbols: &[String]);
method subscribe_candlestick (line 100) | async fn subscribe_candlestick(&self, symbol_interval_list: &[(String,...
method subscribe (line 124) | async fn subscribe(&self, topics: &[(String, String)]);
method unsubscribe (line 129) | async fn unsubscribe(&self, topics: &[(String, String)]);
method send (line 134) | async fn send(&self, commands: &[String]);
method run (line 137) | async fn run(&self);
method close (line 140) | async fn close(&self);
FILE: crypto-ws-client/src/common/ws_client_internal.rs
type WSClientInternal (line 20) | pub(crate) struct WSClientInternal<H: MessageHandler> {
function connect (line 36) | pub async fn connect(
function send (line 82) | pub async fn send(&self, commands: &[String]) {
function run (line 91) | pub async fn run(&self) {
function close (line 217) | pub async fn close(&self) {
FILE: crypto-ws-client/tests/binance.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_all_bbo (line 22) | async fn subscribe_all_bbo() {
function subscribe_raw_json (line 31) | async fn subscribe_raw_json() {
function subscribe_trade (line 41) | async fn subscribe_trade() {
function subscribe_ticker (line 50) | async fn subscribe_ticker() {
function subscribe_tickers_all (line 59) | async fn subscribe_tickers_all() {
function subscribe_bbo (line 68) | async fn subscribe_bbo() {
function subscribe_orderbook (line 77) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 86) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 95) | async fn subscribe_candlestick() {
function subscribe (line 112) | async fn subscribe() {
function subscribe_all_bbo (line 125) | async fn subscribe_all_bbo() {
function subscribe_trade (line 134) | async fn subscribe_trade() {
function subscribe_ticker (line 147) | async fn subscribe_ticker() {
function subscribe_tickers_all (line 160) | async fn subscribe_tickers_all() {
function subscribe_bbo (line 169) | async fn subscribe_bbo() {
function subscribe_orderbook (line 182) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 195) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 208) | async fn subscribe_candlestick() {
function subscribe (line 233) | async fn subscribe() {
function subscribe_all_bbo (line 245) | async fn subscribe_all_bbo() {
function subscribe_trade (line 254) | async fn subscribe_trade() {
function subscribe_ticker (line 263) | async fn subscribe_ticker() {
function subscribe_tickers_all (line 272) | async fn subscribe_tickers_all() {
function subscribe_bbo (line 281) | async fn subscribe_bbo() {
function subscribe_orderbook (line 290) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 299) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 308) | async fn subscribe_candlestick() {
function subscribe (line 325) | async fn subscribe() {
function subscribe_all_bbo (line 334) | async fn subscribe_all_bbo() {
function subscribe_trade (line 343) | async fn subscribe_trade() {
function subscribe_ticker (line 352) | async fn subscribe_ticker() {
function subscribe_tickers_all (line 361) | async fn subscribe_tickers_all() {
function subscribe_bbo (line 370) | async fn subscribe_bbo() {
function subscribe_orderbook (line 379) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 388) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 397) | async fn subscribe_candlestick() {
function subscribe_funding_rate (line 409) | async fn subscribe_funding_rate() {
function subscribe_funding_rate_all (line 418) | async fn subscribe_funding_rate_all() {
function subscribe (line 432) | async fn subscribe() {
function subscribe_all_bbo (line 441) | async fn subscribe_all_bbo() {
function subscribe_trade (line 450) | async fn subscribe_trade() {
function subscribe_ticker (line 459) | async fn subscribe_ticker() {
function subscribe_tickers_all (line 468) | async fn subscribe_tickers_all() {
function subscribe_bbo (line 477) | async fn subscribe_bbo() {
function subscribe_orderbook (line 486) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 495) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 504) | async fn subscribe_candlestick() {
function subscribe_funding_rate (line 516) | async fn subscribe_funding_rate() {
function subscribe_funding_rate_all (line 525) | async fn subscribe_funding_rate_all() {
FILE: crypto-ws-client/tests/binance_option.rs
function subscribe (line 8) | async fn subscribe() {
function subscribe_trade (line 22) | async fn subscribe_trade() {
function subscribe_ticker (line 32) | async fn subscribe_ticker() {
function subscribe_ticker_all (line 42) | async fn subscribe_ticker_all() {
function subscribe_orderbook (line 52) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 62) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 72) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/bitfinex.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_illegal_symbol (line 22) | fn subscribe_illegal_symbol() {
function subscribe_trade (line 31) | async fn subscribe_trade() {
function subscribe_ticker (line 40) | async fn subscribe_ticker() {
function subscribe_orderbook (line 45) | async fn subscribe_orderbook() {
function subscribe_l3_orderbook (line 50) | async fn subscribe_l3_orderbook() {
function subscribe_candlestick (line 55) | async fn subscribe_candlestick() {
function subscribe (line 66) | async fn subscribe() {
function subscribe_trade (line 75) | async fn subscribe_trade() {
function subscribe_ticker (line 84) | async fn subscribe_ticker() {
function subscribe_orderbook (line 89) | async fn subscribe_orderbook() {
function subscribe_l3_orderbook (line 94) | async fn subscribe_l3_orderbook() {
function subscribe_candlestick (line 103) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/bitget.rs
function subscribe_trade (line 9) | async fn subscribe_trade() {
function subscribe_orderbook_topk (line 14) | async fn subscribe_orderbook_topk() {
function subscribe_orderbook (line 19) | async fn subscribe_orderbook() {
function subscribe_ticker (line 24) | async fn subscribe_ticker() {
function subscribe_candlestick (line 29) | async fn subscribe_candlestick() {
function subscribe (line 40) | async fn subscribe() {
function subscribe_raw_json (line 49) | async fn subscribe_raw_json() {
function subscribe_trade (line 58) | async fn subscribe_trade() {
function subscribe_orderbook_topk (line 63) | async fn subscribe_orderbook_topk() {
function subscribe_orderbook (line 68) | async fn subscribe_orderbook() {
function subscribe_ticker (line 73) | async fn subscribe_ticker() {
function subscribe_candlestick (line 78) | async fn subscribe_candlestick() {
function subscribe_funding_rate (line 85) | async fn subscribe_funding_rate() {
function subscribe_trade (line 99) | async fn subscribe_trade() {
function subscribe_orderbook_topk (line 104) | async fn subscribe_orderbook_topk() {
function subscribe_orderbook (line 109) | async fn subscribe_orderbook() {
function subscribe_ticker (line 114) | async fn subscribe_ticker() {
function subscribe_candlestick (line 119) | async fn subscribe_candlestick() {
function subscribe_funding_rate (line 126) | async fn subscribe_funding_rate() {
FILE: crypto-ws-client/tests/bithumb.rs
function subscribe (line 8) | async fn subscribe() {
function subscribe_illegal_symbol (line 21) | fn subscribe_illegal_symbol() {
function subscribe_raw_json (line 26) | async fn subscribe_raw_json() {
function subscribe_trade (line 35) | async fn subscribe_trade() {
function subscribe_orderbook (line 44) | async fn subscribe_orderbook() {
function subscribe_ticker (line 54) | async fn subscribe_ticker() {
FILE: crypto-ws-client/tests/bitmex.rs
function bitmex_instrument (line 7) | async fn bitmex_instrument() {
function subscribe (line 20) | async fn subscribe() {
function subscribe_raw_json (line 32) | async fn subscribe_raw_json() {
function subscribe_trade (line 41) | async fn subscribe_trade() {
function subscribe_bbo (line 46) | async fn subscribe_bbo() {
function subscribe_orderbook (line 51) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 56) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 61) | async fn subscribe_candlestick() {
function subscribe_funding_rate (line 68) | fn subscribe_funding_rate() {
function subscribe_funding_rate_all (line 73) | async fn subscribe_funding_rate_all() {
function subscribe_instrument (line 82) | async fn subscribe_instrument() {
function subscribe (line 96) | async fn subscribe() {
function subscribe_trade (line 108) | async fn subscribe_trade() {
function subscribe_bbo (line 117) | async fn subscribe_bbo() {
function subscribe_orderbook (line 126) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 135) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 144) | async fn subscribe_candlestick() {
function subscribe_trade (line 161) | async fn subscribe_trade() {
function subscribe_bbo (line 166) | async fn subscribe_bbo() {
function subscribe_orderbook (line 171) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 176) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 181) | async fn subscribe_candlestick() {
function subscribe_funding_rate (line 188) | fn subscribe_funding_rate() {
function subscribe_trade (line 198) | async fn subscribe_trade() {
function subscribe_bbo (line 207) | async fn subscribe_bbo() {
function subscribe_orderbook (line 212) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 217) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 222) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/bitstamp.rs
function subscribe (line 7) | async fn subscribe() {
function subscribe_raw_json (line 19) | async fn subscribe_raw_json() {
function subscribe_trade (line 31) | async fn subscribe_trade() {
function subscribe_orderbook (line 40) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 49) | async fn subscribe_orderbook_topk() {
function subscribe_l3_orderbook (line 58) | async fn subscribe_l3_orderbook() {
FILE: crypto-ws-client/tests/bitz.rs
function subscribe (line 11) | async fn subscribe() {
function subscribe_raw_json (line 25) | async fn subscribe_raw_json() {
function subscribe_trade (line 38) | async fn subscribe_trade() {
function subscribe_orderbook (line 44) | async fn subscribe_orderbook() {
function subscribe_ticker (line 50) | async fn subscribe_ticker() {
function subscribe_candlestick (line 56) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/bybit.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_raw_json (line 18) | async fn subscribe_raw_json() {
function subscribe_trade (line 27) | async fn subscribe_trade() {
function subscribe_orderbook (line 32) | async fn subscribe_orderbook() {
function subscribe_ticker (line 37) | async fn subscribe_ticker() {
function subscribe_candlestick (line 42) | async fn subscribe_candlestick() {
function subscribe (line 56) | async fn subscribe() {
function subscribe_raw_json (line 65) | async fn subscribe_raw_json() {
function subscribe_trade (line 74) | async fn subscribe_trade() {
function subscribe_orderbook (line 79) | async fn subscribe_orderbook() {
function subscribe_ticker (line 84) | async fn subscribe_ticker() {
function subscribe_candlestick (line 89) | async fn subscribe_candlestick() {
function subscribe_trade (line 100) | async fn subscribe_trade() {
function subscribe_orderbook (line 105) | async fn subscribe_orderbook() {
function subscribe_ticker (line 110) | async fn subscribe_ticker() {
function subscribe_candlestick (line 115) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/coinbase_pro.rs
function subscribe (line 7) | async fn subscribe() {
function subscribe_illegal_symbol (line 20) | async fn subscribe_illegal_symbol() {
function subscribe_raw_json (line 29) | async fn subscribe_raw_json() {
function subscribe_trade (line 55) | async fn subscribe_trade() {
function subscribe_ticker (line 64) | async fn subscribe_ticker() {
function subscribe_orderbook (line 73) | async fn subscribe_orderbook() {
function subscribe_l3_orderbook (line 78) | async fn subscribe_l3_orderbook() {
FILE: crypto-ws-client/tests/deribit.rs
function deribit_all_trades (line 7) | async fn deribit_all_trades() {
function subscribe (line 25) | async fn subscribe() {
function subscribe_trade (line 35) | async fn subscribe_trade() {
function subscribe_ticker (line 44) | async fn subscribe_ticker() {
function subscribe_orderbook (line 49) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 54) | async fn subscribe_orderbook_topk() {
function subscribe_bbo (line 59) | async fn subscribe_bbo() {
function subscribe_candlestick (line 64) | async fn subscribe_candlestick() {
function subscribe (line 75) | async fn subscribe() {
function subscribe_trade (line 84) | async fn subscribe_trade() {
function subscribe_ticker (line 89) | async fn subscribe_ticker() {
function subscribe_orderbook (line 94) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 99) | async fn subscribe_orderbook_topk() {
function subscribe_bbo (line 104) | async fn subscribe_bbo() {
function subscribe_candlestick (line 109) | async fn subscribe_candlestick() {
constant SYMBOLS (line 119) | const SYMBOLS: &[&str] = &[
function subscribe (line 128) | async fn subscribe() {
function subscribe_trade (line 138) | async fn subscribe_trade() {
function subscribe_ticker (line 147) | async fn subscribe_ticker() {
function subscribe_orderbook (line 157) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 167) | async fn subscribe_orderbook_topk() {
function subscribe_bbo (line 176) | async fn subscribe_bbo() {
function subscribe_candlestick (line 185) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/dydx.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_trade (line 21) | async fn subscribe_trade() {
function subscribe_orderbook (line 30) | async fn subscribe_orderbook() {
FILE: crypto-ws-client/tests/ftx.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_raw_json (line 14) | async fn subscribe_raw_json() {
function subscribe_trade (line 23) | async fn subscribe_trade() {
function subscribe_bbo (line 28) | async fn subscribe_bbo() {
function subscribe_orderbook (line 33) | async fn subscribe_orderbook() {
function subscribe_trade (line 43) | async fn subscribe_trade() {
function subscribe_bbo (line 48) | async fn subscribe_bbo() {
function subscribe_orderbook (line 53) | async fn subscribe_orderbook() {
function subscribe_trade (line 67) | async fn subscribe_trade() {
function subscribe_bbo (line 76) | async fn subscribe_bbo() {
function subscribe_orderbook (line 85) | async fn subscribe_orderbook() {
function subscribe_trade (line 96) | fn subscribe_trade() {
function subscribe_bbo (line 101) | async fn subscribe_bbo() {
function subscribe_orderbook (line 106) | async fn subscribe_orderbook() {
function subscribe_trade (line 117) | fn subscribe_trade() {
function subscribe_bbo (line 122) | async fn subscribe_bbo() {
function subscribe_orderbook (line 127) | async fn subscribe_orderbook() {
FILE: crypto-ws-client/tests/gate.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_raw_json (line 21) | async fn subscribe_raw_json() {
function subscribe_trade (line 30) | async fn subscribe_trade() {
function subscribe_orderbook (line 35) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 40) | async fn subscribe_orderbook_topk() {
function subscribe_bbo (line 45) | async fn subscribe_bbo() {
function subscribe_ticker (line 50) | async fn subscribe_ticker() {
function subscribe_candlestick (line 56) | async fn subscribe_candlestick() {
function subscribe (line 68) | async fn subscribe() {
function subscribe_raw_json (line 83) | async fn subscribe_raw_json() {
function subscribe_trade (line 94) | async fn subscribe_trade() {
function subscribe_orderbook (line 103) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 108) | async fn subscribe_orderbook_topk() {
function subscribe_bbo (line 113) | async fn subscribe_bbo() {
function subscribe_ticker (line 118) | async fn subscribe_ticker() {
function subscribe_candlestick (line 124) | async fn subscribe_candlestick() {
function subscribe_trade (line 138) | async fn subscribe_trade() {
function subscribe_orderbook (line 143) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 148) | async fn subscribe_orderbook_topk() {
function subscribe_bbo (line 153) | async fn subscribe_bbo() {
function subscribe_ticker (line 158) | async fn subscribe_ticker() {
function subscribe_candlestick (line 164) | async fn subscribe_candlestick() {
function subscribe_trade (line 179) | fn subscribe_trade() {
function subscribe_orderbook (line 188) | async fn subscribe_orderbook() {
function subscribe_ticker (line 198) | async fn subscribe_ticker() {
function subscribe_candlestick (line 208) | async fn subscribe_candlestick() {
function subscribe_trade (line 226) | fn subscribe_trade() {
function subscribe_orderbook (line 236) | fn subscribe_orderbook() {
function subscribe_ticker (line 245) | async fn subscribe_ticker() {
function subscribe_candlestick (line 255) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/huobi.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_raw_json (line 18) | async fn subscribe_raw_json() {
function subscribe_trade (line 27) | async fn subscribe_trade() {
function subscribe_ticker (line 32) | async fn subscribe_ticker() {
function subscribe_bbo (line 37) | async fn subscribe_bbo() {
function subscribe_orderbook (line 42) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 56) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 61) | async fn subscribe_candlestick() {
function subscribe (line 72) | async fn subscribe() {
function subscribe_trade (line 81) | async fn subscribe_trade() {
function subscribe_ticker (line 86) | async fn subscribe_ticker() {
function subscribe_bbo (line 91) | async fn subscribe_bbo() {
function subscribe_orderbook (line 96) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 101) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 106) | async fn subscribe_candlestick() {
function subscribe (line 117) | async fn subscribe() {
function subscribe_trade (line 126) | async fn subscribe_trade() {
function subscribe_ticker (line 131) | async fn subscribe_ticker() {
function subscribe_bbo (line 136) | async fn subscribe_bbo() {
function subscribe_orderbook (line 141) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 146) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 155) | async fn subscribe_candlestick() {
function subscribe_funding_rate (line 164) | async fn subscribe_funding_rate() {
function subscribe_funding_rate_all (line 184) | async fn subscribe_funding_rate_all() {
function subscribe (line 207) | async fn subscribe() {
function subscribe_trade (line 216) | async fn subscribe_trade() {
function subscribe_ticker (line 221) | async fn subscribe_ticker() {
function subscribe_bbo (line 226) | async fn subscribe_bbo() {
function subscribe_orderbook (line 231) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 236) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 245) | async fn subscribe_candlestick() {
function subscribe_funding_rate (line 254) | async fn subscribe_funding_rate() {
function subscribe_funding_rate_all (line 272) | async fn subscribe_funding_rate_all() {
function subscribe_overview (line 288) | async fn subscribe_overview() {
function subscribe (line 303) | fn subscribe() {
function subscribe_trade (line 313) | fn subscribe_trade() {
function subscribe_ticker (line 323) | fn subscribe_ticker() {
function subscribe_bbo (line 333) | fn subscribe_bbo() {
function subscribe_orderbook (line 343) | fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 353) | fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 363) | fn subscribe_candlestick() {
function subscribe_overview (line 376) | fn subscribe_overview() {
FILE: crypto-ws-client/tests/kraken.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_raw_json (line 23) | async fn subscribe_raw_json() {
function subscribe_trade (line 33) | async fn subscribe_trade() {
function subscribe_ticker (line 42) | async fn subscribe_ticker() {
function subscribe_bbo (line 51) | async fn subscribe_bbo() {
function subscribe_orderbook (line 60) | async fn subscribe_orderbook() {
function subscribe_candlestick (line 69) | async fn subscribe_candlestick() {
function subscribe_raw_json (line 87) | async fn subscribe_raw_json() {
function subscribe_trade (line 96) | async fn subscribe_trade() {
function subscribe_ticker (line 101) | async fn subscribe_ticker() {
function subscribe_orderbook (line 106) | async fn subscribe_orderbook() {
function subscribe_raw_json (line 116) | async fn subscribe_raw_json() {
function subscribe_trade (line 126) | async fn subscribe_trade() {
function subscribe_ticker (line 131) | async fn subscribe_ticker() {
function subscribe_orderbook (line 136) | async fn subscribe_orderbook() {
FILE: crypto-ws-client/tests/kucoin.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_all_bbo (line 18) | async fn subscribe_all_bbo() {
function subscribe_raw_json (line 27) | async fn subscribe_raw_json() {
function subscribe_trade (line 36) | async fn subscribe_trade() {
function subscribe_bbo (line 45) | async fn subscribe_bbo() {
function subscribe_orderbook (line 50) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 55) | async fn subscribe_orderbook_topk() {
function subscribe_ticker (line 60) | async fn subscribe_ticker() {
function subscribe_candlestick (line 65) | async fn subscribe_candlestick() {
function subscribe (line 78) | async fn subscribe() {
function subscribe_raw_json (line 92) | async fn subscribe_raw_json() {
function subscribe_trade (line 101) | async fn subscribe_trade() {
function subscribe_bbo (line 115) | async fn subscribe_bbo() {
function subscribe_orderbook (line 120) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 125) | async fn subscribe_orderbook_topk() {
function subscribe_ticker (line 130) | async fn subscribe_ticker() {
function subscribe_candlestick (line 136) | async fn subscribe_candlestick() {
function subscribe (line 154) | async fn subscribe() {
function subscribe_raw_json (line 163) | async fn subscribe_raw_json() {
function subscribe_trade (line 172) | async fn subscribe_trade() {
function subscribe_bbo (line 177) | async fn subscribe_bbo() {
function subscribe_orderbook (line 182) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 187) | async fn subscribe_orderbook_topk() {
function subscribe_ticker (line 192) | async fn subscribe_ticker() {
function subscribe_candlestick (line 198) | async fn subscribe_candlestick() {
function subscribe (line 217) | async fn subscribe() {
function subscribe_raw_json (line 227) | async fn subscribe_raw_json() {
function subscribe_trade (line 237) | async fn subscribe_trade() {
function subscribe_bbo (line 243) | async fn subscribe_bbo() {
function subscribe_orderbook (line 248) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 253) | async fn subscribe_orderbook_topk() {
function subscribe_ticker (line 258) | async fn subscribe_ticker() {
function subscribe_candlestick (line 264) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/mexc.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_raw_json (line 22) | async fn subscribe_raw_json() {
function subscribe_trade (line 35) | async fn subscribe_trade() {
function subscribe_orderbook (line 44) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 53) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 58) | async fn subscribe_candlestick() {
function subscribe_overview (line 78) | async fn subscribe_overview() {
function subscribe (line 88) | async fn subscribe() {
function subscribe_raw_json (line 100) | async fn subscribe_raw_json() {
function subscribe_trade (line 109) | async fn subscribe_trade() {
function subscribe_ticker (line 114) | async fn subscribe_ticker() {
function subscribe_orderbook (line 119) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 124) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 129) | async fn subscribe_candlestick() {
function subscribe_trade (line 140) | async fn subscribe_trade() {
function subscribe_ticker (line 145) | async fn subscribe_ticker() {
function subscribe_orderbook (line 150) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 155) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 160) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/okx.rs
function okex_index (line 7) | async fn okex_index() {
function subscribe (line 20) | async fn subscribe() {
function subscribe_raw_json (line 25) | async fn subscribe_raw_json() {
function subscribe_trade (line 35) | async fn subscribe_trade() {
function subscribe_ticker (line 40) | async fn subscribe_ticker() {
function subscribe_bbo (line 45) | async fn subscribe_bbo() {
function subscribe_orderbook (line 50) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 55) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 60) | async fn subscribe_candlestick() {
function subscribe (line 71) | async fn subscribe() {
function subscribe_trade (line 80) | async fn subscribe_trade() {
function subscribe_ticker (line 85) | async fn subscribe_ticker() {
function subscribe_bbo (line 90) | async fn subscribe_bbo() {
function subscribe_orderbook (line 95) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 100) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 105) | async fn subscribe_candlestick() {
function subscribe (line 116) | async fn subscribe() {
function subscribe_trade (line 125) | async fn subscribe_trade() {
function subscribe_ticker (line 130) | async fn subscribe_ticker() {
function subscribe_bbo (line 135) | async fn subscribe_bbo() {
function subscribe_orderbook (line 140) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 145) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 150) | async fn subscribe_candlestick() {
function subscribe_funding_rate (line 156) | async fn subscribe_funding_rate() {
function subscribe_trade (line 171) | async fn subscribe_trade() {
function subscribe_ticker (line 176) | async fn subscribe_ticker() {
function subscribe_bbo (line 181) | async fn subscribe_bbo() {
function subscribe_orderbook (line 186) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 191) | async fn subscribe_orderbook_topk() {
function subscribe_candlestick (line 201) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/zb.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_raw_json (line 18) | async fn subscribe_raw_json() {
function subscribe_trade (line 27) | async fn subscribe_trade() {
function subscribe_orderbook_topk (line 32) | async fn subscribe_orderbook_topk() {
function subscribe_ticker (line 37) | async fn subscribe_ticker() {
function subscribe_candlestick (line 42) | async fn subscribe_candlestick() {
function subscribe (line 53) | async fn subscribe() {
function subscribe_raw_json (line 65) | async fn subscribe_raw_json() {
function subscribe_trade (line 77) | async fn subscribe_trade() {
function subscribe_orderbook (line 86) | async fn subscribe_orderbook() {
function subscribe_orderbook_topk (line 95) | async fn subscribe_orderbook_topk() {
function subscribe_ticker (line 104) | async fn subscribe_ticker() {
function subscribe_candlestick (line 113) | async fn subscribe_candlestick() {
FILE: crypto-ws-client/tests/zbg.rs
function subscribe (line 9) | async fn subscribe() {
function subscribe_raw_json (line 18) | async fn subscribe_raw_json() {
function subscribe_trade (line 27) | async fn subscribe_trade() {
function subscribe_orderbook (line 32) | async fn subscribe_orderbook() {
function subscribe_ticker (line 37) | async fn subscribe_ticker() {
function subscribe_ticker_all (line 43) | async fn subscribe_ticker_all() {
function subscribe_candlestick (line 52) | async fn subscribe_candlestick() {
function subscribe (line 64) | fn subscribe() {
function subscribe_raw_json (line 77) | fn subscribe_raw_json() {
function subscribe_trade (line 90) | fn subscribe_trade() {
function subscribe_orderbook (line 100) | fn subscribe_orderbook() {
function subscribe_ticker (line 110) | async fn subscribe_ticker() {
function subscribe_ticker_all (line 120) | async fn subscribe_ticker_all() {
function subscribe_candlestick (line 130) | async fn subscribe_candlestick() {
function subscribe (line 148) | fn subscribe() {
function subscribe_raw_json (line 161) | fn subscribe_raw_json() {
function subscribe_trade (line 174) | fn subscribe_trade() {
function subscribe_orderbook (line 184) | fn subscribe_orderbook() {
function subscribe_ticker (line 194) | async fn subscribe_ticker() {
function subscribe_ticker_all (line 204) | async fn subscribe_ticker_all() {
function subscribe_candlestick (line 214) | async fn subscribe_candlestick() {
Condensed preview — 306 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,011K chars).
[
{
"path": ".config/nextest.toml",
"chars": 104,
"preview": "[profile.default]\nslow-timeout = { period = \"60s\", terminate-after = 2 }\nfail-fast = false\nretries = 1\n\n"
},
{
"path": ".editorconfig",
"chars": 280,
"preview": "# https://EditorConfig.org\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 4\nindent_style = space\ninsert"
},
{
"path": ".github/CODEOWNERS",
"chars": 16,
"preview": "*\t@soulmachine\n\n"
},
{
"path": ".github/workflows/ci.yml",
"chars": 2610,
"preview": "name: CI\n\non: [push, pull_request]\n\nenv:\n CARGO_TERM_COLOR: always\n\n# Stop the previous CI tasks (which is deprecated)\n"
},
{
"path": ".gitignore",
"chars": 378,
"preview": "# Generated by Cargo\n# will have compiled files and executables\n/target/\n\n# Remove Cargo.lock from gitignore if creating"
},
{
"path": "Cargo.toml",
"chars": 176,
"preview": "[workspace]\nmembers = [\n \"crypto-client\",\n \"crypto-crawler\",\n \"crypto-markets\",\n \"crypto-market-type\",\n \"crypto-msg"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 1986,
"preview": "# crypto-crawler-rs\n\n[](https"
},
{
"path": "crypto-client/Cargo.toml",
"chars": 559,
"preview": "[package]\nname = \"crypto-client\"\nversion = \"0.1.0\"\nauthors = [\"soulmachine <soulmachine@gmail.com>\"]\nedition = \"2021\"\nde"
},
{
"path": "crypto-client/README.md",
"chars": 662,
"preview": "# crypto-client\n\nAn unified client for all cryptocurrency exchanges.\n\n## Example\n\n```rust\nuse crypto_client::{CryptoClie"
},
{
"path": "crypto-client/src/lib.rs",
"chars": 234,
"preview": "/// An unified restful client for all cryptocurrency exchanges.\npub struct CryptoClient {\n #[allow(dead_code)]\n ex"
},
{
"path": "crypto-crawler/Cargo.toml",
"chars": 960,
"preview": "[package]\nname = \"crypto-crawler\"\nversion = \"4.7.9\"\nauthors = [\"soulmachine <soulmachine@gmail.com>\"]\nedition = \"2021\"\nd"
},
{
"path": "crypto-crawler/README.md",
"chars": 5214,
"preview": "# crypto-crawler\n\n[](https://"
},
{
"path": "crypto-crawler/src/crawlers/binance.rs",
"chars": 6485,
"preview": "use core::panic;\nuse std::sync::mpsc::Sender;\n\nuse crate::{\n crawlers::utils::crawl_event, fetch_symbols_retry, get_h"
},
{
"path": "crypto-crawler/src/crawlers/bitmex.rs",
"chars": 5014,
"preview": "use super::{\n crawl_candlestick_ext, crawl_event,\n utils::{check_args, fetch_symbols_retry},\n};\nuse crate::{crawle"
},
{
"path": "crypto-crawler/src/crawlers/deribit.rs",
"chars": 1691,
"preview": "use super::crawl_event;\nuse crate::{crawlers::utils::create_conversion_thread, msg::Message};\nuse crypto_market_type::Ma"
},
{
"path": "crypto-crawler/src/crawlers/huobi.rs",
"chars": 3101,
"preview": "use super::utils::fetch_symbols_retry;\nuse crate::{\n crawlers::{crawl_event, utils::create_conversion_thread},\n ms"
},
{
"path": "crypto-crawler/src/crawlers/kucoin.rs",
"chars": 1098,
"preview": "use crate::{crawlers::utils::create_conversion_thread, msg::Message};\nuse crypto_market_type::MarketType;\nuse crypto_msg"
},
{
"path": "crypto-crawler/src/crawlers/mod.rs",
"chars": 370,
"preview": "#[macro_use]\nmod utils;\n\npub(super) mod binance;\npub(super) mod bitmex;\npub(super) mod deribit;\npub(super) mod huobi;\npu"
},
{
"path": "crypto-crawler/src/crawlers/okx.rs",
"chars": 2455,
"preview": "use super::utils::fetch_symbols_retry;\nuse crate::{crawlers::utils::create_conversion_thread, msg::Message};\nuse crypto_"
},
{
"path": "crypto-crawler/src/crawlers/utils.rs",
"chars": 40369,
"preview": "use std::{\n sync::{mpsc::Sender, Arc},\n time::{Duration, SystemTime, UNIX_EPOCH},\n};\n\nuse crate::utils::{REST_LOCK"
},
{
"path": "crypto-crawler/src/crawlers/zb.rs",
"chars": 1052,
"preview": "use std::sync::mpsc::Sender;\n\nuse crate::{crawlers::utils::crawl_event, msg::Message};\nuse crypto_market_type::MarketTyp"
},
{
"path": "crypto-crawler/src/crawlers/zbg.rs",
"chars": 1642,
"preview": "use std::sync::mpsc::Sender;\n\nuse crate::{crawlers::utils::crawl_event, msg::Message};\nuse crypto_market_type::MarketTyp"
},
{
"path": "crypto-crawler/src/lib.rs",
"chars": 14084,
"preview": "//! A rock-solid cryprocurrency crawler.\n//!\n//! ## Crawl realtime trades\n//!\n//! ```rust\n//! use crypto_crawler::{crawl"
},
{
"path": "crypto-crawler/src/msg.rs",
"chars": 2751,
"preview": "use crypto_market_type::MarketType;\nuse crypto_msg_type::MessageType;\nuse serde::{Deserialize, Serialize};\nuse std::{\n "
},
{
"path": "crypto-crawler/src/utils/cmc_rank.rs",
"chars": 9107,
"preview": "use reqwest::header;\nuse serde::{Deserialize, Serialize};\nuse serde_json::Value;\nuse std::collections::HashMap;\n\nuse onc"
},
{
"path": "crypto-crawler/src/utils/lock.rs",
"chars": 7807,
"preview": "use std::{collections::HashMap, sync::Arc};\n\nuse crypto_market_type::MarketType;\nuse fslock::LockFile;\nuse once_cell::sy"
},
{
"path": "crypto-crawler/src/utils/mod.rs",
"chars": 154,
"preview": "pub(crate) mod cmc_rank;\nmod lock;\npub(crate) mod spot_symbols;\n\npub(crate) use lock::{REST_LOCKS, WS_LOCKS};\npub use sp"
},
{
"path": "crypto-crawler/src/utils/spot_symbols.rs",
"chars": 2073,
"preview": "use std::collections::HashSet;\n\nuse crypto_market_type::MarketType;\n\npub fn get_hot_spot_symbols(exchange: &str, spot_sy"
},
{
"path": "crypto-crawler/tests/binance.rs",
"chars": 5532,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/bitfinex.rs",
"chars": 2839,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/bitget.rs",
"chars": 3137,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/bithumb.rs",
"chars": 1688,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/bitmex.rs",
"chars": 3209,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/bitstamp.rs",
"chars": 2239,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/bitz.rs",
"chars": 2369,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/bybit.rs",
"chars": 2878,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/coinbase_pro.rs",
"chars": 2247,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/deribit.rs",
"chars": 3786,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/dydx.rs",
"chars": 1198,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/ftx.rs",
"chars": 3027,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/gate.rs",
"chars": 3694,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/huobi.rs",
"chars": 4940,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/kraken.rs",
"chars": 2732,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/kucoin.rs",
"chars": 4074,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/mexc.rs",
"chars": 2818,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/okx.rs",
"chars": 5693,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/utils/mod.rs",
"chars": 4694,
"preview": "use crypto_crawler::Message;\nuse crypto_market_type::MarketType;\nuse crypto_msg_type::MessageType;\n\npub(crate) fn parse("
},
{
"path": "crypto-crawler/tests/zb.rs",
"chars": 2503,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-crawler/tests/zbg.rs",
"chars": 2477,
"preview": "#[macro_use]\nmod utils;\n\nuse test_case::test_case;\n\nuse crypto_crawler::*;\nuse crypto_market_type::MarketType;\nuse crypt"
},
{
"path": "crypto-market-type/Cargo.toml",
"chars": 444,
"preview": "[package]\nname = \"crypto-market-type\"\nversion = \"1.1.5\"\nauthors = [\"soulmachine <soulmachine@gmail.com>\"]\nedition = \"202"
},
{
"path": "crypto-market-type/include/crypto_market_type.h",
"chars": 1224,
"preview": "/* Licensed under Apache-2.0 */\n#ifndef CRYPTO_MARKET_TYPE_H_\n#define CRYPTO_MARKET_TYPE_H_\n\n/**\n * Market type.\n *\n * *"
},
{
"path": "crypto-market-type/src/lib.rs",
"chars": 4723,
"preview": "use serde::{Deserialize, Serialize};\nuse strum_macros::{Display, EnumString};\n\n/// Market type.\n///\n/// * In spot market"
},
{
"path": "crypto-markets/Cargo.toml",
"chars": 669,
"preview": "[package]\nname = \"crypto-markets\"\nversion = \"1.3.11\"\nauthors = [\"soulmachine <soulmachine@gmail.com>\"]\nedition = \"2021\"\n"
},
{
"path": "crypto-markets/README.md",
"chars": 666,
"preview": "# crypto-markets\n\n[](https://"
},
{
"path": "crypto-markets/src/error.rs",
"chars": 556,
"preview": "use std::{error::Error as StdError, fmt};\n\npub(crate) type Result<T> = std::result::Result<T, Error>;\n\n#[derive(Debug)]\n"
},
{
"path": "crypto-markets/src/exchanges/binance/binance_inverse.rs",
"chars": 4508,
"preview": "use super::utils::{binance_http_get, parse_filter};\nuse crate::{error::Result, market::*, Market, MarketType};\n\nuse serd"
},
{
"path": "crypto-markets/src/exchanges/binance/binance_linear.rs",
"chars": 4437,
"preview": "use super::utils::{binance_http_get, parse_filter};\nuse crate::{error::Result, market::*, Market, MarketType};\n\nuse serd"
},
{
"path": "crypto-markets/src/exchanges/binance/binance_option.rs",
"chars": 3390,
"preview": "use super::utils::binance_http_get;\nuse crate::{error::Result, market::*, Market, MarketType};\n\nuse serde::{Deserialize,"
},
{
"path": "crypto-markets/src/exchanges/binance/binance_spot.rs",
"chars": 3192,
"preview": "use super::utils::{binance_http_get, parse_filter};\nuse crate::{error::Result, market::*, Market, MarketType};\n\nuse serd"
},
{
"path": "crypto-markets/src/exchanges/binance/mod.rs",
"chars": 1475,
"preview": "pub(super) mod binance_inverse;\npub(super) mod binance_linear;\npub(super) mod binance_option;\npub(super) mod binance_spo"
},
{
"path": "crypto-markets/src/exchanges/binance/utils.rs",
"chars": 977,
"preview": "use super::super::utils::http_get;\nuse crate::error::{Error, Result};\n\nuse serde_json::Value;\nuse std::collections::Hash"
},
{
"path": "crypto-markets/src/exchanges/bitfinex.rs",
"chars": 7101,
"preview": "use std::collections::HashMap;\n\nuse super::utils::http_get;\nuse crate::{\n error::Result,\n market::{Fees, Precision"
},
{
"path": "crypto-markets/src/exchanges/bitget/bitget_spot.rs",
"chars": 3679,
"preview": "use std::collections::HashMap;\n\nuse super::{super::utils::http_get, EXCHANGE_NAME};\nuse crate::{\n error::{Error, Resu"
},
{
"path": "crypto-markets/src/exchanges/bitget/bitget_swap.rs",
"chars": 6014,
"preview": "use std::collections::HashMap;\n\nuse super::{super::utils::http_get, EXCHANGE_NAME};\nuse crate::{\n error::{Error, Resu"
},
{
"path": "crypto-markets/src/exchanges/bitget/mod.rs",
"chars": 1101,
"preview": "pub(super) mod bitget_spot;\npub(super) mod bitget_swap;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(super) con"
},
{
"path": "crypto-markets/src/exchanges/bithumb.rs",
"chars": 3898,
"preview": "use std::collections::HashMap;\n\nuse super::utils::http_get;\nuse crate::{\n error::{Error, Result},\n Fees, Market, M"
},
{
"path": "crypto-markets/src/exchanges/bitmex.rs",
"chars": 9150,
"preview": "use std::collections::HashMap;\n\nuse super::utils::http_get;\nuse crate::{\n error::Result,\n market::{Fees, Precision"
},
{
"path": "crypto-markets/src/exchanges/bitstamp.rs",
"chars": 2995,
"preview": "use super::utils::http_get;\nuse crate::{error::Result, Fees, Market, MarketType, Precision};\n\nuse serde::{Deserialize, S"
},
{
"path": "crypto-markets/src/exchanges/bitz/bitz_spot.rs",
"chars": 1455,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::error::{Error, Result};\n\nuse serde::{Deser"
},
{
"path": "crypto-markets/src/exchanges/bitz/bitz_swap.rs",
"chars": 2815,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::error::{Error, Result};\n\nuse serde::{Deser"
},
{
"path": "crypto-markets/src/exchanges/bitz/mod.rs",
"chars": 565,
"preview": "mod bitz_spot;\nmod bitz_swap;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(crate) fn fetch_symbols(market_type:"
},
{
"path": "crypto-markets/src/exchanges/bybit.rs",
"chars": 6989,
"preview": "use std::collections::HashMap;\n\nuse super::utils::http_get;\nuse crate::{error::Result, Fees, Market, MarketType, Precisi"
},
{
"path": "crypto-markets/src/exchanges/coinbase_pro.rs",
"chars": 3531,
"preview": "use std::collections::HashMap;\n\nuse super::utils::http_get;\nuse crate::{error::Result, Fees, Market, MarketType, Precisi"
},
{
"path": "crypto-markets/src/exchanges/deribit/mod.rs",
"chars": 842,
"preview": "mod utils;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(crate) fn fetch_symbols(market_type: MarketType) -> Res"
},
{
"path": "crypto-markets/src/exchanges/deribit/utils.rs",
"chars": 6317,
"preview": "use super::super::utils::http_get;\nuse crate::{\n error::{Error, Result},\n market::{Fees, Precision, QuantityLimit}"
},
{
"path": "crypto-markets/src/exchanges/dydx/dydx_swap.rs",
"chars": 3060,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{error::Result, Fees, Market, Precision, Q"
},
{
"path": "crypto-markets/src/exchanges/dydx/mod.rs",
"chars": 570,
"preview": "mod dydx_swap;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(crate) fn fetch_symbols(market_type: MarketType) ->"
},
{
"path": "crypto-markets/src/exchanges/ftx.rs",
"chars": 8063,
"preview": "use std::collections::HashMap;\n\nuse super::utils::http_get;\nuse crate::{error::Result, Fees, Market, MarketType, Precisi"
},
{
"path": "crypto-markets/src/exchanges/gate/gate_future.rs",
"chars": 4487,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{error::Result, Fees, Market, Precision, Q"
},
{
"path": "crypto-markets/src/exchanges/gate/gate_spot.rs",
"chars": 3078,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{error::Result, Fees, Market, Precision, Q"
},
{
"path": "crypto-markets/src/exchanges/gate/gate_swap.rs",
"chars": 4315,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{error::Result, Fees, Market, Precision, Q"
},
{
"path": "crypto-markets/src/exchanges/gate/mod.rs",
"chars": 1190,
"preview": "mod gate_future;\nmod gate_spot;\nmod gate_swap;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(crate) fn fetch_sym"
},
{
"path": "crypto-markets/src/exchanges/huobi/huobi_future.rs",
"chars": 3540,
"preview": "use super::utils::huobi_http_get;\nuse crate::{\n error::Result,\n market::{Fees, Precision},\n Market,\n};\n\nuse cry"
},
{
"path": "crypto-markets/src/exchanges/huobi/huobi_inverse_swap.rs",
"chars": 2768,
"preview": "use super::utils::huobi_http_get;\nuse crate::{\n error::Result,\n market::{Fees, Precision},\n Market,\n};\n\nuse cry"
},
{
"path": "crypto-markets/src/exchanges/huobi/huobi_linear_swap.rs",
"chars": 2772,
"preview": "use super::utils::huobi_http_get;\nuse crate::{\n error::Result,\n market::{Fees, Precision},\n Market,\n};\n\nuse cry"
},
{
"path": "crypto-markets/src/exchanges/huobi/huobi_option.rs",
"chars": 1391,
"preview": "use super::utils::huobi_http_get;\nuse crate::error::Result;\n\nuse serde::{Deserialize, Serialize};\nuse serde_json::Value;"
},
{
"path": "crypto-markets/src/exchanges/huobi/huobi_spot.rs",
"chars": 3267,
"preview": "use super::utils::huobi_http_get;\nuse crate::{\n error::Result,\n market::{Fees, Precision, QuantityLimit},\n Mark"
},
{
"path": "crypto-markets/src/exchanges/huobi/mod.rs",
"chars": 1317,
"preview": "mod utils;\n\npub(super) mod huobi_future;\npub(super) mod huobi_inverse_swap;\npub(super) mod huobi_linear_swap;\npub(super)"
},
{
"path": "crypto-markets/src/exchanges/huobi/utils.rs",
"chars": 750,
"preview": "use super::super::utils::http_get;\nuse crate::error::{Error, Result};\n\nuse serde_json::Value;\nuse std::collections::Hash"
},
{
"path": "crypto-markets/src/exchanges/kraken/kraken_futures.rs",
"chars": 5375,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{\n error::{Error, Result},\n Fees, Ma"
},
{
"path": "crypto-markets/src/exchanges/kraken/kraken_spot.rs",
"chars": 3865,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{\n error::{Error, Result},\n Fees, Ma"
},
{
"path": "crypto-markets/src/exchanges/kraken/mod.rs",
"chars": 892,
"preview": "mod kraken_futures;\nmod kraken_spot;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(crate) fn fetch_symbols(marke"
},
{
"path": "crypto-markets/src/exchanges/kucoin/kucoin_spot.rs",
"chars": 3231,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{\n error::{Error, Result},\n Fees, Ma"
},
{
"path": "crypto-markets/src/exchanges/kucoin/kucoin_swap.rs",
"chars": 5198,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{\n error::{Error, Result},\n Fees, Ma"
},
{
"path": "crypto-markets/src/exchanges/kucoin/mod.rs",
"chars": 1029,
"preview": "mod kucoin_spot;\nmod kucoin_swap;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(crate) fn fetch_symbols(market_t"
},
{
"path": "crypto-markets/src/exchanges/mexc/mexc_spot.rs",
"chars": 3113,
"preview": "use super::utils::mexc_http_get;\nuse crate::{error::Result, Fees, Market, Precision, QuantityLimit};\n\nuse crypto_market_"
},
{
"path": "crypto-markets/src/exchanges/mexc/mexc_swap.rs",
"chars": 4154,
"preview": "use super::utils::mexc_http_get;\nuse crate::{error::Result, Fees, Market, Precision, QuantityLimit};\n\nuse crypto_market_"
},
{
"path": "crypto-markets/src/exchanges/mexc/mod.rs",
"chars": 931,
"preview": "mod utils;\n\npub(super) mod mexc_spot;\npub(super) mod mexc_swap;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(su"
},
{
"path": "crypto-markets/src/exchanges/mexc/utils.rs",
"chars": 736,
"preview": "use super::super::utils::http_get;\nuse crate::error::{Error, Result};\n\nuse serde_json::Value;\nuse std::collections::Hash"
},
{
"path": "crypto-markets/src/exchanges/mod.rs",
"chars": 475,
"preview": "#[macro_use]\nmod utils;\n\npub(super) mod binance;\npub(super) mod bitfinex;\npub(super) mod bitget;\npub(super) mod bithumb;"
},
{
"path": "crypto-markets/src/exchanges/okx.rs",
"chars": 11057,
"preview": "use std::collections::HashMap;\n\nuse super::utils::http_get;\nuse crate::{\n error::Result,\n market::{Fees, Precision"
},
{
"path": "crypto-markets/src/exchanges/utils.rs",
"chars": 2699,
"preview": "use reqwest::header;\n\nuse crate::error::{Error, Result};\nuse std::collections::HashMap;\n\npub(super) fn http_get(url: &st"
},
{
"path": "crypto-markets/src/exchanges/zb/mod.rs",
"chars": 675,
"preview": "mod zb_spot;\nmod zb_swap;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(crate) fn fetch_symbols(market_type: Mar"
},
{
"path": "crypto-markets/src/exchanges/zb/zb_spot.rs",
"chars": 2873,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{error::Result, Fees, Market, Precision, Q"
},
{
"path": "crypto-markets/src/exchanges/zb/zb_swap.rs",
"chars": 3591,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{\n error::{Error, Result},\n Fees, Ma"
},
{
"path": "crypto-markets/src/exchanges/zbg/mod.rs",
"chars": 831,
"preview": "mod zbg_spot;\nmod zbg_swap;\n\nuse crate::{error::Result, Market, MarketType};\n\npub(crate) fn fetch_symbols(market_type: M"
},
{
"path": "crypto-markets/src/exchanges/zbg/zbg_spot.rs",
"chars": 3257,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{\n error::{Error, Result},\n Fees, Ma"
},
{
"path": "crypto-markets/src/exchanges/zbg/zbg_swap.rs",
"chars": 4179,
"preview": "use std::collections::HashMap;\n\nuse super::super::utils::http_get;\nuse crate::{\n error::{Error, Result},\n Fees, Ma"
},
{
"path": "crypto-markets/src/lib.rs",
"chars": 3988,
"preview": "#![allow(clippy::unnecessary_wraps)]\n//! Get all trading pairs of a cryptocurrency exchange.\n//!\n//! ## Example\n//!\n//! "
},
{
"path": "crypto-markets/src/main.rs",
"chars": 692,
"preview": "use crypto_market_type::MarketType;\nuse crypto_markets::fetch_markets;\nuse std::{env, str::FromStr};\n\nfn main() {\n le"
},
{
"path": "crypto-markets/src/market.rs",
"chars": 2965,
"preview": "use crypto_market_type::MarketType;\nuse serde::{Deserialize, Serialize};\nuse serde_json::{Map, Value};\n\n#[derive(Clone, "
},
{
"path": "crypto-markets/tests/binance.rs",
"chars": 5838,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/bitfinex.rs",
"chars": 2280,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/bitget.rs",
"chars": 4226,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/bithumb.rs",
"chars": 1028,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/bitmex.rs",
"chars": 4378,
"preview": "use crypto_market_type::MarketType;\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_pair::get_market_type"
},
{
"path": "crypto-markets/tests/bitstamp.rs",
"chars": 917,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/bitz.rs",
"chars": 1148,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::fetch_symbols;\n\n#[macro_use]\nmod utils;\n\ncon"
},
{
"path": "crypto-markets/tests/bybit.rs",
"chars": 3366,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/coinbase_pro.rs",
"chars": 1180,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/deribit.rs",
"chars": 3616,
"preview": "use crypto_market_type::MarketType;\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_pair::get_market_type"
},
{
"path": "crypto-markets/tests/dydx.rs",
"chars": 1264,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/ftx.rs",
"chars": 5078,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/gate.rs",
"chars": 5372,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse test_cas"
},
{
"path": "crypto-markets/tests/huobi.rs",
"chars": 4062,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/kraken.rs",
"chars": 2878,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/kucoin.rs",
"chars": 4055,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/mexc.rs",
"chars": 3311,
"preview": "use crypto_market_type::MarketType;\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_pair::get_market_type"
},
{
"path": "crypto-markets/tests/okx.rs",
"chars": 5917,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/utils/mod.rs",
"chars": 2433,
"preview": "#[allow(unused_macros)]\nmacro_rules! gen_all_symbols {\n () => {\n let market_types = get_market_types(EXCHANGE_"
},
{
"path": "crypto-markets/tests/zb.rs",
"chars": 2634,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-markets/tests/zbg.rs",
"chars": 3180,
"preview": "use crypto_market_type::{get_market_types, MarketType};\nuse crypto_markets::{fetch_markets, fetch_symbols};\nuse crypto_p"
},
{
"path": "crypto-msg-type/Cargo.toml",
"chars": 455,
"preview": "[package]\nname = \"crypto-msg-type\"\nversion = \"1.0.11\"\nauthors = [\"soulmachine <soulmachine@gmail.com>\"]\nedition = \"2021\""
},
{
"path": "crypto-msg-type/include/crypto_msg_type.h",
"chars": 1059,
"preview": "/* Licensed under Apache-2.0 */\n#ifndef CRYPTO_MSG_TYPE_H_\n#define CRYPTO_MSG_TYPE_H_\n\n/**\n * Crypto message types.\n *\n "
},
{
"path": "crypto-msg-type/src/exchanges/binance.rs",
"chars": 3170,
"preview": "use std::collections::HashMap;\n\nuse crate::MessageType;\n\nfn msg_type_to_channel(msg_type: MessageType) -> &'static str {"
},
{
"path": "crypto-msg-type/src/exchanges/bitfinex.rs",
"chars": 3495,
"preview": "use std::collections::HashMap;\n\nuse crate::MessageType;\n\nfn msg_type_symbol_to_command(\n msg_type: MessageType,\n s"
},
{
"path": "crypto-msg-type/src/exchanges/bitmex.rs",
"chars": 2835,
"preview": "use std::collections::HashMap;\n\nuse crate::MessageType;\n\nfn msg_type_to_channel(msg_type: MessageType) -> &'static str {"
},
{
"path": "crypto-msg-type/src/exchanges/bybit.rs",
"chars": 2963,
"preview": "use std::collections::HashMap;\n\nuse crate::MessageType;\n\nfn msg_type_to_channel(msg_type: MessageType) -> &'static str {"
},
{
"path": "crypto-msg-type/src/exchanges/deribit.rs",
"chars": 3033,
"preview": "use std::collections::HashMap;\n\nuse crate::MessageType;\n\nfn msg_type_symbol_to_topic(\n msg_type: MessageType,\n sym"
},
{
"path": "crypto-msg-type/src/exchanges/ftx.rs",
"chars": 2066,
"preview": "use std::collections::HashMap;\n\nuse crate::MessageType;\n\nfn msg_type_to_channel(msg_type: MessageType) -> &'static str {"
},
{
"path": "crypto-msg-type/src/exchanges/huobi.rs",
"chars": 3611,
"preview": "use std::collections::HashMap;\n\nuse crate::MessageType;\n\nfn msg_type_symbol_to_topic(\n msg_type: MessageType,\n sym"
},
{
"path": "crypto-msg-type/src/exchanges/mod.rs",
"chars": 201,
"preview": "pub(super) mod binance;\npub(super) mod bitfinex;\npub(super) mod bitmex;\npub(super) mod bybit;\npub(super) mod deribit;\npu"
},
{
"path": "crypto-msg-type/src/exchanges/okex.rs",
"chars": 3565,
"preview": "use std::collections::HashMap;\n\nuse crate::MessageType;\n\nfn get_market_type(symbol: &str) -> &'static str {\n if symbo"
},
{
"path": "crypto-msg-type/src/exchanges/okx.rs",
"chars": 3511,
"preview": "use std::collections::{BTreeMap, HashMap};\n\nuse crate::MessageType;\n\nfn msg_type_to_channel(msg_type: MessageType) -> &'"
},
{
"path": "crypto-msg-type/src/lib.rs",
"chars": 2636,
"preview": "mod exchanges;\n\nuse std::collections::HashMap;\n\nuse serde::{Deserialize, Serialize};\nuse strum_macros::{Display, EnumStr"
},
{
"path": "crypto-rest-client/Cargo.toml",
"chars": 653,
"preview": "[package]\nname = \"crypto-rest-client\"\nversion = \"1.0.1\"\nauthors = [\"soulmachine <soulmachine@gmail.com>\"]\nedition = \"202"
},
{
"path": "crypto-rest-client/README.md",
"chars": 552,
"preview": "# crypto-rest-client\n\nAn RESTful client for all cryptocurrency exchanges.\n\n## Example\n\n```rust\nuse crypto_rest_client::{"
},
{
"path": "crypto-rest-client/src/error.rs",
"chars": 556,
"preview": "use std::{error::Error as StdError, fmt};\n\npub(crate) type Result<T> = std::result::Result<T, Error>;\n\n#[derive(Debug)]\n"
},
{
"path": "crypto-rest-client/src/exchanges/binance/binance_inverse.rs",
"chars": 2415,
"preview": "use super::{super::utils::http_get, utils::*};\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL"
},
{
"path": "crypto-rest-client/src/exchanges/binance/binance_linear.rs",
"chars": 2395,
"preview": "use super::{super::utils::http_get, utils::*};\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL"
},
{
"path": "crypto-rest-client/src/exchanges/binance/binance_option.rs",
"chars": 1448,
"preview": "use super::{super::utils::http_get, utils::*};\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL"
},
{
"path": "crypto-rest-client/src/exchanges/binance/binance_spot.rs",
"chars": 1770,
"preview": "use super::{super::utils::http_get, utils::*};\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL"
},
{
"path": "crypto-rest-client/src/exchanges/binance/mod.rs",
"chars": 1436,
"preview": "#[macro_use]\nmod utils;\n\npub(crate) mod binance_inverse;\npub(crate) mod binance_linear;\npub(crate) mod binance_option;\np"
},
{
"path": "crypto-rest-client/src/exchanges/binance/utils.rs",
"chars": 1447,
"preview": "use std::collections::BTreeMap;\n\nuse crate::error::{Error, Result};\n\nuse once_cell::sync::Lazy;\nuse regex::Regex;\nuse se"
},
{
"path": "crypto-rest-client/src/exchanges/bitfinex.rs",
"chars": 1754,
"preview": "use super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"https://a"
},
{
"path": "crypto-rest-client/src/exchanges/bitget/bitget_spot.rs",
"chars": 975,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/bitget/bitget_swap.rs",
"chars": 1281,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/bitget/mod.rs",
"chars": 1047,
"preview": "mod bitget_spot;\nmod bitget_swap;\n\npub use bitget_spot::BitgetSpotRestClient;\npub use bitget_swap::BitgetSwapRestClient;"
},
{
"path": "crypto-rest-client/src/exchanges/bithumb.rs",
"chars": 1403,
"preview": "use super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"https://g"
},
{
"path": "crypto-rest-client/src/exchanges/bitmex.rs",
"chars": 1683,
"preview": "use super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"https://w"
},
{
"path": "crypto-rest-client/src/exchanges/bitstamp.rs",
"chars": 1911,
"preview": "use super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"https://w"
},
{
"path": "crypto-rest-client/src/exchanges/bitz/bitz_spot.rs",
"chars": 957,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/bitz/bitz_swap.rs",
"chars": 3040,
"preview": "use super::super::utils::http_get;\nuse crate::error::{Error, Result};\nuse std::collections::{BTreeMap, HashMap};\n\nuse se"
},
{
"path": "crypto-rest-client/src/exchanges/bitz/mod.rs",
"chars": 971,
"preview": "mod bitz_spot;\nmod bitz_swap;\n\npub use bitz_spot::BitzSpotRestClient;\npub use bitz_swap::BitzSwapRestClient;\n\nuse crate:"
},
{
"path": "crypto-rest-client/src/exchanges/bybit.rs",
"chars": 2447,
"preview": "use super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"https://a"
},
{
"path": "crypto-rest-client/src/exchanges/coinbase_pro.rs",
"chars": 1856,
"preview": "use super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"https://a"
},
{
"path": "crypto-rest-client/src/exchanges/deribit.rs",
"chars": 2574,
"preview": "use super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"https://w"
},
{
"path": "crypto-rest-client/src/exchanges/dydx/dydx_swap.rs",
"chars": 1146,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/dydx/mod.rs",
"chars": 720,
"preview": "pub(crate) mod dydx_swap;\n\nuse crate::error::Result;\nuse crypto_market_type::MarketType;\n\npub(crate) fn fetch_l2_snapsho"
},
{
"path": "crypto-rest-client/src/exchanges/ftx.rs",
"chars": 1390,
"preview": "use super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"https://f"
},
{
"path": "crypto-rest-client/src/exchanges/gate/gate_future.rs",
"chars": 1419,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/gate/gate_spot.rs",
"chars": 1114,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/gate/gate_swap.rs",
"chars": 2085,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/gate/mod.rs",
"chars": 1169,
"preview": "mod gate_future;\nmod gate_spot;\nmod gate_swap;\n\npub use gate_future::GateFutureRestClient;\npub use gate_spot::GateSpotRe"
},
{
"path": "crypto-rest-client/src/exchanges/huobi/huobi_future.rs",
"chars": 1472,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/huobi/huobi_inverse_swap.rs",
"chars": 1613,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/huobi/huobi_linear_swap.rs",
"chars": 1623,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/huobi/huobi_option.rs",
"chars": 1122,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/huobi/huobi_spot.rs",
"chars": 985,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/huobi/mod.rs",
"chars": 2086,
"preview": "#[macro_use]\nmod utils;\n\npub(crate) mod huobi_future;\npub(crate) mod huobi_inverse_swap;\npub(crate) mod huobi_linear_swa"
},
{
"path": "crypto-rest-client/src/exchanges/huobi/utils.rs",
"chars": 686,
"preview": "macro_rules! impl_contract {\n ($struct_name:ident) => {\n impl $struct_name {\n pub fn new(api_key: O"
},
{
"path": "crypto-rest-client/src/exchanges/kraken/kraken_futures.rs",
"chars": 1556,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\n// see https://support.kra"
},
{
"path": "crypto-rest-client/src/exchanges/kraken/kraken_spot.rs",
"chars": 2068,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/kraken/mod.rs",
"chars": 570,
"preview": "pub(crate) mod kraken_futures;\npub(crate) mod kraken_spot;\n\nuse crate::error::Result;\nuse crypto_market_type::MarketType"
},
{
"path": "crypto-rest-client/src/exchanges/kucoin/kucoin_spot.rs",
"chars": 1512,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/kucoin/kucoin_swap.rs",
"chars": 1614,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/kucoin/mod.rs",
"chars": 1466,
"preview": "mod kucoin_spot;\nmod kucoin_swap;\n\npub use kucoin_spot::KuCoinSpotRestClient;\npub use kucoin_swap::KuCoinSwapRestClient;"
},
{
"path": "crypto-rest-client/src/exchanges/mexc/mexc_spot.rs",
"chars": 1444,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/mexc/mexc_swap.rs",
"chars": 1216,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/mexc/mod.rs",
"chars": 544,
"preview": "pub(crate) mod mexc_spot;\npub(crate) mod mexc_swap;\n\nuse crate::error::Result;\nuse crypto_market_type::MarketType;\n\npub("
},
{
"path": "crypto-rest-client/src/exchanges/mod.rs",
"chars": 475,
"preview": "#[macro_use]\nmod utils;\n\npub(super) mod binance;\npub(super) mod bitfinex;\npub(super) mod bitget;\npub(super) mod bithumb;"
},
{
"path": "crypto-rest-client/src/exchanges/okx.rs",
"chars": 3217,
"preview": "use super::utils::http_get;\nuse crate::error::Result;\nuse crypto_market_type::MarketType;\nuse serde_json::Value;\nuse std"
},
{
"path": "crypto-rest-client/src/exchanges/utils.rs",
"chars": 2952,
"preview": "use reqwest::{blocking::Response, header};\n\nuse crate::error::{Error, Result};\nuse std::collections::BTreeMap;\n\n// Retur"
},
{
"path": "crypto-rest-client/src/exchanges/zb/mod.rs",
"chars": 580,
"preview": "mod zb_spot;\nmod zb_swap;\n\npub use zb_spot::ZbSpotRestClient;\npub use zb_swap::ZbSwapRestClient;\n\nuse crate::error::Resu"
},
{
"path": "crypto-rest-client/src/exchanges/zb/zb_spot.rs",
"chars": 907,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/zb/zb_swap.rs",
"chars": 1170,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/zbg/mod.rs",
"chars": 954,
"preview": "mod zbg_spot;\nmod zbg_swap;\n\npub use zbg_spot::ZbgSpotRestClient;\npub use zbg_swap::ZbgSwapRestClient;\n\nuse crate::error"
},
{
"path": "crypto-rest-client/src/exchanges/zbg/zbg_spot.rs",
"chars": 953,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
},
{
"path": "crypto-rest-client/src/exchanges/zbg/zbg_swap.rs",
"chars": 1270,
"preview": "use super::super::utils::http_get;\nuse crate::error::Result;\nuse std::collections::BTreeMap;\n\nconst BASE_URL: &str = \"ht"
}
]
// ... and 106 more files (download for full content)
About this extraction
This page contains the full source code of the crypto-crawler/crypto-crawler-rs GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 306 files (926.4 KB), approximately 246.8k tokens, and a symbol index with 1969 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.