Feat/support binance (#22)

* add docs

* Add Binance exchange support

- Updated the environment configuration to include Binance as a selectable exchange option.
- Enhanced the README documentation to reflect the addition of Binance.
- Implemented the Binance exchange adapter and integrated it into the existing exchange framework.
- Modified the basis arbitrage strategy to support Binance alongside existing exchanges.
- Added tests to ensure proper functionality and integration of Binance within the trading system.

* Enhance README with detailed Binance exchange configuration

- Added comprehensive instructions for setting up Binance as an exchange option.
- Included environment variable specifications for API keys, market types, and trading symbols.
- Provided examples for both perpetual and spot trading strategies.
- Clarified the use of WebSocket and REST for the Binance adapter.

* Enhance exchange support and testing framework

- Added a new test suite for exchange contracts to ensure consistency and functionality across supported exchanges.
- Refactored exchange ID handling to utilize a centralized list of supported exchanges, improving maintainability.
- Updated CLI argument parsing and help documentation to reflect the new exchange structure.
- Introduced utility functions for validating supported exchanges and their display names.
- Enhanced the BasisApp and strategy runner to leverage the new exchange validation logic.
- Added a new test command for running exchange-related tests.

* Refactor exchange contract tests and update CLI commands

- Removed the trailing supported exchanges set and simplified the logic for trailing stop support in the exchange contract tests.
- Updated the test command for exchange contracts to exclude unnecessary tests, streamlining the testing process.
- Enhanced test descriptions for clarity and improved understanding of the functionality being tested.
This commit is contained in:
Disney
2026-02-27 11:37:44 +08:00
committed by GitHub
parent 422ee6f465
commit d6399b92aa
588 changed files with 96879 additions and 106 deletions
+72 -40
View File
@@ -6,6 +6,25 @@ import { BackpackExchangeAdapter, type BackpackCredentials } from "./backpack/ad
import { ParadexExchangeAdapter, type ParadexCredentials } from "./paradex/adapter";
import { NadoExchangeAdapter, type NadoCredentials } from "./nado/adapter";
import { StandxExchangeAdapter, type StandxCredentials } from "./standx/adapter";
import { BinanceExchangeAdapter, type BinanceCredentials } from "./binance/adapter";
export const SUPPORTED_EXCHANGE_IDS = [
"aster",
"grvt",
"lighter",
"backpack",
"paradex",
"nado",
"standx",
"binance",
] as const;
export const BASIS_SUPPORTED_EXCHANGE_IDS = [
"aster",
"nado",
"standx",
"binance",
] as const;
export interface ExchangeFactoryOptions {
symbol: string;
@@ -17,60 +36,73 @@ export interface ExchangeFactoryOptions {
paradex?: ParadexCredentials;
nado?: NadoCredentials;
standx?: StandxCredentials;
binance?: BinanceCredentials;
}
export type SupportedExchangeId =
| "aster"
| "grvt"
| "lighter"
| "backpack"
| "paradex"
| "nado"
| "standx";
export type SupportedExchangeId = (typeof SUPPORTED_EXCHANGE_IDS)[number];
export type BasisSupportedExchangeId = (typeof BASIS_SUPPORTED_EXCHANGE_IDS)[number];
const EXCHANGE_DISPLAY_NAME: Record<SupportedExchangeId, string> = {
aster: "AsterDex",
grvt: "GRVT",
lighter: "Lighter",
backpack: "Backpack",
paradex: "Paradex",
nado: "Nado",
standx: "StandX",
binance: "Binance",
};
const EXCHANGE_ALIAS_MAP: Record<string, SupportedExchangeId> = {
aster: "aster",
grvt: "grvt",
lighter: "lighter",
backpack: "backpack",
paradex: "paradex",
nado: "nado",
standx: "standx",
binance: "binance",
bnb: "binance",
};
export function isSupportedExchangeId(value: string): value is SupportedExchangeId {
return SUPPORTED_EXCHANGE_IDS.includes(value as SupportedExchangeId);
}
export function isBasisSupportedExchangeId(value: string): value is BasisSupportedExchangeId {
return BASIS_SUPPORTED_EXCHANGE_IDS.includes(value as BasisSupportedExchangeId);
}
export function resolveExchangeId(value?: string | null): SupportedExchangeId {
const fallback = (value ?? process.env.EXCHANGE ?? process.env.TRADE_EXCHANGE ?? "aster")
.toString()
.trim()
.toLowerCase();
if (fallback === "grvt") return "grvt";
if (fallback === "lighter") return "lighter";
if (fallback === "backpack") return "backpack";
if (fallback === "paradex") return "paradex";
if (fallback === "nado") return "nado";
if (fallback === "standx") return "standx";
return "aster";
return EXCHANGE_ALIAS_MAP[fallback] ?? "aster";
}
export function getExchangeDisplayName(id: SupportedExchangeId): string {
if (id === "grvt") return "GRVT";
if (id === "lighter") return "Lighter";
if (id === "backpack") return "Backpack";
if (id === "paradex") return "Paradex";
if (id === "nado") return "Nado";
if (id === "standx") return "StandX";
return "AsterDex";
return EXCHANGE_DISPLAY_NAME[id];
}
export function createExchangeAdapter(options: ExchangeFactoryOptions): ExchangeAdapter {
const id = resolveExchangeId(options.exchange);
if (id === "grvt") {
return new GrvtExchangeAdapter({ ...options.grvt, symbol: options.symbol });
switch (id) {
case "aster":
return new AsterExchangeAdapter({ ...options.aster, symbol: options.symbol });
case "grvt":
return new GrvtExchangeAdapter({ ...options.grvt, symbol: options.symbol });
case "lighter":
return new LighterExchangeAdapter({ ...options.lighter, displaySymbol: options.symbol });
case "backpack":
return new BackpackExchangeAdapter({ ...options.backpack, symbol: options.symbol });
case "paradex":
return new ParadexExchangeAdapter({ ...options.paradex, symbol: options.symbol });
case "nado":
return new NadoExchangeAdapter({ ...options.nado, symbol: options.symbol });
case "standx":
return new StandxExchangeAdapter({ ...options.standx, symbol: options.symbol });
case "binance":
return new BinanceExchangeAdapter({ ...options.binance, symbol: options.symbol });
}
if (id === "lighter") {
return new LighterExchangeAdapter({ ...options.lighter, displaySymbol: options.symbol });
}
if (id === "backpack") {
return new BackpackExchangeAdapter({ ...options.backpack, symbol: options.symbol });
}
if (id === "paradex") {
return new ParadexExchangeAdapter({ ...options.paradex, symbol: options.symbol });
}
if (id === "nado") {
return new NadoExchangeAdapter({ ...options.nado, symbol: options.symbol });
}
if (id === "standx") {
return new StandxExchangeAdapter({ ...options.standx, symbol: options.symbol });
}
return new AsterExchangeAdapter({ ...options.aster, symbol: options.symbol });
}