mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-10 00:38:07 +00:00
Add Oxlint configuration and integrate linting commands
- Introduced a new `.oxlintrc.json` file to configure Oxlint for code quality checks. - Updated `package.json` to include linting scripts (`lint` and `lint:fix`) for easier code maintenance. - Enhanced documentation in `README` files to guide users on running Oxlint checks and applying fixes.
This commit is contained in:
@@ -155,7 +155,7 @@ function parseExchangeCommand(
|
||||
options: Record<string, string | boolean>,
|
||||
common: CommandCommonOptions & { help?: boolean }
|
||||
): ParsedCliCommand {
|
||||
assertAllowedOptions(options, new Set([...GLOBAL_OPTION_NAMES]));
|
||||
assertAllowedOptions(options, new Set(GLOBAL_OPTION_NAMES));
|
||||
if (action === "list") return { kind: "exchange-list", ...common };
|
||||
if (action === "capabilities") return { kind: "exchange-capabilities", ...common };
|
||||
throw new CommandParseError(`Unsupported exchange action '${action}'`);
|
||||
|
||||
@@ -543,7 +543,7 @@ export class AsterSpotRestClient {
|
||||
}
|
||||
try {
|
||||
return JSON.parse(text) as T;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
throw new Error(`[AsterSpotRestClient] 无法解析响应: ${text.slice(0, 200)}`);
|
||||
}
|
||||
}
|
||||
@@ -795,7 +795,7 @@ export class AsterRestClient {
|
||||
}
|
||||
try {
|
||||
return JSON.parse(text) as AsterFuturesExchangeInfo;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
throw new Error(`[AsterRestClient] 无法解析交易规则响应: ${text.slice(0, 200)}`);
|
||||
}
|
||||
}
|
||||
@@ -869,7 +869,7 @@ export class AsterRestClient {
|
||||
try {
|
||||
const payload = JSON.parse(text) as any[];
|
||||
return payload.map((entry) => fromRestKline(entry, interval, upper));
|
||||
} catch (error) {
|
||||
} catch {
|
||||
throw new Error(`[AsterRestClient] 无法解析K线响应: ${text.slice(0, 200)}`);
|
||||
}
|
||||
}
|
||||
@@ -899,7 +899,7 @@ export class AsterRestClient {
|
||||
const payload = JSON.parse(text) as any;
|
||||
// The response shape mirrors Binance: { symbol, markPrice, indexPrice, lastFundingRate, nextFundingTime, time }
|
||||
return payload;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
throw new Error(`[AsterRestClient] 无法解析资金费率响应: ${text.slice(0, 200)}`);
|
||||
}
|
||||
}
|
||||
@@ -942,7 +942,7 @@ export class AsterRestClient {
|
||||
}
|
||||
try {
|
||||
return JSON.parse(text) as T;
|
||||
} catch (error) {
|
||||
} catch {
|
||||
throw new Error(`[AsterRestClient] 无法解析响应: ${text.slice(0, 200)}`);
|
||||
}
|
||||
}
|
||||
@@ -1366,7 +1366,7 @@ export class AsterGateway {
|
||||
});
|
||||
}
|
||||
|
||||
async ensureInitialized(symbol: string): Promise<void> {
|
||||
async ensureInitialized(_symbol: string): Promise<void> {
|
||||
if (this.initialized) return;
|
||||
if (this.initializing) return this.initializing;
|
||||
this.initializing = (async () => {
|
||||
|
||||
@@ -7,7 +7,6 @@ import ccxt, {
|
||||
import NodeWebSocket from "ws";
|
||||
import { sign, utils as edUtils, hashes as edHashes } from "@noble/ed25519";
|
||||
import { sha512 } from "@noble/hashes/sha512";
|
||||
import { randomBytes } from "crypto";
|
||||
import type {
|
||||
AsterAccountSnapshot,
|
||||
AsterAccountPosition,
|
||||
@@ -137,17 +136,16 @@ export class BackpackGateway {
|
||||
}
|
||||
|
||||
private async doInitialize(symbol?: string): Promise<void> {
|
||||
try {
|
||||
await this.exchange.loadMarkets();
|
||||
const requested = (symbol ?? this.symbol).toUpperCase();
|
||||
const market = this.findMarket(requested);
|
||||
if (!market) {
|
||||
throw new Error(`Symbol ${requested} not found in Backpack markets`);
|
||||
}
|
||||
this.market = market;
|
||||
this.marketSymbol = market.symbol;
|
||||
this.marketId = market.id;
|
||||
this.isContractMarket = Boolean(market.contract);
|
||||
await this.exchange.loadMarkets();
|
||||
const requested = (symbol ?? this.symbol).toUpperCase();
|
||||
const market = this.findMarket(requested);
|
||||
if (!market) {
|
||||
throw new Error(`Symbol ${requested} not found in Backpack markets`);
|
||||
}
|
||||
this.market = market;
|
||||
this.marketSymbol = market.symbol;
|
||||
this.marketId = market.id;
|
||||
this.isContractMarket = Boolean(market.contract);
|
||||
if (process.env.BACKPACK_DEBUG === "1") {
|
||||
console.debug("[BackpackGateway] marketInfo", {
|
||||
userSymbol: this.symbol,
|
||||
@@ -155,10 +153,7 @@ export class BackpackGateway {
|
||||
marketId: this.marketId,
|
||||
});
|
||||
}
|
||||
this.initialized = true;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
private findMarket(requested: string): any | null {
|
||||
@@ -774,7 +769,7 @@ export class BackpackGateway {
|
||||
void this.resubscribeAllTopics();
|
||||
};
|
||||
|
||||
private handleWsClose = (event: any): void => {
|
||||
private handleWsClose = (_event: any): void => {
|
||||
if (this.wsCleanup) {
|
||||
try {
|
||||
this.wsCleanup();
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import ccxt, {
|
||||
type Balances,
|
||||
type Order as CcxtOrder,
|
||||
type OrderBook as CcxtOrderBook,
|
||||
type OHLCV as CcxtOhlcv,
|
||||
type Ticker as CcxtTicker,
|
||||
} from "ccxt";
|
||||
import axios from "axios";
|
||||
import { createHash } from "crypto";
|
||||
|
||||
@@ -1161,7 +1161,7 @@ function mapTicker(response: IApiTickerResponse, symbol: string): AsterTicker |
|
||||
};
|
||||
}
|
||||
|
||||
function mapKlines(response: IApiCandlestickResponse, symbol: string): AsterKline[] {
|
||||
function mapKlines(response: IApiCandlestickResponse, _symbol: string): AsterKline[] {
|
||||
return (response.result ?? []).reverse().map((entry) => ({
|
||||
openTime: nsToMs(entry.open_time ?? Date.now() * ONE_SECOND_IN_NANOSECONDS),
|
||||
closeTime: nsToMs(entry.close_time ?? Date.now() * ONE_SECOND_IN_NANOSECONDS),
|
||||
|
||||
@@ -16,12 +16,10 @@ import type {
|
||||
AsterTicker,
|
||||
CreateOrderParams,
|
||||
} from "../types";
|
||||
import { extractMessage } from "../../utils/errors";
|
||||
import type { OrderSide, OrderType } from "../types";
|
||||
import { LighterHttpClient } from "./http-client";
|
||||
import { HttpNonceManager } from "./nonce-manager";
|
||||
import { LighterSigner, type CreateOrderSignParams } from "./signer";
|
||||
import { bytesToHex } from "./bytes";
|
||||
import type {
|
||||
LighterAccountDetails,
|
||||
LighterAccountAsset,
|
||||
@@ -39,7 +37,6 @@ import {
|
||||
LIGHTER_HOSTS,
|
||||
LIGHTER_ORDER_TYPE,
|
||||
LIGHTER_TIME_IN_FORCE,
|
||||
DEFAULT_ORDER_EXPIRY_PLACEHOLDER,
|
||||
IMMEDIATE_OR_CANCEL_EXPIRY_PLACEHOLDER,
|
||||
type LighterEnvironment,
|
||||
} from "./constants";
|
||||
@@ -2210,7 +2207,7 @@ function extractJsonRequestId(message: any): string | null {
|
||||
function tryParseTxInfo(value: string): unknown {
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
} catch (_) {
|
||||
} catch {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ function computeExecutedQty(order: LighterOrder): string {
|
||||
if (Number.isFinite(initial) && Number.isFinite(remaining)) {
|
||||
return (initial - remaining).toString();
|
||||
}
|
||||
} catch (_) {
|
||||
} catch {
|
||||
// fall through
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1684,7 +1684,7 @@ export class NadoGateway {
|
||||
try {
|
||||
const text = typeof data === "string" ? data : data.toString("utf8");
|
||||
message = JSON.parse(text);
|
||||
} catch (_error) {
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
if (!message || typeof message !== "object") return;
|
||||
|
||||
@@ -32,7 +32,7 @@ function loadCcxtPro(): any | null {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const mod = require("ccxt.pro");
|
||||
return mod?.default ?? mod;
|
||||
} catch (_error) {
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -571,7 +571,6 @@ export class ParadexGateway {
|
||||
const market = typeof (this.exchange as any).market === "function"
|
||||
? (this.exchange as any).market(symbol)
|
||||
: (this.exchange.markets ?? {})[symbol];
|
||||
const precisionDigits = Number((market?.precision?.amount ?? market?.amountPrecision));
|
||||
const limitMin = Number(market?.limits?.amount?.min);
|
||||
// Only trust explicit exchange min limit; do NOT infer 1 from precision=0
|
||||
const minAmount = Number.isFinite(limitMin) && limitMin > 0 ? limitMin : undefined;
|
||||
@@ -593,7 +592,7 @@ export class ParadexGateway {
|
||||
if (typeof (this.exchange as any).amountToPrecision === "function" && Number.isFinite(Number(amount))) {
|
||||
amount = Number((this.exchange as any).amountToPrecision(symbol, amount));
|
||||
}
|
||||
} catch (_normalizeError) {
|
||||
} catch {
|
||||
// Swallow precision normalization errors and let exchange validation surface if any
|
||||
}
|
||||
|
||||
@@ -944,7 +943,7 @@ export class ParadexGateway {
|
||||
}
|
||||
}
|
||||
|
||||
private updateOrdersFromRemote(open: CcxtOrder[], closed: CcxtOrder[]): void {
|
||||
private updateOrdersFromRemote(open: CcxtOrder[], _closed: CcxtOrder[]): void {
|
||||
const nextOpen = new Map<string, AsterOrder>();
|
||||
|
||||
for (const order of open) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import { App } from "./ui/App";
|
||||
import { setupGlobalErrorHandlers } from "./runtime-errors";
|
||||
import { parseCliArgs, printCliHelp } from "./cli/args";
|
||||
import { startStrategy } from "./cli/strategy-runner";
|
||||
import { resolveExchangeId } from "./exchanges/create-adapter";
|
||||
import { CommandParseError, parseCommandArgv, printCommandHelp } from "./cli/command-parser";
|
||||
import { executeCliCommand, renderCommandPayload } from "./cli/command-executor";
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ export class BasisArbEngine {
|
||||
if (!Number.isFinite(wallet) || !Number.isFinite(available)) continue;
|
||||
if (Math.abs(wallet) === 0 && Math.abs(available) === 0) continue;
|
||||
|
||||
const isTaggedFuturesAsset = /0$/.test(name);
|
||||
const isTaggedFuturesAsset = name.endsWith("0");
|
||||
if (isTaggedFuturesAsset) {
|
||||
futuresBalances.push({ asset: name.replace(/0$/, ""), wallet, available });
|
||||
continue;
|
||||
|
||||
@@ -461,7 +461,7 @@ export class GridEngine {
|
||||
return false;
|
||||
}
|
||||
|
||||
private async haltGrid(price: number): Promise<void> {
|
||||
private async haltGrid(_price: number): Promise<void> {
|
||||
if (!this.running) return;
|
||||
const reason = this.stopReason ?? "触发网格止损";
|
||||
this.log("warn", `${reason},开始执行平仓与撤单`);
|
||||
|
||||
@@ -3,7 +3,6 @@ import type { ExchangeAdapter } from "../exchanges/adapter";
|
||||
import type {
|
||||
AsterAccountSnapshot,
|
||||
AsterDepth,
|
||||
AsterKline,
|
||||
AsterOrder,
|
||||
AsterTicker,
|
||||
} from "../exchanges/types";
|
||||
|
||||
@@ -422,7 +422,7 @@ export class SwingEngine {
|
||||
: position.entryPrice * (1 + Math.max(0, this.config.stopLossPct));
|
||||
|
||||
const tick = Math.max(1e-9, this.config.priceTick);
|
||||
const lastPrice = referencePrice ?? Number(this.tickerSnapshot?.lastPrice) ?? null;
|
||||
const lastPrice = referencePrice;
|
||||
|
||||
// Kill-switch (always-on).
|
||||
const triggerKill =
|
||||
@@ -621,4 +621,3 @@ export class SwingEngine {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -386,7 +386,7 @@ export class TrendEngine {
|
||||
private async enforceRateLimitStop(): Promise<void> {
|
||||
const position = getPosition(this.accountSnapshot, this.config.symbol);
|
||||
if (Math.abs(position.positionAmt) < 1e-5) return;
|
||||
const price = this.getReferencePrice() ?? Number(this.tickerSnapshot?.lastPrice) ?? this.lastPrice;
|
||||
const price = this.getReferencePrice();
|
||||
if (!Number.isFinite(price) || price == null) return;
|
||||
const result = await this.handlePositionManagement(position, Number(price));
|
||||
if (result.closed) {
|
||||
|
||||
Reference in New Issue
Block a user