feat: add Guardian strategy to manage existing positions with stop loss and trailing stop functionality

This commit is contained in:
discountry
2025-11-09 14:09:54 +08:00
parent e94cf1bda2
commit 1baee3a207
8 changed files with 965 additions and 23 deletions
+10 -3
View File
@@ -1,4 +1,4 @@
export type StrategyId = "trend" | "maker" | "offset-maker" | "basis" | "grid";
export type StrategyId = "trend" | "guardian" | "maker" | "offset-maker" | "basis" | "grid";
export interface CliOptions {
strategy?: StrategyId;
@@ -7,7 +7,14 @@ export interface CliOptions {
exchange?: "aster" | "grvt" | "lighter" | "backpack";
}
const STRATEGY_VALUES = new Set<StrategyId>(["trend", "maker", "offset-maker", "basis", "grid"]);
const STRATEGY_VALUES = new Set<StrategyId>([
"trend",
"guardian",
"maker",
"offset-maker",
"basis",
"grid",
]);
export function parseCliArgs(argv: string[] = process.argv.slice(2)): CliOptions {
const options: CliOptions = { silent: false, help: false };
@@ -77,7 +84,7 @@ function assignExchange(options: CliOptions, raw: string): void {
export function printCliHelp(): void {
// eslint-disable-next-line no-console
console.log(`Usage: bun run index.ts [--strategy <trend|maker|offset-maker|basis|grid>] [--exchange <aster|grvt|lighter|backpack>] [--silent]\n\n` +
console.log(`Usage: bun run index.ts [--strategy <trend|guardian|maker|offset-maker|basis|grid>] [--exchange <aster|grvt|lighter|backpack>] [--silent]\n\n` +
`Options:\n` +
` --strategy, -s Automatically start the specified strategy without the interactive menu.\n` +
` Aliases: offset, offset-maker for the offset maker engine.\n` +
+22 -1
View File
@@ -5,6 +5,7 @@ import { buildAdapterFromEnv } from "../exchanges/resolve-from-env";
import { MakerEngine, type MakerEngineSnapshot } from "../strategy/maker-engine";
import { OffsetMakerEngine, type OffsetMakerEngineSnapshot } from "../strategy/offset-maker-engine";
import { TrendEngine, type TrendEngineSnapshot } from "../strategy/trend-engine";
import { GuardianEngine, type GuardianEngineSnapshot } from "../strategy/guardian-engine";
import { BasisArbEngine, type BasisArbSnapshot } from "../strategy/basis-arb-engine";
import { GridEngine, type GridEngineSnapshot } from "../strategy/grid-engine";
import { extractMessage } from "../utils/errors";
@@ -18,6 +19,7 @@ type StrategyRunner = (options: RunnerOptions) => Promise<void>;
export const STRATEGY_LABELS: Record<StrategyId, string> = {
trend: "Trend Following",
guardian: "Guardian",
maker: "Maker",
"offset-maker": "Offset Maker",
basis: "Basis Arbitrage",
@@ -46,6 +48,19 @@ const STRATEGY_FACTORIES: Record<StrategyId, StrategyRunner> = {
offUpdate: (emitter) => engine.off("update", emitter),
});
},
guardian: async (opts) => {
const config = tradingConfig;
const adapter = createAdapterOrThrow(config.symbol);
const engine = new GuardianEngine(config, adapter);
await runEngine({
engine,
strategy: "guardian",
silent: opts.silent,
getSnapshot: () => engine.getSnapshot(),
onUpdate: (emitter) => engine.on("update", emitter),
offUpdate: (emitter) => engine.off("update", emitter),
});
},
maker: async (opts) => {
const config = makerConfig;
const adapter = createAdapterOrThrow(config.symbol);
@@ -116,7 +131,13 @@ interface EngineHarness<TSnapshot> {
}
async function runEngine<
TSnapshot extends TrendEngineSnapshot | MakerEngineSnapshot | OffsetMakerEngineSnapshot | BasisArbSnapshot | GridEngineSnapshot
TSnapshot extends
| TrendEngineSnapshot
| GuardianEngineSnapshot
| MakerEngineSnapshot
| OffsetMakerEngineSnapshot
| BasisArbSnapshot
| GridEngineSnapshot
>(
harness: EngineHarness<TSnapshot>
): Promise<void> {