@clonegod/ttd-core 3.0.21 → 3.1.2
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/analyze/index.d.ts +1 -1
- package/dist/analyze/index.js +21 -22
- package/dist/index.d.ts +1 -1
- package/dist/quote/log_quote_price.js +0 -27
- package/dist/quote/on_quote_response.d.ts +16 -1
- package/dist/quote/on_quote_response.js +56 -16
- package/dist/quote/to_price_message.js +10 -14
- package/dist/trade/abstract_tx_check.js +12 -0
- package/dist/trade/handle_order_message.js +6 -2
- package/package.json +1 -1
- package/types/index.d.ts +216 -0
package/dist/analyze/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { OrderMessageType, PriceMessageType } from "../../types";
|
|
2
|
-
export declare const report_trade_analyze_data: (type: string, message: PriceMessageType | OrderMessageType) => void;
|
|
2
|
+
export declare const report_trade_analyze_data: (type: string, message: PriceMessageType | OrderMessageType | any) => void;
|
|
3
3
|
export declare const get_pool_latest_quote_price: (unique_orderbook_id: string) => Promise<PriceMessageType>;
|
package/dist/analyze/index.js
CHANGED
|
@@ -15,35 +15,34 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
exports.get_pool_latest_quote_price = exports.report_trade_analyze_data = void 0;
|
|
16
16
|
const axios_1 = __importDefault(require("axios"));
|
|
17
17
|
const index_1 = require("../index");
|
|
18
|
-
const
|
|
19
|
-
const
|
|
18
|
+
const ANALYZE_HOST = process.env.TRADE_ANALYZE_HOST || '';
|
|
19
|
+
const ANALYZE_PORT = process.env.TRADE_ANALYZE_PORT || '8004';
|
|
20
|
+
const ANALYZE_BASE = ANALYZE_HOST ? `http://${ANALYZE_HOST}:${ANALYZE_PORT}/trade/analyze` : '';
|
|
20
21
|
const headers = { 'Content-Type': 'application/json' };
|
|
21
22
|
const report_trade_analyze_data = (type, message) => {
|
|
22
|
-
|
|
23
|
-
type,
|
|
24
|
-
message
|
|
25
|
-
};
|
|
26
|
-
if (!report_trade_log) {
|
|
23
|
+
if (!ANALYZE_BASE)
|
|
27
24
|
return;
|
|
25
|
+
try {
|
|
26
|
+
axios_1.default.post(ANALYZE_BASE, { type, message }, { headers, timeout: 3000 })
|
|
27
|
+
.then(() => (0, index_1.log_trace)(`[analyze] report ${type} ok`))
|
|
28
|
+
.catch(err => (0, index_1.log_warn)(`[analyze] report ${type} fail: ${err.message}`));
|
|
29
|
+
}
|
|
30
|
+
catch (err) {
|
|
31
|
+
(0, index_1.log_warn)(`[analyze] report ${type} error: ${err.message}`);
|
|
28
32
|
}
|
|
29
|
-
axios_1.default.post(trade_analyze_url, body, { headers })
|
|
30
|
-
.then(res => (0, index_1.log_trace)('report_trade_analzye_data, success, res=', res.data))
|
|
31
|
-
.catch(err => (0, index_1.log_warn)(`report_trade_analzye_data, error: ${err.message}`));
|
|
32
33
|
};
|
|
33
34
|
exports.report_trade_analyze_data = report_trade_analyze_data;
|
|
34
35
|
const get_pool_latest_quote_price = (unique_orderbook_id) => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
36
|
+
if (!ANALYZE_BASE || (0, index_1.isEmpty)(unique_orderbook_id))
|
|
37
|
+
return null;
|
|
38
|
+
try {
|
|
39
|
+
const url = `${ANALYZE_BASE}/price_msg?unique_orderbook_id=${unique_orderbook_id}`;
|
|
40
|
+
const res = (yield axios_1.default.get(url, { headers, timeout: 3000 })).data;
|
|
41
|
+
return res.data;
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
(0, index_1.log_warn)(`[analyze] get_price fail: ${err.message}`);
|
|
45
|
+
return null;
|
|
46
46
|
}
|
|
47
|
-
return price_msg;
|
|
48
47
|
});
|
|
49
48
|
exports.get_pool_latest_quote_price = get_pool_latest_quote_price;
|
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export * from './trade';
|
|
|
15
15
|
export * from './chains';
|
|
16
16
|
export * from './ws';
|
|
17
17
|
export * from './util';
|
|
18
|
-
export type { CommonServiceType, ConfigCenterServiceType, QuoteServiceType, OrderbookServiceType, TradeProxyServiceType, StandardTokenConfigType, StandardTokenInfoType, StandardPoolConfigType, StandardDexPoolConfigType, StandardPoolInfoType, StandardPairType, TradeServiceConfigType, TradeGroupType, TradePairType, TradePairDexPoolsType, TradeSettingsType, RpcInfoType, TradeStrategyType, TradeCommandLineArgs, TradeRuntimeType, TradeProcessInstanceType, TokenPriceWithAmountType, QuoteResultType, PriceMessageType, QuoteSourceType, UniqueOrderbookIdType, PriceType, QuoteTimeInfoType, OrderbookPriceType, Ladder, OrderMessageType, OrderSubmitResultType, OrderSubmitResponseType, StandardSwapDetailType, TokenBalChangeType, TokenBalanceChangeType, TradeResponseType, TradeResultType, TradeResultBalanceChangeType, TradeExecutionInfoType, TradeTimeFlowType, TradeBroadcastType, TradeGasFeeType, ServerInfoType, SendTxLogType, WalletInfoType, WalletTokenBalanceInfoType, RedisConfigChangeEventMessageType, RedisOrderEventMessageType, RedisQuoteEventMessageType, } from '../types';
|
|
18
|
+
export type { CommonServiceType, ConfigCenterServiceType, QuoteServiceType, OrderbookServiceType, TradeProxyServiceType, StandardTokenConfigType, StandardTokenInfoType, StandardPoolConfigType, StandardDexPoolConfigType, StandardPoolInfoType, StandardPairType, TradeServiceConfigType, TradeGroupType, TradePairType, TradePairDexPoolsType, TradeSettingsType, RpcInfoType, TradeStrategyType, TradeCommandLineArgs, TradeRuntimeType, TradeProcessInstanceType, TokenPriceWithAmountType, QuoteResultType, PriceMessageType, QuoteSourceType, UniqueOrderbookIdType, PriceType, QuoteTimeInfoType, OrderbookPriceType, Ladder, OrderMessageType, OrderSubmitResultType, OrderSubmitResponseType, StandardSwapDetailType, TokenBalChangeType, TokenBalanceChangeType, TradeResponseType, TradeResultType, TradeResultBalanceChangeType, TradeExecutionInfoType, TradeTimeFlowType, TradeBroadcastType, TradeGasFeeType, ServerInfoType, SendTxLogType, WalletInfoType, WalletTokenBalanceInfoType, RedisConfigChangeEventMessageType, RedisOrderEventMessageType, RedisQuoteEventMessageType, PreTradeEventType, ProviderComparisonType, ProviderArrivalType, OnTradeType, OnTradePriceType, OnTradeDepthType, OnTradeExecutionType, OnTradeResultType, AnalyzeDepthLevelType, AnalyzeTokenAmountType, PostTradeType, AnalyzeQuoteSnapshotType, AnalyzePoolEventType, AnalyzeEventSummaryType, AnalyzeSameBlockType, } from '../types';
|
|
19
19
|
export declare const FAILED = "FAILED";
|
|
20
20
|
export declare const SUCCESS = "SUCCESS";
|
|
21
21
|
export declare const NOT_FOUND = "NOT_FOUND";
|
|
@@ -33,32 +33,5 @@ function log_quote_price(event_source, price_message, tx_hash) {
|
|
|
33
33
|
String(ask.price).padEnd(8) + ' - ' +
|
|
34
34
|
String(bid.price).padEnd(8) + ' - ' +
|
|
35
35
|
`${times.join(',')} ms`);
|
|
36
|
-
const depthLine = formatDepthLine(ask, bid);
|
|
37
|
-
if (depthLine) {
|
|
38
|
-
console.log(depthLine);
|
|
39
|
-
}
|
|
40
36
|
});
|
|
41
37
|
}
|
|
42
|
-
function formatDepthLine(ask, bid) {
|
|
43
|
-
const bpsSet = new Set();
|
|
44
|
-
for (const key of Object.keys(ask)) {
|
|
45
|
-
const match = key.match(/^depth_(\d+)$/);
|
|
46
|
-
if (match)
|
|
47
|
-
bpsSet.add(Number(match[1]));
|
|
48
|
-
}
|
|
49
|
-
if (bpsSet.size === 0)
|
|
50
|
-
return null;
|
|
51
|
-
const parts = [];
|
|
52
|
-
for (const bps of [...bpsSet].sort((a, b) => a - b)) {
|
|
53
|
-
const askAmt = ask[`depth_${bps}`];
|
|
54
|
-
const askUsd = ask[`depth_${bps}_usd`];
|
|
55
|
-
const askTick = ask[`depth_${bps}_tick`] || '';
|
|
56
|
-
const bidAmt = bid[`depth_${bps}`];
|
|
57
|
-
const bidUsd = bid[`depth_${bps}_usd`];
|
|
58
|
-
const bidTick = bid[`depth_${bps}_tick`] || '';
|
|
59
|
-
const askTickStr = askTick ? ` ${askTick}` : '';
|
|
60
|
-
const bidTickStr = bidTick ? ` ${bidTick}` : '';
|
|
61
|
-
parts.push(`${bps}bps: ask=${askAmt}($${askUsd})${askTickStr} | bid=${bidAmt}($${bidUsd})${bidTickStr}`);
|
|
62
|
-
}
|
|
63
|
-
return ` ↳ [Depth] ${parts.join(' | ')}`;
|
|
64
|
-
}
|
|
@@ -16,4 +16,19 @@ export interface PoolDepthData {
|
|
|
16
16
|
tickMove?: string;
|
|
17
17
|
}>;
|
|
18
18
|
}
|
|
19
|
-
export
|
|
19
|
+
export interface QuoteResponseOptions {
|
|
20
|
+
appConfig: AppConfig;
|
|
21
|
+
poolInfo: StandardPoolInfoType;
|
|
22
|
+
quoteAmountUsd: number;
|
|
23
|
+
streamTime: number;
|
|
24
|
+
quoteStartTime: number;
|
|
25
|
+
blockNumber: number;
|
|
26
|
+
quotes: [QuoteResultType, QuoteResultType];
|
|
27
|
+
txid: string;
|
|
28
|
+
pushPriceMessage?: boolean;
|
|
29
|
+
source?: string;
|
|
30
|
+
depth?: PoolDepthData;
|
|
31
|
+
tickLiquidity?: any;
|
|
32
|
+
}
|
|
33
|
+
export declare function on_quote_response(opts: QuoteResponseOptions): void;
|
|
34
|
+
export declare function on_quote_respose(appConfig: AppConfig, pool_info: StandardPoolInfoType, quote_amount_usd: number, _execution_price: number, stream_time: number, quote_start_time: number, slot_info: string, result: [QuoteResultType, QuoteResultType, number], txid: string, push_price_message?: boolean, source?: string, depth?: PoolDepthData): void;
|
|
@@ -1,30 +1,70 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.on_quote_response = on_quote_response;
|
|
3
4
|
exports.on_quote_respose = on_quote_respose;
|
|
4
5
|
const analyze_1 = require("../analyze");
|
|
5
6
|
const log_quote_price_1 = require("./log_quote_price");
|
|
6
7
|
const publish_quote_price_1 = require("./publish_quote_price");
|
|
7
8
|
const to_price_message_1 = require("./to_price_message");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
9
|
+
const TICK_LIQUIDITY_INTERVAL_MS = parseInt(process.env.TICK_CACHE_FORCE_FULL_REFRESH_INTERVAL || '60000', 10);
|
|
10
|
+
const _tickLiquidityLastPush = new Map();
|
|
11
|
+
function on_quote_response(opts) {
|
|
12
|
+
const { appConfig, poolInfo, quoteAmountUsd, streamTime, quoteStartTime, blockNumber, quotes, txid, pushPriceMessage = true, source = '', depth, tickLiquidity, } = opts;
|
|
13
|
+
const quoteEndTime = Date.now();
|
|
14
|
+
const quoteAskPrice = Number(quotes[0].price);
|
|
15
|
+
const quoteBidPrice = Number(quotes[1].price);
|
|
16
|
+
const priceTime = Date.now();
|
|
14
17
|
const time = {
|
|
15
|
-
block_time,
|
|
16
|
-
stream_time,
|
|
17
|
-
quote_start_time,
|
|
18
|
-
quote_end_time,
|
|
19
|
-
price_time,
|
|
20
|
-
total_quote_time:
|
|
18
|
+
block_time: 0,
|
|
19
|
+
stream_time: streamTime,
|
|
20
|
+
quote_start_time: quoteStartTime,
|
|
21
|
+
quote_end_time: quoteEndTime,
|
|
22
|
+
price_time: priceTime,
|
|
23
|
+
total_quote_time: priceTime - streamTime
|
|
21
24
|
};
|
|
22
|
-
(0, to_price_message_1.to_price_message)(appConfig,
|
|
25
|
+
(0, to_price_message_1.to_price_message)(appConfig, quoteAmountUsd, 0, quoteAskPrice, quoteBidPrice, poolInfo, time, String(blockNumber), source, depth)
|
|
23
26
|
.then((price_msg) => {
|
|
24
|
-
if (
|
|
27
|
+
if (pushPriceMessage) {
|
|
25
28
|
(0, publish_quote_price_1.publish_quote_price)(appConfig, price_msg);
|
|
26
29
|
}
|
|
27
|
-
(0, log_quote_price_1.log_quote_price)(
|
|
28
|
-
(0, analyze_1.report_trade_analyze_data)('PriceMessageType', Object.assign(Object.assign({}, price_msg), { quote_source: { slot:
|
|
30
|
+
(0, log_quote_price_1.log_quote_price)(String(blockNumber), price_msg, txid);
|
|
31
|
+
(0, analyze_1.report_trade_analyze_data)('PriceMessageType', Object.assign(Object.assign({}, price_msg), { quote_source: { slot: String(blockNumber), block: null, txid } }));
|
|
32
|
+
if (depth) {
|
|
33
|
+
(0, analyze_1.report_trade_analyze_data)('DepthLevels', {
|
|
34
|
+
price_id: price_msg.price_id,
|
|
35
|
+
unique_orderbook_id: price_msg.unique_orderbook_id,
|
|
36
|
+
pair: price_msg.pair,
|
|
37
|
+
depth
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (tickLiquidity) {
|
|
41
|
+
const poolAddr = price_msg.pool_id || '';
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
const lastPush = _tickLiquidityLastPush.get(poolAddr) || 0;
|
|
44
|
+
if (now - lastPush >= TICK_LIQUIDITY_INTERVAL_MS) {
|
|
45
|
+
_tickLiquidityLastPush.set(poolAddr, now);
|
|
46
|
+
tickLiquidity.pair = price_msg.pair;
|
|
47
|
+
tickLiquidity.protocolId = price_msg.dex_id;
|
|
48
|
+
(0, analyze_1.report_trade_analyze_data)('TickLiquidity', tickLiquidity);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
})
|
|
52
|
+
.catch(err => {
|
|
53
|
+
console.error(`[on_quote_response] error: ${(err === null || err === void 0 ? void 0 : err.message) || err}`);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function on_quote_respose(appConfig, pool_info, quote_amount_usd, _execution_price, stream_time, quote_start_time, slot_info, result, txid, push_price_message = true, source = "", depth) {
|
|
57
|
+
on_quote_response({
|
|
58
|
+
appConfig,
|
|
59
|
+
poolInfo: pool_info,
|
|
60
|
+
quoteAmountUsd: quote_amount_usd,
|
|
61
|
+
streamTime: stream_time,
|
|
62
|
+
quoteStartTime: quote_start_time,
|
|
63
|
+
blockNumber: parseInt(slot_info, 10) || 0,
|
|
64
|
+
quotes: [result[0], result[1]],
|
|
65
|
+
txid,
|
|
66
|
+
pushPriceMessage: push_price_message,
|
|
67
|
+
source,
|
|
68
|
+
depth,
|
|
29
69
|
});
|
|
30
70
|
}
|
|
@@ -32,6 +32,7 @@ const get_quote_token_decimals = (pool_info) => {
|
|
|
32
32
|
exports.get_quote_token_decimals = get_quote_token_decimals;
|
|
33
33
|
function to_price_message(appConfig_1, quote_amount_usd_1, tx_price_1, quote_ask_price_1, quote_bid_price_1, pool_info_1, time_1, slot_1) {
|
|
34
34
|
return __awaiter(this, arguments, void 0, function* (appConfig, quote_amount_usd, tx_price, quote_ask_price, quote_bid_price, pool_info, time, slot, source = "", depth) {
|
|
35
|
+
var _a, _b;
|
|
35
36
|
let { pool_address, tokenA, tokenB } = pool_info;
|
|
36
37
|
let { dex_id, pool_name, fee_rate, is_reverse_token } = yield appConfig.arb_cache.get_one_pool_info(pool_address);
|
|
37
38
|
let _dex_id = dex_id;
|
|
@@ -50,20 +51,15 @@ function to_price_message(appConfig_1, quote_amount_usd_1, tx_price_1, quote_ask
|
|
|
50
51
|
price: bid_price,
|
|
51
52
|
quantity: quote_amount_usd
|
|
52
53
|
};
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
bidData[`depth_${bps}_usd`] = data.amountUsd.toFixed(2);
|
|
63
|
-
if (data.tickMove)
|
|
64
|
-
bidData[`depth_${bps}_tick`] = data.tickMove;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
54
|
+
const cexBps = parseInt(process.env.DEPTH_CEX_BPS || '20');
|
|
55
|
+
const askDepth = (_a = depth === null || depth === void 0 ? void 0 : depth.ask) === null || _a === void 0 ? void 0 : _a[cexBps];
|
|
56
|
+
const bidDepth = (_b = depth === null || depth === void 0 ? void 0 : depth.bid) === null || _b === void 0 ? void 0 : _b[cexBps];
|
|
57
|
+
askData.depth_bps = cexBps;
|
|
58
|
+
askData.depth_amount = askDepth ? askDepth.amount.toFixed(6) : '0';
|
|
59
|
+
askData.depth_usd = askDepth ? askDepth.amountUsd.toFixed(2) : '0';
|
|
60
|
+
bidData.depth_bps = cexBps;
|
|
61
|
+
bidData.depth_amount = bidDepth ? bidDepth.amount.toFixed(6) : '0';
|
|
62
|
+
bidData.depth_usd = bidDepth ? bidDepth.amountUsd.toFixed(2) : '0';
|
|
67
63
|
let price_message = {
|
|
68
64
|
chain_id,
|
|
69
65
|
dex_id,
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.AbstractTransactionResultCheck = void 0;
|
|
13
13
|
const __1 = require("..");
|
|
14
|
+
const analyze_1 = require("../analyze");
|
|
14
15
|
class AbstractTransactionResultCheck {
|
|
15
16
|
constructor(env_args, event_emitter) {
|
|
16
17
|
this.env_args = env_args;
|
|
@@ -49,6 +50,7 @@ class AbstractTransactionResultCheck {
|
|
|
49
50
|
});
|
|
50
51
|
}
|
|
51
52
|
map_swap_result_to_tx_result(swap_result) {
|
|
53
|
+
var _a;
|
|
52
54
|
let { success, error_code, wallet, block_number, block_time: order_block_time, txid, tx_price, tokenA, tokenB, gas_fee } = swap_result;
|
|
53
55
|
if (this.context.ui_tip_amount) {
|
|
54
56
|
gas_fee.priority_fee = this.context.ui_tip_amount;
|
|
@@ -78,6 +80,15 @@ class AbstractTransactionResultCheck {
|
|
|
78
80
|
order_end_time,
|
|
79
81
|
total_order_time,
|
|
80
82
|
};
|
|
83
|
+
time.order_block_number = block_number || 0;
|
|
84
|
+
const _marks = (_a = this.context) === null || _a === void 0 ? void 0 : _a._execution_marks;
|
|
85
|
+
if (_marks) {
|
|
86
|
+
;
|
|
87
|
+
time.caller_ready_time = _marks['caller'] || 0;
|
|
88
|
+
time.encode_done_time = _marks['encode'] || 0;
|
|
89
|
+
time.sign_done_time = _marks['sign'] || 0;
|
|
90
|
+
time.tx_send_time = _marks['sent'] || 0;
|
|
91
|
+
}
|
|
81
92
|
let broadcast = [];
|
|
82
93
|
broadcast.push({
|
|
83
94
|
rpc: {
|
|
@@ -137,6 +148,7 @@ class AbstractTransactionResultCheck {
|
|
|
137
148
|
execution: trade_extra_info,
|
|
138
149
|
c_id
|
|
139
150
|
};
|
|
151
|
+
(0, analyze_1.report_trade_analyze_data)('TradeResultType', trade_result);
|
|
140
152
|
return trade_result;
|
|
141
153
|
}
|
|
142
154
|
}
|
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.handle_order_message = exports.try_lock_order_msg = void 0;
|
|
13
13
|
const __1 = require("..");
|
|
14
|
+
const analyze_1 = require("../analyze");
|
|
14
15
|
const logger = (0, __1.createLogger)(__filename);
|
|
15
16
|
const trade_context_1 = require("./trade_context");
|
|
16
17
|
const check_parse_order_msg = (appConfig, order_msg) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -108,10 +109,13 @@ const handle_order_message = (trade_appconfig, trade_instance, tx_result_checker
|
|
|
108
109
|
};
|
|
109
110
|
}
|
|
110
111
|
finally {
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
const order_msg_with_result = Object.assign(Object.assign({}, order_msg), { order_submit_result });
|
|
113
|
+
trade_appconfig.arb_cache.cache_order_message(order_msg_with_result)
|
|
114
|
+
.then(() => { })
|
|
115
|
+
.catch(err => {
|
|
113
116
|
logger.warn('cache order submit result, error!', { order_msg, order_submit_result, err });
|
|
114
117
|
});
|
|
118
|
+
(0, analyze_1.report_trade_analyze_data)('OrderMessageType', order_msg_with_result);
|
|
115
119
|
}
|
|
116
120
|
});
|
|
117
121
|
exports.handle_order_message = handle_order_message;
|
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -511,6 +511,13 @@ export interface TradeTimeFlowType extends QuoteTimeInfoType {
|
|
|
511
511
|
order_end_time: number // dex 解析得到交易结果的时间
|
|
512
512
|
order_block_time: number // dex 交易所在区块的出块时间
|
|
513
513
|
total_order_time: number // dex 交易耗时: order_end_time - order_recv_time
|
|
514
|
+
// trade-analyze 扩展
|
|
515
|
+
order_block_number?: number // 交易所在区块号
|
|
516
|
+
order_tx_index?: number // 交易在区块内的位置
|
|
517
|
+
caller_ready_time?: number // 获取到 Caller Wallet 的时间
|
|
518
|
+
encode_done_time?: number // 交易编码完成时间
|
|
519
|
+
sign_done_time?: number // 交易签名完成时间
|
|
520
|
+
tx_send_time?: number // 交易发送到 RPC 的时间
|
|
514
521
|
}
|
|
515
522
|
|
|
516
523
|
// TRANSACTION BROADCASTING
|
|
@@ -784,3 +791,212 @@ export declare class RedisCommand {
|
|
|
784
791
|
}
|
|
785
792
|
|
|
786
793
|
|
|
794
|
+
/*********************************************************************
|
|
795
|
+
* TRADE ANALYZE TYPES *
|
|
796
|
+
*********************************************************************/
|
|
797
|
+
|
|
798
|
+
// ═══ PreTrade: 事前 - 事件感知延迟 + Provider 对比 ═══
|
|
799
|
+
|
|
800
|
+
export interface PreTradeEventType {
|
|
801
|
+
pool_address: string
|
|
802
|
+
pair: string
|
|
803
|
+
dex_id: string
|
|
804
|
+
event_type: string // Sync | Swap | Mint | Burn | ModifyLiquidity
|
|
805
|
+
source_txid: string
|
|
806
|
+
log_index: number
|
|
807
|
+
tx_index: number // 交易在区块内的位置
|
|
808
|
+
|
|
809
|
+
// 时间线
|
|
810
|
+
block_time: number // 链上出块时间 (ms),analyze 端通过 PriceMessage 缓存补充
|
|
811
|
+
block_number: number
|
|
812
|
+
stream_recv_time: number // RPC/WS 推送到达本地
|
|
813
|
+
|
|
814
|
+
// Provider
|
|
815
|
+
provider_id: string
|
|
816
|
+
subscribe_mode: string // SINGLE | MULTI
|
|
817
|
+
|
|
818
|
+
// 事件内容(stream-quote 已解析好的数据,标准化上报)
|
|
819
|
+
// AMM (Sync)
|
|
820
|
+
reserve0?: string
|
|
821
|
+
reserve1?: string
|
|
822
|
+
// CLMM (Swap)
|
|
823
|
+
amount0?: string
|
|
824
|
+
amount1?: string
|
|
825
|
+
sqrtPriceX96?: string
|
|
826
|
+
tick?: number
|
|
827
|
+
liquidity?: string
|
|
828
|
+
// Liquidity (Mint/Burn/ModifyLiquidity)
|
|
829
|
+
tickLower?: number
|
|
830
|
+
tickUpper?: number
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
export interface ProviderComparisonType {
|
|
834
|
+
event_key: string // blockNumber_txHash_logIndex
|
|
835
|
+
pool_address: string
|
|
836
|
+
event_type: string
|
|
837
|
+
providers: ProviderArrivalType[]
|
|
838
|
+
fastest_provider: string
|
|
839
|
+
max_gap_ms: number
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
export interface ProviderArrivalType {
|
|
843
|
+
provider_id: string
|
|
844
|
+
stream_recv_time: number
|
|
845
|
+
delta_vs_fastest_ms: number
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// ═══ OnTrade: 事中 - 价格偏差 / 深度验证 / 执行时间线 ═══
|
|
849
|
+
|
|
850
|
+
export interface OnTradeType {
|
|
851
|
+
id: string // unique_order_msg_id
|
|
852
|
+
txid: string
|
|
853
|
+
price_id: string // 关联键:串联 PriceMessage ↔ Order ↔ TradeResult
|
|
854
|
+
unique_orderbook_id: string // 关联键:定位 Pool 的所有报价
|
|
855
|
+
pool_address: string
|
|
856
|
+
pair: string
|
|
857
|
+
dex_id: string
|
|
858
|
+
group_id: string
|
|
859
|
+
chain_id: string
|
|
860
|
+
direction: 'BUY' | 'SELL'
|
|
861
|
+
|
|
862
|
+
price: OnTradePriceType
|
|
863
|
+
depth: OnTradeDepthType
|
|
864
|
+
execution: OnTradeExecutionType
|
|
865
|
+
result: OnTradeResultType
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
export interface OnTradePriceType {
|
|
869
|
+
quote_ask: string
|
|
870
|
+
quote_bid: string
|
|
871
|
+
cex_price: string
|
|
872
|
+
exec_price: string
|
|
873
|
+
/** 报价 vs 成交偏差 (bps), 正=成交比报价差 */
|
|
874
|
+
quote_exec_deviation_bps: number
|
|
875
|
+
/** CEX vs DEX 价差 (bps) */
|
|
876
|
+
cex_dex_spread_bps: number
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
export interface OnTradeDepthType {
|
|
880
|
+
levels: Record<number, AnalyzeDepthLevelType>
|
|
881
|
+
trade_size_usd: number
|
|
882
|
+
/** 交易量消耗了多少可用深度 (%) */
|
|
883
|
+
depth_utilization_pct: number
|
|
884
|
+
estimated_slippage_bps: number
|
|
885
|
+
actual_slippage_bps: number
|
|
886
|
+
/** 滑点偏差 = actual - estimated (bps) */
|
|
887
|
+
slippage_deviation_bps: number
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
export interface AnalyzeDepthLevelType {
|
|
891
|
+
amount: number
|
|
892
|
+
amount_usd: number
|
|
893
|
+
amount_in: number
|
|
894
|
+
amount_in_usd: number
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
export interface OnTradeExecutionType {
|
|
898
|
+
order_send_time: number // CEX 发出
|
|
899
|
+
order_recv_time: number // DEX 收到
|
|
900
|
+
caller_ready_time: number // Caller 就绪
|
|
901
|
+
encode_done_time: number // 编码完成
|
|
902
|
+
sign_done_time: number // 签名完成
|
|
903
|
+
tx_send_time: number // 发送上链
|
|
904
|
+
tx_block_time: number // 交易被打包的区块时间
|
|
905
|
+
tx_block_number: number
|
|
906
|
+
tx_index: number // 区块内位置
|
|
907
|
+
tx_confirmed_time: number // 监控到结果
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
export interface OnTradeResultType {
|
|
911
|
+
success: boolean
|
|
912
|
+
error_code?: string
|
|
913
|
+
token_in: AnalyzeTokenAmountType
|
|
914
|
+
token_out: AnalyzeTokenAmountType
|
|
915
|
+
gas_used: number
|
|
916
|
+
gas_price_gwei: number
|
|
917
|
+
gas_cost_usd: number
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
export interface AnalyzeTokenAmountType {
|
|
921
|
+
symbol: string
|
|
922
|
+
amount: number
|
|
923
|
+
value_usd: number
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// ═══ PostTrade: 事后 - 交易回溯 ═══
|
|
927
|
+
|
|
928
|
+
export interface PostTradeType {
|
|
929
|
+
txid: string
|
|
930
|
+
pair: string
|
|
931
|
+
pool_address: string
|
|
932
|
+
dex_id: string
|
|
933
|
+
direction: 'BUY' | 'SELL'
|
|
934
|
+
|
|
935
|
+
/** 时间窗口: 报价生成 → 交易上链 */
|
|
936
|
+
window_start: number
|
|
937
|
+
window_end: number
|
|
938
|
+
window_duration_ms: number
|
|
939
|
+
|
|
940
|
+
/** 触发下单的那次报价 */
|
|
941
|
+
trigger_quote: AnalyzeQuoteSnapshotType
|
|
942
|
+
/** 窗口内该 Pool 的所有报价 */
|
|
943
|
+
quote_sequence: AnalyzeQuoteSnapshotType[]
|
|
944
|
+
/** 第一条 vs 最后一条报价的价格变化 (bps) */
|
|
945
|
+
price_drift_bps: number
|
|
946
|
+
|
|
947
|
+
/** 窗口内该 Pool 上发生的链上事件 */
|
|
948
|
+
intervening_events: AnalyzePoolEventType[]
|
|
949
|
+
event_summary: AnalyzeEventSummaryType
|
|
950
|
+
|
|
951
|
+
/** 同区块分析 (MEV) */
|
|
952
|
+
same_block: AnalyzeSameBlockType
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
export interface AnalyzeQuoteSnapshotType {
|
|
956
|
+
price_id: string
|
|
957
|
+
ask: string
|
|
958
|
+
bid: string
|
|
959
|
+
block_number: number
|
|
960
|
+
source_txid: string
|
|
961
|
+
stream_recv_time: number
|
|
962
|
+
price_ready_time: number
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
export interface AnalyzePoolEventType {
|
|
966
|
+
txid: string
|
|
967
|
+
block_number: number
|
|
968
|
+
tx_index: number
|
|
969
|
+
event_type: 'SWAP' | 'MINT' | 'BURN' | 'MODIFY_LIQUIDITY'
|
|
970
|
+
timestamp: number
|
|
971
|
+
swap?: {
|
|
972
|
+
direction: 'BUY' | 'SELL'
|
|
973
|
+
amount_in: string
|
|
974
|
+
amount_out: string
|
|
975
|
+
price: string
|
|
976
|
+
}
|
|
977
|
+
liquidity?: {
|
|
978
|
+
tick_lower?: number
|
|
979
|
+
tick_upper?: number
|
|
980
|
+
amount0: string
|
|
981
|
+
amount1: string
|
|
982
|
+
}
|
|
983
|
+
/** 该事件对价格的影响 (bps) */
|
|
984
|
+
price_impact_bps: number
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
export interface AnalyzeEventSummaryType {
|
|
988
|
+
swap_count: number
|
|
989
|
+
mint_count: number
|
|
990
|
+
burn_count: number
|
|
991
|
+
total_count: number
|
|
992
|
+
cumulative_price_impact_bps: number
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
export interface AnalyzeSameBlockType {
|
|
996
|
+
my_tx_index: number
|
|
997
|
+
before_me: AnalyzePoolEventType[]
|
|
998
|
+
after_me: AnalyzePoolEventType[]
|
|
999
|
+
sandwich_detected: boolean
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
|