Thank you for helping improve ccxt.collector. This guide explains the project scope and the way we work so contributors can be effective and consistent.
- Purpose: Reimplement the exchanges available in ccxt/ccxt (C#) in this repository, aligned to our codebase and unified API.
- Focus on essential features only; avoid scope creep and unnecessary complexity.
- Keep exchanges organized by region under
src/exchanges/<region>/<exchange>/.
This project is a .NET library for real-time cryptocurrency market data collection via WebSocket across many exchanges, providing unified data models and optional technical indicators.
High-level architecture
Application → CCXT.Collector Library → Exchange WebSocket APIs
├── Callbacks (OnOrderbook, OnTrade, OnTicker, OnCandle)
├── Indicators (SMA, EMA, RSI, MACD, ...)
├── Data Transformation (Unified Models)
└── WebSocket Management (Connection, Subscriptions, Auth)
Project structure (key folders)
src/
├─ core/ # Abstractions (IWebSocketClient, WebSocketClientBase)
├─ models/ # Market (orderbook, ticker), Trading (account, orders)
├─ indicators/ # Trend, Momentum, Volatility, Volume, MarketStrength
├─ utilities/ # JsonExtension, TimeExtension, Statistics, CLogger
└─ exchanges/ # Exchanges by country (kr/, us/, cn/, ...)
Core components
- IWebSocketClient: identity, connect/disconnect, subscribe methods, and event callbacks.
- WebSocketClientBase: reconnection with exponential backoff; dynamic buffer; subscription tracking and restoration; thread-safe operations; optional batch subscriptions.
- IChannelObserver: observability interface for metrics injection (ChannelStatistics, ConnectionHealth).
- Unified models: SOrderBooks, STradeItem, STicker, SCandleItem, etc.
- Dependency Injection: AddCcxtCollector() extension methods for service registration.
- Do not add features that are not required by the standardized collector workflows.
- Avoid premature optimization; performance work should follow real measurements.
- Do not introduce breaking API changes without a documented migration.
We implement exchanges in the following order of priority:
- Included and maintained in ccxt/ccxt C# bindings.
- High user demand and market share (global liquidity, reliability).
- WebSocket support available or stable REST for core market data.
- Lower maintenance risk (clear docs, stable APIs, reasonable rate limits).
Examples that typically score high: Binance, OKX, Bybit, Bitget, Kraken, Coinbase, Bitfinex, Bitstamp. Regional priorities may elevate local leaders.
- The core contract is
IExchange(standardized API v1.1.6+). Implement its methods consistently. - If an exchange cannot fully implement the contract yet, throw
NotImplementedExceptionand mark the file header metadata accordingly. - Use the file header metadata block at the top of exchange implementations:
// == CCXT-COLLECTOR-META-BEGIN == // EXCHANGE: <name> // IMPLEMENTATION_STATUS: FULL | PARTIAL | SKELETON // PROGRESS_STATUS: DONE | WIP | TODO // MARKET_SCOPE: spot | futures | margin | ... // NOT_IMPLEMENTED_EXCEPTIONS: <count> // LAST_REVIEWED: <yyyy-mm-dd> // == CCXT-COLLECTOR-META-END ==
Follow this lightweight, repeatable loop:
- Select exchange using the prioritization policy above; confirm it exists under ccxt/ccxt C#.
- Create a minimal skeleton: constructor, identity (name/url), auth placeholders, and stubs with
NotImplementedExceptionfor non-essential parts. - Implement essential features only:
- Public market data: markets/symbols, tickers, trades, order book, candles.
- Mapping: convert raw API responses to standard ccxt.collector models with strict time/number parsing.
- Add tests: one happy path + one edge case (nulls/empty, rate limit/backoff path). Mark credentialed tests skippable if secrets are absent.
- Update documentation:
docs/TASK.mdstatus by region/exchange; add release note if user-visible. - Self-review with quality gates; open PR.
Set up the repository and run local builds/tests.
git clone https://github.com/YOUR_USERNAME/ccxt.collector.git
cd ccxt.collector
git remote add upstream https://github.com/odinsoft-lab/ccxt.collector.git
dotnet restore
dotnet build
dotnet testMinimal usage example (for ad-hoc local testing):
using CCXT.Collector.Exchanges;
var client = new BinanceWebSocketClient();
client.OnOrderbookReceived += (symbol, ob) => Console.WriteLine($"{symbol} bid: {ob.Bids[0]?.Price}");
await client.ConnectAsync();
await client.SubscribeOrderbookAsync("BTC/USDT");- Language policy: All Markdown must be English; every function/method must include an English comment (XML doc recommended) describing purpose, inputs, outputs, and error modes.
- XML documentation: All public members require XML docs. Prefer
<inheritdoc/>where the interface already documents the member; write explicit summaries for constructors, helpers, and any non-interface members. - Style: Follow existing code style; do not reformat unrelated files. Keep changes minimal and focused.
- Naming: Use
X<Exchange>for exchange classes, e.g.,XKraken, and setExchangeNameto the lowercase slug used in HTTP clients.
/// <summary>
/// Short description of what the method does.
/// </summary>
/// <param name="paramName">Meaning and units if applicable.</param>
/// <returns>What is returned, including nullability.</returns>
/// <exception cref="ExceptionType">When and why it is thrown.</exception>- Create
src/exchanges/<region>/<exchange>/X<Exchange>.csusing an existing skeleton as a template. - Fill in metadata header,
ExchangeName,ExchangeUrl, and authentication boilerplate (Encryptor, signature helpers). - Implement the standardized methods of
IExchange(market data, account, trading, funding). For incomplete parts, throwNotImplementedException. - Add English XML docs or
<inheritdoc/>for all public members. - Update documentation:
docs/EXCHANGES.mdanddocs/TASK.mdto reflect implemented/unimplemented status by region.- Add or update release notes in
docs/releases/if the change is user-visible.
- Add or update unit tests under
tests/for the new exchange (happy path + 1–2 edge cases).
Security is a first-class concern. Do not introduce insecure patterns.
- Credentials: Never hardcode or commit API keys. Prefer environment variables, local user-secrets, or a vault (Azure Key Vault, AWS Secrets Manager).
- Input validation: Validate symbols and external inputs; reject malformed payloads and unexpected types.
- Rate limiting/throttling: Respect exchange limits; add simple local throttles as needed.
- Logging: Do not log secrets; redact tokens/keys; lower verbosity for sensitive paths.
- Reviews: Call out security-impacting changes in PR descriptions.
Checklist
- Secure credential storage (env/vault/user-secrets)
- Validation for external data (symbols, message shapes)
- Throttling where applicable
- Sensitive logging redaction
- Regular dependency/runtime updates
- File:
docs/TASK.mdtracks implementation status by region and exchange. - Recommended format: a table with columns
Region | Exchange | Status(FULL/PARTIAL/TODO) | Notes. - Update the row whenever status changes; keep notes brief and actionable (e.g., "no WS for candles; REST only").
- Build with
dotnet build; run tests withdotnet test. - Do not introduce new build warnings. In particular, address CS1591 by adding XML docs or
<inheritdoc/>. - Keep public behavior backward compatible unless a release note calls out a change.
- Build: succeeds on all target frameworks with zero warnings.
- Tests: new/updated tests pass locally; avoid flakiness (no real network in unit tests).
- Docs: English-only; updated
docs/TASK.mdand release notes if user-visible. - Lint/Analyzers: documentation warnings (e.g., CS1591) resolved or intentionally suppressed with justification.
- You run git add/commit manually; do not automate commits or pushes.
- Write commit messages in English, in imperative mood (e.g., "Add Upbit order book snapshot mapper").
- Update
docs/TASK.mdanddocs/releases/x.y.z.mdwith any user-visible changes.
- One file per version:
docs/releases/x.y.z.md. - Use sections: Added, Changed, Fixed, Removed, Performance, Security, Migration.
- Keep entries concise and reproducible; add issue/PR numbers in parentheses when relevant.
- Standard models live in
src/models. - Exchange-specific or non-standard code lives in
src/exchanges/<region>/<exchange>. - Shared utilities in
src/utilities. - Tests in
testsmirror thesrctree.
- Code builds without warnings on all target frameworks.
- English XML comments for all new or changed functions.
- Tests added or updated; all tests pass locally.
- Docs updated:
docs/TASK.mdand release notes if applicable. - Exchange mapping updated if adding a new exchange.
- Use GitHub issues and PRs. Keep discussion in English for consistency.
This section consolidates publishing and deployment guidance. Prefer the repository scripts for common tasks.
Prerequisites
- .NET SDK installed
- NuGet API key available (environment variable or secure script)
- PowerShell available on Windows
Pre-upload checklist (generic)
- Bump version in
src/ccxt.collector.csproj(Version/AssemblyVersion/FileVersion) - Update PackageReleaseNotes with a concise summary
- Update docs: README (install line), TASK.md (if user-visible), release notes file
- Build Release and run tests locally
- Address warnings; documentation (CS1591) resolved
- Security checklist reviewed (no secrets, vaults configured for CI)
Scripts (preferred)
scripts/publish-nuget.ps1and.bat: build, test, pack, and publishscripts/unlist-nuget.ps1and.bat: unlist a versionscripts/nuget-config.ps1.example: template to manage the API key
Manual commands (alternative)
dotnet clean
dotnet restore
dotnet build -c Release
dotnet test tests/ccxt.tests.csproj -c Release
dotnet pack src/ccxt.collector.csproj -c Release -o ./nupkg
# Upload (skip-duplicate recommended for CI)
dotnet nuget push ./nupkg/CCXT.Collector.{VERSION}.nupkg \
--source https://api.nuget.org/v3/index.json \
--api-key $NUGET_API_KEY \
--skip-duplicatePost-upload tasks
- Verify package on NuGet.org
- Test installation in a clean sample project
- Create GitHub release tag and attach release notes
- Announce in appropriate channels
Package contents (verify)
- Sources from
src/ - README.md, LICENSE.md, package icon
- Target frameworks: netstandard2.0, netstandard2.1, net8.0, net9.0, net10.0
- Correct dependencies (Microsoft.Extensions.Configuration, System.Text.Json, etc.)
Security notes for releases
- Never commit API keys; keep
scripts/nuget-config.ps1untracked (use the example) - Prefer GitHub Secrets or a vault for CI/CD
- Rotate API keys periodically
These are operational examples for running the collector as an app/service. Adapt as needed; they are not required for library usage.
- Linux publish (dotnet publish), Supervisor unit example, and logrotate snippet
- Dockerfile and docker-compose usage
- Windows Service basics with
sc.exe - Cloud: Azure App Service, AWS Elastic Beanstalk, and a basic Kubernetes Deployment/Service manifest
Environment configuration example (appsettings.Production.json)
- Common keys: websocket retry/backoff, auto-start options, logging levels
Monitoring
- Health checks endpoint
- Optional integrations: Application Insights, Prometheus metrics
Troubleshooting quick tips
- Port in use: identify with netstat; stop conflicting process
- Linux permissions: executable bits and ownership
- Service won’t start: inspect logs, config, dependencies, firewall