@continuumdao/continuum-node-sdk 1.3.30 → 1.3.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-host-catalog.json +7 -0
- package/dist/core/chart/analysis/analysis-agent-view.d.ts.map +1 -1
- package/dist/core/chart/analysis/analysis-agent-view.js +48 -7
- package/dist/core/chart/analysis/analysis-agent-view.js.map +1 -1
- package/dist/core/chart/analysis/analysis-catalog.d.ts +19 -13
- package/dist/core/chart/analysis/analysis-catalog.d.ts.map +1 -1
- package/dist/core/chart/analysis/analysis-catalog.js +132 -106
- package/dist/core/chart/analysis/analysis-catalog.js.map +1 -1
- package/dist/core/chart/analysis/elliott-wave-drawings-tools.d.ts +31 -0
- package/dist/core/chart/analysis/elliott-wave-drawings-tools.d.ts.map +1 -0
- package/dist/core/chart/analysis/elliott-wave-drawings-tools.js +301 -0
- package/dist/core/chart/analysis/elliott-wave-drawings-tools.js.map +1 -0
- package/dist/core/chart/analysis/elliott-waves-analyze-tools.d.ts +161 -0
- package/dist/core/chart/analysis/elliott-waves-analyze-tools.d.ts.map +1 -0
- package/dist/core/chart/analysis/elliott-waves-analyze-tools.js +139 -0
- package/dist/core/chart/analysis/elliott-waves-analyze-tools.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/build-trade-uniswap-limit.d.ts +10 -0
- package/dist/core/chart/analysis/trade-setups/build-trade-uniswap-limit.d.ts.map +1 -0
- package/dist/core/chart/analysis/trade-setups/build-trade-uniswap-limit.js +123 -0
- package/dist/core/chart/analysis/trade-setups/build-trade-uniswap-limit.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/build-trade.d.ts +29 -1
- package/dist/core/chart/analysis/trade-setups/build-trade.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/build-trade.js +267 -8
- package/dist/core/chart/analysis/trade-setups/build-trade.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/elliott-waves-trade-setup.d.ts +50 -0
- package/dist/core/chart/analysis/trade-setups/elliott-waves-trade-setup.d.ts.map +1 -0
- package/dist/core/chart/analysis/trade-setups/elliott-waves-trade-setup.js +116 -0
- package/dist/core/chart/analysis/trade-setups/elliott-waves-trade-setup.js.map +1 -0
- package/dist/core/chart/analysis/trade-setups/shared.d.ts +1 -1
- package/dist/core/chart/analysis/trade-setups/shared.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/shared.js +2 -0
- package/dist/core/chart/analysis/trade-setups/shared.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-desk-defaults.d.ts +13 -1
- package/dist/core/chart/analysis/trade-setups/trade-desk-defaults.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-desk-defaults.js +11 -0
- package/dist/core/chart/analysis/trade-setups/trade-desk-defaults.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-idea-list.d.ts +2 -0
- package/dist/core/chart/analysis/trade-setups/trade-idea-list.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-idea-list.js +38 -3
- package/dist/core/chart/analysis/trade-setups/trade-idea-list.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-idea.d.ts +4 -0
- package/dist/core/chart/analysis/trade-setups/trade-idea.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-idea.js +4 -0
- package/dist/core/chart/analysis/trade-setups/trade-idea.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-purpose-format.d.ts +2 -0
- package/dist/core/chart/analysis/trade-setups/trade-purpose-format.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-purpose-format.js +6 -0
- package/dist/core/chart/analysis/trade-setups/trade-purpose-format.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-setup-selection.d.ts +8 -1
- package/dist/core/chart/analysis/trade-setups/trade-setup-selection.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trade-setup-selection.js +13 -0
- package/dist/core/chart/analysis/trade-setups/trade-setup-selection.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trend-structure-trade-setup.d.ts +20 -0
- package/dist/core/chart/analysis/trade-setups/trend-structure-trade-setup.d.ts.map +1 -1
- package/dist/core/chart/analysis/trade-setups/trend-structure-trade-setup.js +54 -0
- package/dist/core/chart/analysis/trade-setups/trend-structure-trade-setup.js.map +1 -1
- package/dist/core/chart/analysis/trade-setups/uniswap-tpsl-monitor.d.ts +41 -0
- package/dist/core/chart/analysis/trade-setups/uniswap-tpsl-monitor.d.ts.map +1 -0
- package/dist/core/chart/analysis/trade-setups/uniswap-tpsl-monitor.js +80 -0
- package/dist/core/chart/analysis/trade-setups/uniswap-tpsl-monitor.js.map +1 -0
- package/dist/core/chart/fetch-agent-view.d.ts +17 -0
- package/dist/core/chart/fetch-agent-view.d.ts.map +1 -0
- package/dist/core/chart/fetch-agent-view.js +39 -0
- package/dist/core/chart/fetch-agent-view.js.map +1 -0
- package/dist/core/chart/live/binding-extract.d.ts.map +1 -1
- package/dist/core/chart/live/binding-extract.js +34 -2
- package/dist/core/chart/live/binding-extract.js.map +1 -1
- package/dist/core/chart/live/fetch-tick.d.ts.map +1 -1
- package/dist/core/chart/live/fetch-tick.js +25 -1
- package/dist/core/chart/live/fetch-tick.js.map +1 -1
- package/dist/core/chart/live/index.d.ts +1 -1
- package/dist/core/chart/live/index.d.ts.map +1 -1
- package/dist/core/chart/live/index.js +1 -1
- package/dist/core/chart/live/index.js.map +1 -1
- package/dist/core/chart/live/schemas.d.ts +1 -0
- package/dist/core/chart/live/schemas.d.ts.map +1 -1
- package/dist/core/chart/live/schemas.js +1 -0
- package/dist/core/chart/live/schemas.js.map +1 -1
- package/dist/core/chart/overlay-schemas.d.ts +241 -0
- package/dist/core/chart/overlay-schemas.d.ts.map +1 -1
- package/dist/core/chart/overlay-schemas.js +63 -0
- package/dist/core/chart/overlay-schemas.js.map +1 -1
- package/dist/core/chart/overlays.d.ts.map +1 -1
- package/dist/core/chart/overlays.js +72 -1
- package/dist/core/chart/overlays.js.map +1 -1
- package/dist/core/chart/prepare-from-rows.d.ts +60 -0
- package/dist/core/chart/prepare-from-rows.d.ts.map +1 -1
- package/dist/core/chart/schemas.d.ts +240 -0
- package/dist/core/chart/schemas.d.ts.map +1 -1
- package/dist/core/coinmarketcap/schemas.d.ts +2 -2
- package/dist/core/elliott-waves/analyze.d.ts +38 -0
- package/dist/core/elliott-waves/analyze.d.ts.map +1 -0
- package/dist/core/elliott-waves/analyze.js +276 -0
- package/dist/core/elliott-waves/analyze.js.map +1 -0
- package/dist/core/elliott-waves/constants.d.ts +24 -0
- package/dist/core/elliott-waves/constants.d.ts.map +1 -0
- package/dist/core/elliott-waves/constants.js +24 -0
- package/dist/core/elliott-waves/constants.js.map +1 -0
- package/dist/core/elliott-waves/data-requirements.d.ts +22 -0
- package/dist/core/elliott-waves/data-requirements.d.ts.map +1 -0
- package/dist/core/elliott-waves/data-requirements.js +105 -0
- package/dist/core/elliott-waves/data-requirements.js.map +1 -0
- package/dist/core/elliott-waves/fibonacci-projector.d.ts +7 -0
- package/dist/core/elliott-waves/fibonacci-projector.d.ts.map +1 -0
- package/dist/core/elliott-waves/fibonacci-projector.js +20 -0
- package/dist/core/elliott-waves/fibonacci-projector.js.map +1 -0
- package/dist/core/elliott-waves/impulse-detector.d.ts +11 -0
- package/dist/core/elliott-waves/impulse-detector.d.ts.map +1 -0
- package/dist/core/elliott-waves/impulse-detector.js +294 -0
- package/dist/core/elliott-waves/impulse-detector.js.map +1 -0
- package/dist/core/elliott-waves/index.d.ts +10 -0
- package/dist/core/elliott-waves/index.d.ts.map +1 -0
- package/dist/core/elliott-waves/index.js +10 -0
- package/dist/core/elliott-waves/index.js.map +1 -0
- package/dist/core/elliott-waves/pivot-scanner.d.ts +40 -0
- package/dist/core/elliott-waves/pivot-scanner.d.ts.map +1 -0
- package/dist/core/elliott-waves/pivot-scanner.js +121 -0
- package/dist/core/elliott-waves/pivot-scanner.js.map +1 -0
- package/dist/core/elliott-waves/projection-builder.d.ts +32 -0
- package/dist/core/elliott-waves/projection-builder.d.ts.map +1 -0
- package/dist/core/elliott-waves/projection-builder.js +153 -0
- package/dist/core/elliott-waves/projection-builder.js.map +1 -0
- package/dist/core/elliott-waves/types.d.ts +117 -0
- package/dist/core/elliott-waves/types.d.ts.map +1 -0
- package/dist/core/elliott-waves/types.js +6 -0
- package/dist/core/elliott-waves/types.js.map +1 -0
- package/dist/core/elliott-waves/wave-labeler.d.ts +34 -0
- package/dist/core/elliott-waves/wave-labeler.d.ts.map +1 -0
- package/dist/core/elliott-waves/wave-labeler.js +95 -0
- package/dist/core/elliott-waves/wave-labeler.js.map +1 -0
- package/dist/core/elliott-waves/wave-math.d.ts +10 -0
- package/dist/core/elliott-waves/wave-math.d.ts.map +1 -0
- package/dist/core/elliott-waves/wave-math.js +61 -0
- package/dist/core/elliott-waves/wave-math.js.map +1 -0
- package/dist/core/mpc/broadcast-sign-result.d.ts +1 -0
- package/dist/core/mpc/broadcast-sign-result.d.ts.map +1 -1
- package/dist/core/mpc/broadcast-sign-result.js +129 -0
- package/dist/core/mpc/broadcast-sign-result.js.map +1 -1
- package/dist/core/mpc/deliver-arcus-exchange.d.ts +17 -0
- package/dist/core/mpc/deliver-arcus-exchange.d.ts.map +1 -0
- package/dist/core/mpc/deliver-arcus-exchange.js +380 -0
- package/dist/core/mpc/deliver-arcus-exchange.js.map +1 -0
- package/dist/core/mpc/deliver-hyperliquid-exchange.d.ts +13 -0
- package/dist/core/mpc/deliver-hyperliquid-exchange.d.ts.map +1 -0
- package/dist/core/mpc/deliver-hyperliquid-exchange.js +93 -0
- package/dist/core/mpc/deliver-hyperliquid-exchange.js.map +1 -0
- package/dist/core/mpc/deliver-personal-sign.d.ts +13 -0
- package/dist/core/mpc/deliver-personal-sign.d.ts.map +1 -0
- package/dist/core/mpc/deliver-personal-sign.js +17 -0
- package/dist/core/mpc/deliver-personal-sign.js.map +1 -0
- package/dist/core/mpc/deliver-uniswapx-limit-order.d.ts +6 -0
- package/dist/core/mpc/deliver-uniswapx-limit-order.d.ts.map +1 -0
- package/dist/core/mpc/deliver-uniswapx-limit-order.js +59 -0
- package/dist/core/mpc/deliver-uniswapx-limit-order.js.map +1 -0
- package/dist/core/mpc/eip712-sign-request.d.ts +8 -0
- package/dist/core/mpc/eip712-sign-request.d.ts.map +1 -0
- package/dist/core/mpc/eip712-sign-request.js +65 -0
- package/dist/core/mpc/eip712-sign-request.js.map +1 -0
- package/dist/core/mpc/trigger-sign-result.d.ts.map +1 -1
- package/dist/core/mpc/trigger-sign-result.js +15 -1
- package/dist/core/mpc/trigger-sign-result.js.map +1 -1
- package/dist/mcp/agent-host-catalog.d.ts +1 -1
- package/dist/mcp/agent-host-catalog.d.ts.map +1 -1
- package/dist/mcp/agent-host-catalog.js +2 -1
- package/dist/mcp/agent-host-catalog.js.map +1 -1
- package/dist/mcp/chart.d.ts.map +1 -1
- package/dist/mcp/chart.js +33 -4
- package/dist/mcp/chart.js.map +1 -1
- package/dist/mcp/deferred/tool-group-map.d.ts.map +1 -1
- package/dist/mcp/deferred/tool-group-map.js +7 -0
- package/dist/mcp/deferred/tool-group-map.js.map +1 -1
- package/dist/mcp/defi/bitquery-api-key.d.ts +16 -0
- package/dist/mcp/defi/bitquery-api-key.d.ts.map +1 -0
- package/dist/mcp/defi/bitquery-api-key.js +86 -0
- package/dist/mcp/defi/bitquery-api-key.js.map +1 -0
- package/dist/mcp/defi/catalog-adapter.d.ts +3 -2
- package/dist/mcp/defi/catalog-adapter.d.ts.map +1 -1
- package/dist/mcp/defi/catalog-adapter.js +7 -2
- package/dist/mcp/defi/catalog-adapter.js.map +1 -1
- package/dist/mcp/defi/defi-protocol-fetch-meta.d.ts.map +1 -1
- package/dist/mcp/defi/defi-protocol-fetch-meta.js +8 -4
- package/dist/mcp/defi/defi-protocol-fetch-meta.js.map +1 -1
- package/dist/mcp/defi/eip712-multisign.d.ts +26 -0
- package/dist/mcp/defi/eip712-multisign.d.ts.map +1 -0
- package/dist/mcp/defi/eip712-multisign.js +74 -0
- package/dist/mcp/defi/eip712-multisign.js.map +1 -0
- package/dist/mcp/defi/handler.d.ts.map +1 -1
- package/dist/mcp/defi/handler.js +46 -29
- package/dist/mcp/defi/handler.js.map +1 -1
- package/dist/mcp/defi/ohlcv-chart-workflow.d.ts +4 -2
- package/dist/mcp/defi/ohlcv-chart-workflow.d.ts.map +1 -1
- package/dist/mcp/defi/ohlcv-chart-workflow.js +20 -8
- package/dist/mcp/defi/ohlcv-chart-workflow.js.map +1 -1
- package/dist/mcp/defi/register-protocol-tools.d.ts.map +1 -1
- package/dist/mcp/defi/register-protocol-tools.js +36 -5
- package/dist/mcp/defi/register-protocol-tools.js.map +1 -1
- package/dist/mcp/defi/tool-schemas.d.ts +1 -3
- package/dist/mcp/defi/tool-schemas.d.ts.map +1 -1
- package/dist/mcp/defi/uniswap-api-key.d.ts.map +1 -1
- package/dist/mcp/defi/uniswap-api-key.js +3 -0
- package/dist/mcp/defi/uniswap-api-key.js.map +1 -1
- package/dist/mcp/defi/uniswap-limit-order-input.d.ts +10 -0
- package/dist/mcp/defi/uniswap-limit-order-input.d.ts.map +1 -0
- package/dist/mcp/defi/uniswap-limit-order-input.js +39 -0
- package/dist/mcp/defi/uniswap-limit-order-input.js.map +1 -0
- package/dist/mcp/defi/uniswap-quote-input.d.ts.map +1 -1
- package/dist/mcp/defi/uniswap-quote-input.js +45 -26
- package/dist/mcp/defi/uniswap-quote-input.js.map +1 -1
- package/dist/mcp/defi/uniswap-v4-ohlcv-chains.d.ts +2 -2
- package/dist/mcp/defi/uniswap-v4-ohlcv-chains.js +3 -3
- package/dist/mcp/defi/uniswap-v4-ohlcv-chains.js.map +1 -1
- package/dist/mcp/ohlcv-session-wrapper.d.ts.map +1 -1
- package/dist/mcp/ohlcv-session-wrapper.js +56 -2
- package/dist/mcp/ohlcv-session-wrapper.js.map +1 -1
- package/dist/mcp/resources/agent-cron-jobs.md +22 -1
- package/dist/mcp/resources/chart-analysis.md +37 -3
- package/dist/mcp/resources/chart.md +5 -2
- package/dist/mcp/resources/uniswap-tpsl-monitor-cron.example.md +27 -0
- package/dist/mcp/trade-tools.d.ts.map +1 -1
- package/dist/mcp/trade-tools.js +192 -4
- package/dist/mcp/trade-tools.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { getMcpToolDefinitions } from '@continuumdao/ctm-mpc-defi/agent';
|
|
2
|
+
import { resolveTokenFromRegistry } from '../../../registry/tokens.js';
|
|
3
|
+
import { executeDefiMcpTool } from '../../../../mcp/defi/handler.js';
|
|
4
|
+
import { formatHumanPrice, validateBuildTradePrices } from './build-trade.js';
|
|
5
|
+
const UNISWAP_LIMIT_QUOTE_TOOL = 'ctm_uniswap_v4_limit_order_quote';
|
|
6
|
+
const UNISWAP_BUILD_LIMIT_TOOL = 'ctm_uniswap_v4_build_limit_order_multisign';
|
|
7
|
+
const DEFAULT_COLLATERAL_SYMBOL = 'USDC';
|
|
8
|
+
const MAINNET_CHAIN_ID = 1;
|
|
9
|
+
const DEFAULT_ORDER_TTL_SEC = 7 * 24 * 60 * 60;
|
|
10
|
+
function findDefiTool(toolName) {
|
|
11
|
+
return getMcpToolDefinitions().find(tool => tool.name === toolName) ?? null;
|
|
12
|
+
}
|
|
13
|
+
function humanToBaseUnits(human, decimals) {
|
|
14
|
+
const trimmed = human.trim();
|
|
15
|
+
if (!trimmed || !/^\d+(\.\d+)?$/.test(trimmed)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const [whole, frac = ''] = trimmed.split('.');
|
|
19
|
+
const fracPadded = (frac + '0'.repeat(decimals)).slice(0, decimals);
|
|
20
|
+
const combined = `${whole}${fracPadded}`.replace(/^0+/, '') || '0';
|
|
21
|
+
try {
|
|
22
|
+
return BigInt(combined).toString();
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function limitPriceFromEntry(entry) {
|
|
29
|
+
return formatHumanPrice(entry);
|
|
30
|
+
}
|
|
31
|
+
export async function buildUniswapLimitOrderFromTradeIdea(config, defiContext, idea, input) {
|
|
32
|
+
const chainId = input.chainId || MAINNET_CHAIN_ID;
|
|
33
|
+
if (chainId !== MAINNET_CHAIN_ID) {
|
|
34
|
+
return {
|
|
35
|
+
ok: false,
|
|
36
|
+
reason: `UniswapX limit orders require Ethereum mainnet (chainId ${MAINNET_CHAIN_ID}). Got ${chainId}.`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
if (idea.side !== 'long' && idea.side !== 'short') {
|
|
40
|
+
return { ok: false, reason: 'Trade idea side must be long or short for Uniswap limit orders.' };
|
|
41
|
+
}
|
|
42
|
+
const validated = validateBuildTradePrices(idea, input);
|
|
43
|
+
if (!validated.ok) {
|
|
44
|
+
return validated;
|
|
45
|
+
}
|
|
46
|
+
const symbol = idea.symbol?.trim().toUpperCase();
|
|
47
|
+
if (!symbol) {
|
|
48
|
+
return { ok: false, reason: 'Trade idea is missing symbol for Uniswap mapping.' };
|
|
49
|
+
}
|
|
50
|
+
const sizeUsd = input.sizeUsdHuman?.trim();
|
|
51
|
+
if (!sizeUsd) {
|
|
52
|
+
return { ok: false, reason: 'sizeUsdHuman is required for Uniswap limit orders.' };
|
|
53
|
+
}
|
|
54
|
+
const tokenOut = await resolveTokenFromRegistry(config, {
|
|
55
|
+
chainId,
|
|
56
|
+
tokenSymbol: idea.side === 'long' ? symbol : DEFAULT_COLLATERAL_SYMBOL,
|
|
57
|
+
});
|
|
58
|
+
if (!tokenOut.ok) {
|
|
59
|
+
return tokenOut;
|
|
60
|
+
}
|
|
61
|
+
const tokenIn = await resolveTokenFromRegistry(config, {
|
|
62
|
+
chainId,
|
|
63
|
+
tokenSymbol: idea.side === 'long' ? DEFAULT_COLLATERAL_SYMBOL : symbol,
|
|
64
|
+
});
|
|
65
|
+
if (!tokenIn.ok) {
|
|
66
|
+
return tokenIn;
|
|
67
|
+
}
|
|
68
|
+
const inDecimals = idea.side === 'long' ? 6 : 18;
|
|
69
|
+
const amountBase = humanToBaseUnits(sizeUsd, inDecimals);
|
|
70
|
+
if (!amountBase) {
|
|
71
|
+
return { ok: false, reason: `Invalid sizeUsdHuman ${sizeUsd} for Uniswap limit quote.` };
|
|
72
|
+
}
|
|
73
|
+
const quoteTool = findDefiTool(UNISWAP_LIMIT_QUOTE_TOOL);
|
|
74
|
+
const buildTool = findDefiTool(UNISWAP_BUILD_LIMIT_TOOL);
|
|
75
|
+
if (!quoteTool || !buildTool) {
|
|
76
|
+
return { ok: false, reason: 'Uniswap V4 limit order MCP tools are not registered.' };
|
|
77
|
+
}
|
|
78
|
+
const tokenInAddr = tokenIn.data.contractAddress === '0x0' ? '0x0000000000000000000000000000000000000000' : tokenIn.data.contractAddress;
|
|
79
|
+
const tokenOutAddr = tokenOut.data.contractAddress === '0x0' ? '0x0000000000000000000000000000000000000000' : tokenOut.data.contractAddress;
|
|
80
|
+
const orderDeadline = input.expiryDate != null && input.expiryDate > 0
|
|
81
|
+
? Math.floor(input.expiryDate)
|
|
82
|
+
: Math.floor(Date.now() / 1000) + DEFAULT_ORDER_TTL_SEC;
|
|
83
|
+
const quoteResult = await executeDefiMcpTool(config, defiContext, quoteTool, {
|
|
84
|
+
type: 'EXACT_INPUT',
|
|
85
|
+
amount: amountBase,
|
|
86
|
+
limitPrice: limitPriceFromEntry(validated.data.entry),
|
|
87
|
+
tokenIn: tokenInAddr,
|
|
88
|
+
tokenOut: tokenOutAddr,
|
|
89
|
+
chainId,
|
|
90
|
+
orderDeadline,
|
|
91
|
+
keyGenId: input.keyGenId,
|
|
92
|
+
});
|
|
93
|
+
if (quoteResult.isError) {
|
|
94
|
+
const text = quoteResult.content?.[0]?.type === 'text' ? quoteResult.content[0].text : 'Uniswap limit quote failed.';
|
|
95
|
+
return { ok: false, reason: text };
|
|
96
|
+
}
|
|
97
|
+
const fullLimitQuote = quoteResult.structuredContent && typeof quoteResult.structuredContent === 'object'
|
|
98
|
+
? quoteResult.structuredContent
|
|
99
|
+
: null;
|
|
100
|
+
if (!fullLimitQuote) {
|
|
101
|
+
return { ok: false, reason: 'Uniswap limit quote returned no structured content.' };
|
|
102
|
+
}
|
|
103
|
+
const buildResult = await executeDefiMcpTool(config, defiContext, buildTool, {
|
|
104
|
+
keyGenId: input.keyGenId,
|
|
105
|
+
chainId,
|
|
106
|
+
purposeText: input.purposeText,
|
|
107
|
+
fullLimitQuote,
|
|
108
|
+
...(input.expiryDate != null && input.expiryDate > 0 ? { expiryDate: Math.floor(input.expiryDate) } : {}),
|
|
109
|
+
});
|
|
110
|
+
if (buildResult.isError) {
|
|
111
|
+
const text = buildResult.content?.[0]?.type === 'text' ? buildResult.content[0].text : 'Uniswap build_limit_order failed.';
|
|
112
|
+
return { ok: false, reason: text };
|
|
113
|
+
}
|
|
114
|
+
const structured = buildResult.structuredContent && typeof buildResult.structuredContent === 'object'
|
|
115
|
+
? buildResult.structuredContent
|
|
116
|
+
: {};
|
|
117
|
+
const requestId = String(structured.requestId ?? '').trim();
|
|
118
|
+
if (!requestId) {
|
|
119
|
+
return { ok: false, reason: 'Uniswap build_limit_order did not return requestId.' };
|
|
120
|
+
}
|
|
121
|
+
return { ok: true, data: { requestId, mappedTool: UNISWAP_BUILD_LIMIT_TOOL } };
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=build-trade-uniswap-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-trade-uniswap-limit.js","sourceRoot":"","sources":["../../../../../src/core/chart/analysis/trade-setups/build-trade-uniswap-limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,qBAAqB,EAAC,MAAM,kCAAkC,CAAC;AAGvE,OAAO,EAAC,wBAAwB,EAAC,MAAM,6BAA6B,CAAC;AAErE,OAAO,EAAC,kBAAkB,EAAC,MAAM,iCAAiC,CAAC;AAGnE,OAAO,EAAC,gBAAgB,EAAE,wBAAwB,EAAC,MAAM,kBAAkB,CAAC;AAE5E,MAAM,wBAAwB,GAAG,kCAAkC,CAAC;AACpE,MAAM,wBAAwB,GAAG,4CAA4C,CAAC;AAC9E,MAAM,yBAAyB,GAAG,MAAM,CAAC;AACzC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AAE/C,SAAS,YAAY,CAAC,QAAgB;IACrC,OAAO,qBAAqB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC;AAC7E,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,QAAgB;IACxD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,MAAM,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,GAAG,KAAK,GAAG,UAAU,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;IACnE,IAAI,CAAC;QACJ,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,IAAI,CAAC;IACb,CAAC;AACF,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACzC,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mCAAmC,CACxD,MAAqB,EACrB,WAAgC,EAChC,IAAe,EACf,KAAmC;IAEnC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,gBAAgB,CAAC;IAClD,IAAI,OAAO,KAAK,gBAAgB,EAAE,CAAC;QAClC,OAAO;YACN,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,2DAA2D,gBAAgB,UAAU,OAAO,GAAG;SACvG,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACnD,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iEAAiE,EAAC,CAAC;IAC/F,CAAC;IACD,MAAM,SAAS,GAAG,wBAAwB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACxD,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QACnB,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mDAAmD,EAAC,CAAC;IACjF,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oDAAoD,EAAC,CAAC;IAClF,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE;QACvD,OAAO;QACP,WAAW,EAAE,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,yBAAyB;KACtE,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,wBAAwB,CAAC,MAAM,EAAE;QACtD,OAAO;QACP,WAAW,EAAE,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,MAAM;KACtE,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IACzD,IAAI,CAAC,UAAU,EAAE,CAAC;QACjB,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,OAAO,2BAA2B,EAAC,CAAC;IACxF,CAAC;IAED,MAAM,SAAS,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAC;IACzD,IAAI,CAAC,SAAS,IAAI,CAAC,SAAS,EAAE,CAAC;QAC9B,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,sDAAsD,EAAC,CAAC;IACpF,CAAC;IAED,MAAM,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,eAAe,KAAK,KAAK,CAAC,CAAC,CAAC,4CAA4C,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC;IACtH,MAAM,YAAY,GACjB,QAAQ,CAAC,IAAI,CAAC,eAAe,KAAK,KAAK,CAAC,CAAC,CAAC,4CAA4C,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,eAAe,CAAC;IAExH,MAAM,aAAa,GAClB,KAAK,CAAC,UAAU,IAAI,IAAI,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC;QAC/C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC;QAC9B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,qBAAqB,CAAC;IAE1D,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE;QAC5E,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,UAAU;QAClB,UAAU,EAAE,mBAAmB,CAAC,SAAS,CAAC,IAAK,CAAC,KAAK,CAAC;QACtD,OAAO,EAAE,WAAW;QACpB,QAAQ,EAAE,YAAY;QACtB,OAAO;QACP,aAAa;QACb,QAAQ,EAAE,KAAK,CAAC,QAAQ;KACxB,CAAC,CAAC;IACH,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,GACT,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,6BAA6B,CAAC;QACzG,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAC,CAAC;IAClC,CAAC;IACD,MAAM,cAAc,GACnB,WAAW,CAAC,iBAAiB,IAAI,OAAO,WAAW,CAAC,iBAAiB,KAAK,QAAQ;QACjF,CAAC,CAAC,WAAW,CAAC,iBAAiB;QAC/B,CAAC,CAAC,IAAI,CAAC;IACT,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,qDAAqD,EAAC,CAAC;IACnF,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE;QAC5E,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO;QACP,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,cAAc;QACd,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,IAAI,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,EAAC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACvG,CAAC,CAAC;IACH,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,GACT,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,mCAAmC,CAAC;QAC/G,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAC,CAAC;IAClC,CAAC;IACD,MAAM,UAAU,GACf,WAAW,CAAC,iBAAiB,IAAI,OAAO,WAAW,CAAC,iBAAiB,KAAK,QAAQ;QACjF,CAAC,CAAE,WAAW,CAAC,iBAA6C;QAC5D,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,OAAO,EAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,qDAAqD,EAAC,CAAC;IACnF,CAAC;IACD,OAAO,EAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAC,SAAS,EAAE,UAAU,EAAE,wBAAwB,EAAC,EAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -3,16 +3,31 @@ import type { SdkResult } from '../../../result.js';
|
|
|
3
3
|
import type { DefiProtocolContext } from '../../../../mcp/defi/context.js';
|
|
4
4
|
import type { EntryOffsetMode, EntryProximityMode } from './pattern-limit-entry.js';
|
|
5
5
|
import type { TradeIdea } from './trade-idea.js';
|
|
6
|
-
|
|
6
|
+
import { type HyperliquidTpslExecMode } from './trade-desk-defaults.js';
|
|
7
|
+
export type BuildTradeProtocolId = 'hyperliquid' | 'arcus' | 'gmx' | 'uniswap';
|
|
8
|
+
/** Trend structure take-profit base before desk targetOffsetPct (default: impulse-leg measured move). */
|
|
9
|
+
export type TakeProfitSource = 'swing' | 'impulse_leg';
|
|
10
|
+
export declare const DEFAULT_TREND_TAKE_PROFIT_SOURCE: TakeProfitSource;
|
|
7
11
|
export type BuildTradeFromTradeIdeaInput = {
|
|
8
12
|
tradeIdea: TradeIdea;
|
|
9
13
|
protocolId: BuildTradeProtocolId;
|
|
10
14
|
keyGenId: string;
|
|
15
|
+
/** Arcus paired ed25519 KeyGen id (same GroupId as secp256k1 keyGenId). */
|
|
16
|
+
ed25519KeyGenId?: string;
|
|
11
17
|
chainId: number;
|
|
12
18
|
purposeText: string;
|
|
13
19
|
useCustomGas?: boolean;
|
|
20
|
+
/** Uniswap mainnet: market spot swap (default) or UniswapX limit order. */
|
|
21
|
+
orderKind?: 'market' | 'limit';
|
|
22
|
+
/** When true, include TP/SL monitor cron registration hints in output (Uniswap). */
|
|
23
|
+
enableTpslMonitor?: boolean;
|
|
14
24
|
entryOffsetPct?: number;
|
|
15
25
|
invalidationOffsetPct?: number;
|
|
26
|
+
targetOffsetPct?: number;
|
|
27
|
+
targetOffsetMode?: EntryProximityMode;
|
|
28
|
+
/** Trend structure only: impulse-leg measured move (default) or recent swing target. */
|
|
29
|
+
takeProfitSource?: TakeProfitSource;
|
|
30
|
+
tpslExecMode?: HyperliquidTpslExecMode;
|
|
16
31
|
entryProximityPct?: number;
|
|
17
32
|
entryProximityMode?: EntryProximityMode;
|
|
18
33
|
szHuman?: string;
|
|
@@ -34,15 +49,28 @@ export type BuildTradeFromTradeIdeaOutput = {
|
|
|
34
49
|
protocolId: BuildTradeProtocolId;
|
|
35
50
|
entryPriceHuman: string;
|
|
36
51
|
invalidationPriceHuman?: string;
|
|
52
|
+
takeProfitPriceHuman?: string;
|
|
53
|
+
stopLossPriceHuman?: string;
|
|
37
54
|
side: TradeIdea['side'];
|
|
55
|
+
/** Set when enableTpslMonitor registered a cron job after build. */
|
|
56
|
+
tpslMonitorCron?: {
|
|
57
|
+
name: string;
|
|
58
|
+
jobId: string;
|
|
59
|
+
};
|
|
60
|
+
/** When enableTpslMonitor was requested but cron could not be created. */
|
|
61
|
+
tpslMonitorWarning?: string;
|
|
38
62
|
};
|
|
39
63
|
export declare function applyEntryOffset(price: number, side: TradeIdea['side'], offsetPct: number | undefined, mode: EntryOffsetMode): number;
|
|
40
64
|
export declare function applyInvalidationOffset(price: number, side: TradeIdea['side'], offsetPct?: number): number;
|
|
41
65
|
export declare function formatHumanPrice(price: number): string;
|
|
66
|
+
export declare function applyTargetOffset(price: number, side: TradeIdea['side'], offsetPct?: number, mode?: EntryProximityMode, atr?: number | null): number;
|
|
42
67
|
export declare function validateBuildTradePrices(idea: TradeIdea, input: BuildTradeFromTradeIdeaInput): SdkResult<{
|
|
43
68
|
entry: number;
|
|
44
69
|
invalidation?: number;
|
|
70
|
+
target?: number;
|
|
45
71
|
}>;
|
|
72
|
+
export declare function mapTradeIdeaToArcusPerpPlaceOrderInput(idea: TradeIdea, input: BuildTradeFromTradeIdeaInput): SdkResult<Record<string, unknown>>;
|
|
73
|
+
export declare function mapTradeIdeaToArcusSpotRfqInput(idea: TradeIdea, input: BuildTradeFromTradeIdeaInput): SdkResult<Record<string, unknown>>;
|
|
46
74
|
export declare function mapTradeIdeaToHyperliquidLimitInput(idea: TradeIdea, input: BuildTradeFromTradeIdeaInput): SdkResult<Record<string, unknown>>;
|
|
47
75
|
export declare function mapTradeIdeaToGmxIncreaseInput(idea: TradeIdea, input: BuildTradeFromTradeIdeaInput): SdkResult<Record<string, unknown>>;
|
|
48
76
|
export declare function buildTradeFromTradeIdea(config: NodeSdkConfig, defiContext: DefiProtocolContext, input: BuildTradeFromTradeIdeaInput): Promise<SdkResult<BuildTradeFromTradeIdeaOutput>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-trade.d.ts","sourceRoot":"","sources":["../../../../../src/core/chart/analysis/trade-setups/build-trade.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,iCAAiC,CAAC;AAEzE,OAAO,KAAK,EAAC,eAAe,EAAE,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAClF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAK/C,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,KAAK,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"build-trade.d.ts","sourceRoot":"","sources":["../../../../../src/core/chart/analysis/trade-setups/build-trade.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,iCAAiC,CAAC;AAEzE,OAAO,KAAK,EAAC,eAAe,EAAE,kBAAkB,EAAC,MAAM,0BAA0B,CAAC;AAClF,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAK/C,OAAO,EAEN,KAAK,uBAAuB,EAC5B,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC;AAE/E,yGAAyG;AACzG,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,aAAa,CAAC;AAEvD,eAAO,MAAM,gCAAgC,EAAE,gBAAgC,CAAC;AAEhF,MAAM,MAAM,4BAA4B,GAAG;IAC1C,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,oBAAoB,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC/B,oFAAoF;IACpF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,oBAAoB,CAAC;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IACxB,oEAAoE;IACpE,eAAe,CAAC,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,CAAC;IAChD,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AA6EF,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EACvB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,IAAI,EAAE,eAAe,GACnB,MAAM,CAqBR;AAED,wBAAgB,uBAAuB,CACtC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EACvB,SAAS,CAAC,EAAE,MAAM,GAChB,MAAM,CAYR;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAStD;AAmBD,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,IAAI,GAAE,kBAA4B,EAClC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GACjB,MAAM,CAwBR;AAoCD,wBAAgB,wBAAwB,CACvC,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,4BAA4B,GACjC,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAC,CAAC,CA+EpE;AAkDD,wBAAgB,sCAAsC,CACrD,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,4BAA4B,GACjC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAoCpC;AAED,wBAAgB,+BAA+B,CAC9C,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,4BAA4B,GACjC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAgCpC;AAED,wBAAgB,mCAAmC,CAClD,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,4BAA4B,GACjC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAuCpC;AAED,wBAAgB,8BAA8B,CAC7C,IAAI,EAAE,SAAS,EACf,KAAK,EAAE,4BAA4B,GACjC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA6CpC;AAED,wBAAsB,uBAAuB,CAC5C,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,mBAAmB,EAChC,KAAK,EAAE,4BAA4B,GACjC,OAAO,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC,CA8HnD"}
|
|
@@ -2,13 +2,19 @@ import { getMcpToolDefinitions } from '@continuumdao/ctm-mpc-defi/agent';
|
|
|
2
2
|
import { executeDefiMcpTool } from '../../../../mcp/defi/handler.js';
|
|
3
3
|
import { tradeIdeaWithFibSideOverride } from './trade-idea.js';
|
|
4
4
|
import { buildUniswapSpotSwapFromTradeIdea } from './build-trade-uniswap.js';
|
|
5
|
+
import { buildUniswapLimitOrderFromTradeIdea } from './build-trade-uniswap-limit.js';
|
|
5
6
|
import { passesEntryProximityGate } from './trade-entry-gates.js';
|
|
7
|
+
import { hyperliquidTradeDeskDefaults, } from './trade-desk-defaults.js';
|
|
8
|
+
export const DEFAULT_TREND_TAKE_PROFIT_SOURCE = 'impulse_leg';
|
|
6
9
|
const DEFAULT_CHAIN_BY_PROTOCOL = {
|
|
7
10
|
hyperliquid: 999,
|
|
11
|
+
arcus: 4663,
|
|
8
12
|
gmx: 42161,
|
|
9
13
|
uniswap: 42161,
|
|
10
14
|
};
|
|
11
15
|
const HYPERLIQUID_LIMIT_TOOL = 'ctm_hyperliquid_build_limit_order_multisign';
|
|
16
|
+
const ARCUS_PERP_PLACE_TOOL = 'ctm_arcus_build_place_order_multisign';
|
|
17
|
+
const ARCUS_SPOT_RFQ_TOOL = 'ctm_arcus_spot_build_rfq_multisign';
|
|
12
18
|
const GMX_INCREASE_TOOL = 'ctm_gmx_build_increase_multisign';
|
|
13
19
|
function proximityFromSetup(idea) {
|
|
14
20
|
const setup = idea.analysisSetup.setup;
|
|
@@ -47,6 +53,21 @@ function entryOffsetModeFromIdea(idea) {
|
|
|
47
53
|
}
|
|
48
54
|
return 'bounce';
|
|
49
55
|
}
|
|
56
|
+
function takeProfitBasePrice(idea, input) {
|
|
57
|
+
const source = input.takeProfitSource ?? DEFAULT_TREND_TAKE_PROFIT_SOURCE;
|
|
58
|
+
if (idea.analysisSetup.kind === 'trend_structure') {
|
|
59
|
+
if (source === 'impulse_leg') {
|
|
60
|
+
const mm = idea.analysisSetup.setup.measuredMove;
|
|
61
|
+
if (mm != null && Number.isFinite(mm.targetPrice)) {
|
|
62
|
+
return mm.targetPrice;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (source === 'swing') {
|
|
66
|
+
return idea.target?.price;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return idea.target?.price;
|
|
70
|
+
}
|
|
50
71
|
export function applyEntryOffset(price, side, offsetPct, mode) {
|
|
51
72
|
if (offsetPct == null || !Number.isFinite(offsetPct) || offsetPct === 0) {
|
|
52
73
|
return price;
|
|
@@ -92,16 +113,68 @@ export function formatHumanPrice(price) {
|
|
|
92
113
|
}
|
|
93
114
|
return price.toFixed(6);
|
|
94
115
|
}
|
|
116
|
+
function atrAtLastBarFromTradeIdea(idea) {
|
|
117
|
+
const setup = idea.analysisSetup.setup;
|
|
118
|
+
if ('atrAtLastBar' in setup) {
|
|
119
|
+
const v = setup.atrAtLastBar;
|
|
120
|
+
if (v != null && Number.isFinite(v) && v > 0) {
|
|
121
|
+
return v;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if ('atr' in setup) {
|
|
125
|
+
const v = setup.atr;
|
|
126
|
+
if (v != null && Number.isFinite(v) && v > 0) {
|
|
127
|
+
return v;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
export function applyTargetOffset(price, side, offsetPct, mode = 'price', atr) {
|
|
133
|
+
if (offsetPct == null || !Number.isFinite(offsetPct) || offsetPct === 0) {
|
|
134
|
+
return price;
|
|
135
|
+
}
|
|
136
|
+
const isShort = side === 'short';
|
|
137
|
+
const isLong = side === 'long';
|
|
138
|
+
if (mode === 'atr' && atr != null && Number.isFinite(atr) && atr > 0) {
|
|
139
|
+
const delta = (atr * offsetPct) / 100;
|
|
140
|
+
if (isLong) {
|
|
141
|
+
return price - delta;
|
|
142
|
+
}
|
|
143
|
+
if (isShort) {
|
|
144
|
+
return price + delta;
|
|
145
|
+
}
|
|
146
|
+
return price;
|
|
147
|
+
}
|
|
148
|
+
const factor = offsetPct / 100;
|
|
149
|
+
if (isLong) {
|
|
150
|
+
return price * (1 - factor);
|
|
151
|
+
}
|
|
152
|
+
if (isShort) {
|
|
153
|
+
return price * (1 + factor);
|
|
154
|
+
}
|
|
155
|
+
return price;
|
|
156
|
+
}
|
|
95
157
|
function resolveEffectivePrices(idea, input) {
|
|
96
158
|
if (!idea.entry) {
|
|
97
159
|
return null;
|
|
98
160
|
}
|
|
161
|
+
const hlDesk = hyperliquidTradeDeskDefaults();
|
|
99
162
|
const mode = entryOffsetModeFromIdea(idea);
|
|
100
163
|
const entry = applyEntryOffset(idea.entry.price, idea.side, input.entryOffsetPct, mode);
|
|
101
164
|
const invalidation = idea.invalidation != null
|
|
102
165
|
? applyInvalidationOffset(idea.invalidation.price, idea.side, input.invalidationOffsetPct)
|
|
103
166
|
: undefined;
|
|
104
|
-
|
|
167
|
+
const targetBase = takeProfitBasePrice(idea, input);
|
|
168
|
+
const target = targetBase != null
|
|
169
|
+
? (() => {
|
|
170
|
+
const offsetPct = input.targetOffsetPct ?? hlDesk.targetOffsetPct;
|
|
171
|
+
const mode = input.targetOffsetMode ?? hlDesk.targetOffsetMode;
|
|
172
|
+
const atr = mode === 'atr' ? atrAtLastBarFromTradeIdea(idea) : null;
|
|
173
|
+
const effectiveMode = mode === 'atr' && atr == null ? 'price' : mode;
|
|
174
|
+
return applyTargetOffset(targetBase, idea.side, offsetPct, effectiveMode, atr);
|
|
175
|
+
})()
|
|
176
|
+
: undefined;
|
|
177
|
+
return { entry, invalidation, target };
|
|
105
178
|
}
|
|
106
179
|
export function validateBuildTradePrices(idea, input) {
|
|
107
180
|
if (idea.side !== 'long' && idea.side !== 'short') {
|
|
@@ -114,7 +187,7 @@ export function validateBuildTradePrices(idea, input) {
|
|
|
114
187
|
if (!resolved) {
|
|
115
188
|
return { ok: false, reason: 'Trade idea has no entry level — cannot build limit order.' };
|
|
116
189
|
}
|
|
117
|
-
const { entry, invalidation } = resolved;
|
|
190
|
+
const { entry, invalidation, target } = resolved;
|
|
118
191
|
const lastClose = idea.lastClose;
|
|
119
192
|
const mode = entryOffsetModeFromIdea(idea);
|
|
120
193
|
if (mode !== 'retest') {
|
|
@@ -145,6 +218,30 @@ export function validateBuildTradePrices(idea, input) {
|
|
|
145
218
|
};
|
|
146
219
|
}
|
|
147
220
|
}
|
|
221
|
+
if (target != null) {
|
|
222
|
+
if (idea.side === 'long' && target <= entry) {
|
|
223
|
+
return {
|
|
224
|
+
ok: false,
|
|
225
|
+
reason: 'Adjusted take-profit must sit above adjusted entry for long setups.',
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
if (idea.side === 'short' && target >= entry) {
|
|
229
|
+
return {
|
|
230
|
+
ok: false,
|
|
231
|
+
reason: 'Adjusted take-profit must sit below adjusted entry for short setups.',
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (input.protocolId === 'hyperliquid' && (target != null || invalidation != null)) {
|
|
236
|
+
if (invalidation != null && target != null) {
|
|
237
|
+
if (idea.side === 'long' && !(invalidation < entry && entry < target)) {
|
|
238
|
+
return { ok: false, reason: 'Long bracket requires SL < entry < TP after desk offsets.' };
|
|
239
|
+
}
|
|
240
|
+
if (idea.side === 'short' && !(target < entry && entry < invalidation)) {
|
|
241
|
+
return { ok: false, reason: 'Short bracket requires TP < entry < SL after desk offsets.' };
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
148
245
|
if (input.protocolId === 'uniswap' &&
|
|
149
246
|
!passesEntryProximityGate({
|
|
150
247
|
lastClose,
|
|
@@ -155,7 +252,7 @@ export function validateBuildTradePrices(idea, input) {
|
|
|
155
252
|
})) {
|
|
156
253
|
return { ok: false, reason: 'Uniswap swap requires price within entry proximity of the idea entry.' };
|
|
157
254
|
}
|
|
158
|
-
return { ok: true, data: { entry, invalidation } };
|
|
255
|
+
return { ok: true, data: { entry, invalidation, target } };
|
|
159
256
|
}
|
|
160
257
|
function resolveGmxSymbol(idea) {
|
|
161
258
|
const symbol = idea.symbol?.trim();
|
|
@@ -171,6 +268,106 @@ function resolveCoinSymbol(idea) {
|
|
|
171
268
|
function findDefiTool(toolName) {
|
|
172
269
|
return getMcpToolDefinitions().find(tool => tool.name === toolName) ?? null;
|
|
173
270
|
}
|
|
271
|
+
function resolveArcusMarket(idea) {
|
|
272
|
+
const symbol = idea.symbol?.trim();
|
|
273
|
+
if (!symbol)
|
|
274
|
+
return null;
|
|
275
|
+
if (symbol.includes('-'))
|
|
276
|
+
return symbol.toUpperCase();
|
|
277
|
+
return `${symbol.toUpperCase()}-USD`;
|
|
278
|
+
}
|
|
279
|
+
function resolveArcusSpotTicker(idea) {
|
|
280
|
+
const symbol = idea.symbol?.trim();
|
|
281
|
+
if (!symbol)
|
|
282
|
+
return null;
|
|
283
|
+
return symbol.split('-')[0].toUpperCase();
|
|
284
|
+
}
|
|
285
|
+
function arcusKeyGenFields(input) {
|
|
286
|
+
const secp256k1KeyGenId = input.keyGenId.trim();
|
|
287
|
+
const ed25519KeyGenId = input.ed25519KeyGenId?.trim() ?? '';
|
|
288
|
+
if (!secp256k1KeyGenId) {
|
|
289
|
+
return { ok: false, reason: 'keyGenId (secp256k1) is required for Arcus trades.' };
|
|
290
|
+
}
|
|
291
|
+
if (!ed25519KeyGenId) {
|
|
292
|
+
return {
|
|
293
|
+
ok: false,
|
|
294
|
+
reason: 'ed25519KeyGenId is required for Arcus trades (paired KeyGen, same GroupId).',
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
return { ok: true, data: { secp256k1KeyGenId, ed25519KeyGenId } };
|
|
298
|
+
}
|
|
299
|
+
export function mapTradeIdeaToArcusPerpPlaceOrderInput(idea, input) {
|
|
300
|
+
if (idea.side !== 'long' && idea.side !== 'short') {
|
|
301
|
+
return { ok: false, reason: 'Trade idea side must be long or short for Arcus perp orders.' };
|
|
302
|
+
}
|
|
303
|
+
const market = resolveArcusMarket(idea);
|
|
304
|
+
if (!market) {
|
|
305
|
+
return { ok: false, reason: 'Trade idea is missing symbol/market for Arcus mapping.' };
|
|
306
|
+
}
|
|
307
|
+
if (!input.szHuman?.trim()) {
|
|
308
|
+
return { ok: false, reason: 'szHuman is required for Arcus perp orders.' };
|
|
309
|
+
}
|
|
310
|
+
const keys = arcusKeyGenFields(input);
|
|
311
|
+
if (!keys.ok)
|
|
312
|
+
return keys;
|
|
313
|
+
const validated = validateBuildTradePrices(idea, input);
|
|
314
|
+
if (!validated.ok) {
|
|
315
|
+
return validated;
|
|
316
|
+
}
|
|
317
|
+
const entryPx = validated.data.entry;
|
|
318
|
+
const tpPx = validated.data.target;
|
|
319
|
+
const slPx = validated.data.invalidation;
|
|
320
|
+
return {
|
|
321
|
+
ok: true,
|
|
322
|
+
data: {
|
|
323
|
+
secp256k1KeyGenId: keys.data.secp256k1KeyGenId,
|
|
324
|
+
ed25519KeyGenId: keys.data.ed25519KeyGenId,
|
|
325
|
+
chainId: input.chainId || DEFAULT_CHAIN_BY_PROTOCOL.arcus,
|
|
326
|
+
purposeText: input.purposeText,
|
|
327
|
+
market,
|
|
328
|
+
isBuy: idea.side === 'long',
|
|
329
|
+
limitPxHuman: formatHumanPrice(entryPx),
|
|
330
|
+
szHuman: input.szHuman.trim(),
|
|
331
|
+
...(tpPx != null ? { takeProfitTriggerPxHuman: formatHumanPrice(tpPx) } : {}),
|
|
332
|
+
...(slPx != null ? { stopLossTriggerPxHuman: formatHumanPrice(slPx) } : {}),
|
|
333
|
+
...(input.expiryDate != null && input.expiryDate > 0 ? { expiryDate: Math.floor(input.expiryDate) } : {}),
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
export function mapTradeIdeaToArcusSpotRfqInput(idea, input) {
|
|
338
|
+
if (idea.side !== 'long' && idea.side !== 'short') {
|
|
339
|
+
return { ok: false, reason: 'Trade idea side must be long or short for Arcus spot RFQ.' };
|
|
340
|
+
}
|
|
341
|
+
const ticker = resolveArcusSpotTicker(idea);
|
|
342
|
+
if (!ticker) {
|
|
343
|
+
return { ok: false, reason: 'Trade idea is missing symbol/ticker for Arcus spot mapping.' };
|
|
344
|
+
}
|
|
345
|
+
if (!input.szHuman?.trim()) {
|
|
346
|
+
return { ok: false, reason: 'szHuman is required for Arcus spot RFQ (sizeHuman).' };
|
|
347
|
+
}
|
|
348
|
+
const keys = arcusKeyGenFields(input);
|
|
349
|
+
if (!keys.ok)
|
|
350
|
+
return keys;
|
|
351
|
+
const validated = validateBuildTradePrices(idea, input);
|
|
352
|
+
if (!validated.ok) {
|
|
353
|
+
return validated;
|
|
354
|
+
}
|
|
355
|
+
const entryPx = validated.data.entry;
|
|
356
|
+
return {
|
|
357
|
+
ok: true,
|
|
358
|
+
data: {
|
|
359
|
+
secp256k1KeyGenId: keys.data.secp256k1KeyGenId,
|
|
360
|
+
ed25519KeyGenId: keys.data.ed25519KeyGenId,
|
|
361
|
+
chainId: input.chainId || DEFAULT_CHAIN_BY_PROTOCOL.arcus,
|
|
362
|
+
purposeText: input.purposeText,
|
|
363
|
+
ticker,
|
|
364
|
+
isBuy: idea.side === 'long',
|
|
365
|
+
sizeHuman: input.szHuman.trim(),
|
|
366
|
+
limitPxHuman: formatHumanPrice(entryPx),
|
|
367
|
+
...(input.expiryDate != null && input.expiryDate > 0 ? { expiryDate: Math.floor(input.expiryDate) } : {}),
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
}
|
|
174
371
|
export function mapTradeIdeaToHyperliquidLimitInput(idea, input) {
|
|
175
372
|
if (idea.side !== 'long' && idea.side !== 'short') {
|
|
176
373
|
return { ok: false, reason: 'Trade idea side must be long or short for Hyperliquid limit orders.' };
|
|
@@ -187,6 +384,10 @@ export function mapTradeIdeaToHyperliquidLimitInput(idea, input) {
|
|
|
187
384
|
return validated;
|
|
188
385
|
}
|
|
189
386
|
const entryPx = validated.data.entry;
|
|
387
|
+
const tpPx = validated.data.target;
|
|
388
|
+
const slPx = validated.data.invalidation;
|
|
389
|
+
const hlDesk = hyperliquidTradeDeskDefaults();
|
|
390
|
+
const tpslExecMode = input.tpslExecMode ?? hlDesk.tpslExecMode;
|
|
190
391
|
return {
|
|
191
392
|
ok: true,
|
|
192
393
|
data: {
|
|
@@ -200,6 +401,9 @@ export function mapTradeIdeaToHyperliquidLimitInput(idea, input) {
|
|
|
200
401
|
szHuman: input.szHuman.trim(),
|
|
201
402
|
marketKind: input.marketKind ?? 'perp',
|
|
202
403
|
tif: input.tif ?? 'gtc',
|
|
404
|
+
...(tpPx != null ? { takeProfitTriggerPxHuman: formatHumanPrice(tpPx) } : {}),
|
|
405
|
+
...(slPx != null ? { stopLossTriggerPxHuman: formatHumanPrice(slPx) } : {}),
|
|
406
|
+
...(tpPx != null || slPx != null ? { tpslExecMode } : {}),
|
|
203
407
|
...(input.expiryDate != null && input.expiryDate > 0 ? { expiryDate: Math.floor(input.expiryDate) } : {}),
|
|
204
408
|
},
|
|
205
409
|
};
|
|
@@ -226,7 +430,8 @@ export function mapTradeIdeaToGmxIncreaseInput(idea, input) {
|
|
|
226
430
|
return validated;
|
|
227
431
|
}
|
|
228
432
|
const triggerPx = validated.data.entry;
|
|
229
|
-
const
|
|
433
|
+
const tpPx = validated.data.target;
|
|
434
|
+
const slPx = validated.data.invalidation;
|
|
230
435
|
return {
|
|
231
436
|
ok: true,
|
|
232
437
|
data: {
|
|
@@ -241,7 +446,9 @@ export function mapTradeIdeaToGmxIncreaseInput(idea, input) {
|
|
|
241
446
|
collateralToken: input.collateralToken.trim(),
|
|
242
447
|
collateralAmountHuman: input.collateralAmountHuman.trim(),
|
|
243
448
|
triggerPriceUsdHuman: formatHumanPrice(triggerPx),
|
|
244
|
-
...(
|
|
449
|
+
...(tpPx != null ? { takeProfitPriceUsdHuman: formatHumanPrice(tpPx) } : {}),
|
|
450
|
+
...(slPx != null ? { stopLossPriceUsdHuman: formatHumanPrice(slPx) } : {}),
|
|
451
|
+
...(slPx != null ? { patternFailureUsdHuman: formatHumanPrice(slPx) } : {}),
|
|
245
452
|
...(input.slippageBps != null ? { slippageBps: input.slippageBps } : {}),
|
|
246
453
|
...(input.expiryDate != null && input.expiryDate > 0 ? { expiryDate: Math.floor(input.expiryDate) } : {}),
|
|
247
454
|
},
|
|
@@ -261,6 +468,33 @@ export async function buildTradeFromTradeIdea(config, defiContext, input) {
|
|
|
261
468
|
if (!proximity.ok) {
|
|
262
469
|
return proximity;
|
|
263
470
|
}
|
|
471
|
+
const orderKind = input.orderKind ?? 'market';
|
|
472
|
+
if (orderKind === 'limit') {
|
|
473
|
+
const built = await buildUniswapLimitOrderFromTradeIdea(config, defiContext, idea, input);
|
|
474
|
+
if (!built.ok) {
|
|
475
|
+
return built;
|
|
476
|
+
}
|
|
477
|
+
return {
|
|
478
|
+
ok: true,
|
|
479
|
+
data: {
|
|
480
|
+
requestId: built.data.requestId,
|
|
481
|
+
tradeIdeaId: idea.id,
|
|
482
|
+
mappedTool: built.data.mappedTool,
|
|
483
|
+
protocolId,
|
|
484
|
+
entryPriceHuman: formatHumanPrice(proximity.data.entry),
|
|
485
|
+
...(proximity.data.invalidation != null
|
|
486
|
+
? {
|
|
487
|
+
invalidationPriceHuman: formatHumanPrice(proximity.data.invalidation),
|
|
488
|
+
stopLossPriceHuman: formatHumanPrice(proximity.data.invalidation),
|
|
489
|
+
}
|
|
490
|
+
: {}),
|
|
491
|
+
...(proximity.data.target != null
|
|
492
|
+
? { takeProfitPriceHuman: formatHumanPrice(proximity.data.target) }
|
|
493
|
+
: {}),
|
|
494
|
+
side: idea.side,
|
|
495
|
+
},
|
|
496
|
+
};
|
|
497
|
+
}
|
|
264
498
|
const built = await buildUniswapSpotSwapFromTradeIdea(config, defiContext, idea, input);
|
|
265
499
|
if (!built.ok) {
|
|
266
500
|
return built;
|
|
@@ -273,18 +507,37 @@ export async function buildTradeFromTradeIdea(config, defiContext, input) {
|
|
|
273
507
|
mappedTool: built.data.mappedTool,
|
|
274
508
|
protocolId,
|
|
275
509
|
entryPriceHuman: formatHumanPrice(proximity.data.entry),
|
|
510
|
+
...(proximity.data.invalidation != null
|
|
511
|
+
? {
|
|
512
|
+
invalidationPriceHuman: formatHumanPrice(proximity.data.invalidation),
|
|
513
|
+
stopLossPriceHuman: formatHumanPrice(proximity.data.invalidation),
|
|
514
|
+
}
|
|
515
|
+
: {}),
|
|
516
|
+
...(proximity.data.target != null
|
|
517
|
+
? { takeProfitPriceHuman: formatHumanPrice(proximity.data.target) }
|
|
518
|
+
: {}),
|
|
276
519
|
side: idea.side,
|
|
277
520
|
},
|
|
278
521
|
};
|
|
279
522
|
}
|
|
280
|
-
const mappedTool = protocolId === 'hyperliquid'
|
|
523
|
+
const mappedTool = protocolId === 'hyperliquid'
|
|
524
|
+
? HYPERLIQUID_LIMIT_TOOL
|
|
525
|
+
: protocolId === 'arcus'
|
|
526
|
+
? (input.marketKind ?? 'perp') === 'spot'
|
|
527
|
+
? ARCUS_SPOT_RFQ_TOOL
|
|
528
|
+
: ARCUS_PERP_PLACE_TOOL
|
|
529
|
+
: GMX_INCREASE_TOOL;
|
|
281
530
|
const tool = findDefiTool(mappedTool);
|
|
282
531
|
if (!tool) {
|
|
283
532
|
return { ok: false, reason: `DeFi tool ${mappedTool} is not registered.` };
|
|
284
533
|
}
|
|
285
534
|
const mapped = protocolId === 'hyperliquid'
|
|
286
535
|
? mapTradeIdeaToHyperliquidLimitInput(idea, input)
|
|
287
|
-
:
|
|
536
|
+
: protocolId === 'arcus'
|
|
537
|
+
? (input.marketKind ?? 'perp') === 'spot'
|
|
538
|
+
? mapTradeIdeaToArcusSpotRfqInput(idea, input)
|
|
539
|
+
: mapTradeIdeaToArcusPerpPlaceOrderInput(idea, input)
|
|
540
|
+
: mapTradeIdeaToGmxIncreaseInput(idea, input);
|
|
288
541
|
if (!mapped.ok) {
|
|
289
542
|
return mapped;
|
|
290
543
|
}
|
|
@@ -313,7 +566,13 @@ export async function buildTradeFromTradeIdea(config, defiContext, input) {
|
|
|
313
566
|
protocolId,
|
|
314
567
|
entryPriceHuman: formatHumanPrice(validated.data.entry),
|
|
315
568
|
...(validated.data.invalidation != null
|
|
316
|
-
? {
|
|
569
|
+
? {
|
|
570
|
+
invalidationPriceHuman: formatHumanPrice(validated.data.invalidation),
|
|
571
|
+
stopLossPriceHuman: formatHumanPrice(validated.data.invalidation),
|
|
572
|
+
}
|
|
573
|
+
: {}),
|
|
574
|
+
...(validated.data.target != null
|
|
575
|
+
? { takeProfitPriceHuman: formatHumanPrice(validated.data.target) }
|
|
317
576
|
: {}),
|
|
318
577
|
side: idea.side,
|
|
319
578
|
},
|