Trong thị trường crypto, mỗi mili-giây đều có ý nghĩa. Việc phân tích L2 Order Book (sổ lệnh mức 2) giúp nhà giao dịch hiểu rõ áp lực mua/bán, dự đoán điểm break-out và tối ưu hóa chiến lược. Bài viết này sẽ hướng dẫn bạn cách sử dụng Tardis API để tải historical tick data và xây dựng hệ thống phân tích micro-structure hoàn chỉnh.
Tại sao L2 Order Book quan trọng với trader BTC/ETH?
L2 Order Book cung cấp thông tin chi tiết về các lệnh đặt mua/bán ở mỗi mức giá. Khác với chỉ báo thuần túy (RSI, MACD), Order Book cho thấy "dòng tiền thật sự" đang ở đâu:
- Bid/Ask Depth: Độ sâu thị trường tại mỗi mức giá
- Order Flow Imbalance (OFI): Chênh lệch giữa khối lượng bid mới và ask mới
- Price Impact: Dự đoán mức giá di chuyển khi có large order
- Liquidity Detection: Phát hiện vùng hỗ trợ/kháng cự ẩn
Kiến trúc hệ thống回测
┌─────────────────────────────────────────────────────────────┐
│ Tardis API │
│ Historical Tick Data → Real-time WebSocket → Replay │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Data Processing Layer │
│ ├── Parse L2 Update (bids/asks snapshot) │
│ ├── Calculate OFI (Order Flow Imbalance) │
│ ├── Compute VWAP, TWAP at micro-level │
│ └── Detect Iceberg Orders (hidden liquidity) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Strategy Engine │
│ ├── Mean Reversion on L2 Imbalance │
│ ├── Momentum on Large Bid/Ask Ratio │
│ └── Break-out on Order Book Unfolding │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Backtest Engine │
│ ├── High-fidelity tick-by-tick replay │
│ ├── Slippage & Fee modeling │
│ └── Performance Metrics (Sharpe, Drawdown, Win Rate) │
└─────────────────────────────────────────────────────────────┘
Kết nối Tardis API - Bước đầu tiên
Để bắt đầu回测, bạn cần kết nối với Tardis để lấy dữ liệu lịch sử. Tardis cung cấp API RESTful với độ trễ thấp và dữ liệu được chuẩn hóa cho nhiều sàn giao dịch.
const axios = require('axios');
class TardisClient {
constructor(apiKey) {
this.baseUrl = 'https://api.tardis.dev/v1';
this.apiKey = apiKey;
this.headers = {
'Authorization': Bearer ${this.apiKey},
'Content-Type': 'application/json'
};
}
// Lấy danh sách các sàn giao dịch được hỗ trợ
async getExchanges() {
const response = await axios.get(
${this.baseUrl}/exchanges,
{ headers: this.headers }
);
return response.data;
}
// Lấy danh sách symbols cho một sàn
async getSymbols(exchange) {
const response = await axios.get(
${this.baseUrl}/exchanges/${exchange}/symbols,
{ headers: this.headers }
);
return response.data;
}
// Lấy thông tin về dữ liệu có sẵn cho một symbol
async getSymbolDetails(exchange, symbol) {
const response = await axios.get(
${this.baseUrl}/exchanges/${exchange}/symbols/${symbol},
{ headers: this.headers }
);
return response.data;
}
// Tải historical L2 order book data
async getHistoricalOrderBook(exchange, symbol, from, to) {
const params = {
from: Math.floor(new Date(from).getTime() / 1000),
to: Math.floor(new Date(to).getTime() / 1000),
format: 'json'
};
const response = await axios.get(
${this.baseUrl}/historical/${exchange}/${symbol}/orderbook-l2,
{
headers: this.headers,
params: params
}
);
return response.data;
}
// Tải historical trades/recks
async getHistoricalTrades(exchange, symbol, from, to) {
const params = {
from: Math.floor(new Date(from).getTime() / 1000),
to: Math.floor(new Date(to).getTime() / 1000),
format: 'json'
};
const response = await axios.get(
${this.baseUrl}/historical/${exchange}/${symbol}/trades,
{
headers: this.headers,
params: params
}
);
return response.data;
}
}
// Ví dụ sử dụng
const tardis = new TardisClient('YOUR_TARDIS_API_KEY');
async function main() {
try {
// Lấy danh sách sàn hỗ trợ
const exchanges = await tardis.getExchanges();
console.log('Sàn hỗ trợ:', exchanges.map(e => e.name));
// Lấy symbols cho Binance
const binanceSymbols = await tardis.getSymbols('binance');
const btcSymbol = binanceSymbols.find(s => s.symbol.includes('BTC'));
console.log('BTC Symbol:', btcSymbol);
// Tải dữ liệu order book cho BTCUSDT
const orderBookData = await tardis.getHistoricalOrderBook(
'binance',
'BTCUSDT',
'2026-01-01T00:00:00Z',
'2026-01-01T01:00:00Z'
);
console.log('Order Book Data Points:', orderBookData.length);
} catch (error) {
console.error('Lỗi khi kết nối Tardis:', error.message);
}
}
main();
Xây dựng L2 Order Book Processor
Đây là phần core của hệ thống - xử lý raw L2 data và tính toán các chỉ báo micro-structure.
class L2OrderBookProcessor {
constructor() {
this.bids = new Map(); // price -> {qty, orders}
this.asks = new Map();
this.sequence = 0;
this.trades = [];
// Các ngưỡng cho phân tích
this.thresholds = {
imbalanceAlert: 0.3, // OFI ngưỡng cảnh báo
largeOrderThreshold: 5, // Đơn vị BTC
depthLevels: 10 // Số mức giá để phân tích
};
}
// Cập nhật order book từ L2 snapshot
updateFromSnapshot(snapshot) {
const timestamp = snapshot.timestamp || Date.now();
// Parse bids
for (const [price, qty] of Object.entries(snapshot.bids || {})) {
if (parseFloat(qty) === 0) {
this.bids.delete(parseFloat(price));
} else {
this.bids.set(parseFloat(price), {
qty: parseFloat(qty),
timestamp: timestamp
});
}
}
// Parse asks
for (const [price, qty] of Object.entries(snapshot.asks || {})) {
if (parseFloat(qty) === 0) {
this.asks.delete(parseFloat(price));
} else {
this.asks.set(parseFloat(price), {
qty: parseFloat(qty),
timestamp: timestamp
});
}
}
}
// Cập nhật từ L2 update (delta)
updateFromDelta(delta) {
// Áp dụng các thay đổi
for (const update of delta) {
const { side, price, qty } = update;
const book = side === 'buy' ? this.bids : this.asks;
if (parseFloat(qty) === 0) {
book.delete(parseFloat(price));
} else {
book.set(parseFloat(price), {
qty: parseFloat(qty),
timestamp: delta.timestamp
});
}
}
this.sequence = delta.sequence || this.sequence + 1;
}
// Tính Order Flow Imbalance (OFI)
calculateOFI(windowMs = 1000) {
const now = Date.now();
const windowStart = now - windowMs;
let bidVolumeChange = 0;
let askVolumeChange = 0;
// Lọc các thay đổi trong window
for (const [price, data] of this.bids) {
if (data.timestamp >= windowStart) {
bidVolumeChange += data.qty;
}
}
for (const [price, data] of this.asks) {
if (data.timestamp >= windowStart) {
askVolumeChange += data.qty;
}
}
const totalVolume = bidVolumeChange + askVolumeChange;
if (totalVolume === 0) return 0;
// OFI = (Bid Change - Ask Change) / Total
const ofi = (bidVolumeChange - askVolumeChange) / totalVolume;
return Math.max(-1, Math.min(1, ofi)); // Normalize về [-1, 1]
}
// Tính micro VWAP
calculateMicroVWAP(trades, windowMs = 5000) {
const now = Date.now();
const windowStart = now - windowMs;
let totalVolume = 0;
let volumeWeightedPrice = 0;
for (const trade of trades) {
if (trade.timestamp >= windowStart) {
volumeWeightedPrice += trade.price * trade.qty;
totalVolume += trade.qty;
}
}
return totalVolume > 0 ? volumeWeightedPrice / totalVolume : null;
}
// Phát hiện vùng liquidity
detectLiquidityZones(levels = 10) {
const sortedBids = [...this.bids.entries()]
.sort((a, b) => b[0] - a[0])
.slice(0, levels);
const sortedAsks = [...this.asks.entries()]
.sort((a, b) => a[0] - b[0])
.slice(0, levels);
const midPrice = this.getMidPrice();
return {
bidZones: sortedBids.map(([price, data]) => ({
price,
qty: data.qty,
distanceFromMid: ((midPrice - price) / midPrice * 100).toFixed(4) + '%'
})),
askZones: sortedAsks.map(([price, data]) => ({
price,
qty: data.qty,
distanceFromMid: ((price - midPrice) / midPrice * 100).toFixed(4) + '%'
})),
midPrice
};
}
// Phát hiện Iceberg Orders
detectIcebergs() {
const icebergCandidates = [];
// Kiểm tra các lệnh lớn bất thường
for (const [price, data] of this.bids) {
if (data.qty >= this.thresholds.largeOrderThreshold) {
// Tính tỷ lệ so với tổng bid depth
const totalBidDepth = [...this.bids.values()]
.reduce((sum, d) => sum + d.qty, 0);
const ratio = data.qty / totalBidDepth;
if (ratio > 0.5) {
icebergCandidates.push({
side: 'buy',
price,
qty: data.qty,
ratio: (ratio * 100).toFixed(2) + '%',
type: ratio > 0.8 ? 'LARGE ICEBERG' : 'WHALE ORDER'
});
}
}
}
for (const [price, data] of this.asks) {
if (data.qty >= this.thresholds.largeOrderThreshold) {
const totalAskDepth = [...this.asks.values()]
.reduce((sum, d) => sum + d.qty, 0);
const ratio = data.qty / totalAskDepth;
if (ratio > 0.5) {
icebergCandidates.push({
side: 'sell',
price,
qty: data.qty,
ratio: (ratio * 100).toFixed(2) + '%',
type: ratio > 0.8 ? 'LARGE ICEBERG' : 'WHALE ORDER'
});
}
}
}
return icebergCandidates;
}
getMidPrice() {
const bestBid = Math.max(...this.bids.keys());
const bestAsk = Math.min(...this.asks.keys());
return (bestBid + bestAsk) / 2;
}
getSpread() {
const bestBid = Math.max(...this.bids.keys());
const bestAsk = Math.min(...this.asks.keys());
return {
absolute: bestAsk - bestBid,
percentage: ((bestAsk - bestBid) / this.getMidPrice() * 100).toFixed(4) + '%'
};
}
// Lấy depth summary
getDepthSummary() {
const bidDepth = [...this.bids.values()]
.reduce((sum, d) => sum + d.qty, 0);
const askDepth = [...this.asks.values()]
.reduce((sum, d) => sum + d.qty, 0);
return {
totalBidDepth: bidDepth,
totalAskDepth: askDepth,
imbalance: ((bidDepth - askDepth) / (bidDepth + askDepth)).toFixed(4),
bidAskRatio: (bidDepth / askDepth).toFixed(4)
};
}
}
// Ví dụ sử dụng
const processor = new L2OrderBookProcessor();
// Giả lập dữ liệu L2
processor.updateFromSnapshot({
timestamp: Date.now(),
bids: {
42150.50: 2.5,
42150.00: 1.8,
42149.50: 3.2,
42149.00: 5.0, // Whale order tiềm năng
42148.50: 1.2
},
asks: {
42151.00: 1.5,
42151.50: 2.0,
42152.00: 4.5,
42152.50: 1.0,
42153.00: 3.0
}
});
console.log('=== Order Book Analysis ===');
console.log('Mid Price:', processor.getMidPrice());
console.log('Spread:', processor.getSpread());
console.log('Depth Summary:', processor.getDepthSummary());
console.log('Liquidity Zones:', processor.detectLiquidityZones());
console.log('Iceberg Detection:', processor.detectIcebergs());
Xây dựng Strategy Engine回测
Sau khi có L2 Processor, chúng ta xây dựng strategy engine để backtest các chiến lược giao dịch dựa trên micro-structure.
class MicroStructureStrategy {
constructor(initialCapital = 10000) {
this.capital = initialCapital;
this.position = 0;
this.trades = [];
this.equityCurve = [];
// Các tham số strategy
this.params = {
ofiThreshold: 0.25, // Ngưỡng OFI để vào lệnh
stopLoss: 0.002, // 0.2% stop loss
takeProfit: 0.005, // 0.5% take profit
positionSize: 0.1, // 10% vốn mỗi lệnh
reEntryDelay: 5000 // 5 giây chờ re-entry
};
// State tracking
this.lastTradeTime = 0;
this.currentOFI = 0;
this.priceHistory = [];
}
// Cập nhật OFI
updateOFI(ofi) {
this.currentOFI = ofi;
}
// Cập nhật giá
updatePrice(price, timestamp) {
this.priceHistory.push({ price, timestamp });
// Giữ chỉ 100 data points gần nhất
if (this.priceHistory.length > 100) {
this.priceHistory.shift();
}
}
// Kiểm tra điều kiện vào lệnh
checkEntryConditions(orderBookState) {
const now = Date.now();
// Kiểm tra re-entry delay
if (now - this.lastTradeTime < this.params.reEntryDelay) {
return { signal: 'NONE', reason: 'Re-entry delay' };
}
// Chiến lược 1: OFI Mean Reversion
const ofiSignal = this.analyzeOFI();
// Chiến lược 2: Order Book Imbalance
const imbalanceSignal = this.analyzeImbalance(orderBookState);
// Chiến lược 3: Break-out Detection
const breakoutSignal = this.analyzeBreakout();
// Tổng hợp tín hiệu
let finalSignal = 'NONE';
let confidence = 0;
if (ofiSignal !== 'NONE') {
confidence += ofiSignal === 'BUY' ? 1 : -1;
}
if (imbalanceSignal !== 'NONE') {
confidence += imbalanceSignal === 'BUY' ? 1 : -1;
}
if (breakoutSignal !== 'NONE') {
confidence += breakoutSignal === 'BUY' ? 1 : -1;
}
if (confidence >= 2) finalSignal = 'BUY';
else if (confidence <= -2) finalSignal = 'SELL';
return {
signal: finalSignal,
confidence,
breakdown: { ofiSignal, imbalanceSignal, breakoutSignal }
};
}
analyzeOFI() {
// Mean reversion: OFI quá cao -> đảo chiều, OFI quá thấp -> đảo chiều
if (this.currentOFI > this.params.ofiThreshold) {
return 'SELL'; // Quá nhiều buy pressure -> có thể đảo
} else if (this.currentOFI < -this.params.ofiThreshold) {
return 'BUY'; // Quá nhiều sell pressure -> có thể đảo
}
return 'NONE';
}
analyzeImbalance(orderBookState) {
const imbalance = parseFloat(orderBookState.imbalance);
// Nếu bid depth >> ask depth -> có thể break-up
if (imbalance > 0.3) {
return 'BUY';
} else if (imbalance < -0.3) {
return 'SELL';
}
return 'NONE';
}
analyzeBreakout() {
if (this.priceHistory.length < 20) return 'NONE';
const recent = this.priceHistory.slice(-20);
const prices = recent.map(p => p.price);
const max = Math.max(...prices);
const min = Math.min(...prices);
const current = prices[prices.length - 1];
const range = max - min;
// Break-out upward: giá gần max với range lớn
if (current > max - range * 0.1 && range / current > 0.001) {
return 'BUY';
}
// Break-out downward
if (current < min + range * 0.1 && range / current > 0.001) {
return 'SELL';
}
return 'NONE';
}
// Thực hiện lệnh
executeTrade(signal, price, timestamp) {
if (signal === 'NONE' || this.position !== 0) {
return null;
}
const positionValue = this.capital * this.params.positionSize;
const qty = positionValue / price;
const cost = qty * price;
const fee = cost * 0.001; // 0.1% fee
const trade = {
side: signal,
entryPrice: price,
qty,
cost,
fee,
timestamp,
pnl: 0,
exitPrice: null
};
if (signal === 'BUY') {
this.position = qty;
} else {
this.position = -qty;
}
this.trades.push(trade);
this.lastTradeTime = timestamp;
return trade;
}
// Kiểm tra điều kiện thoát lệnh
checkExitConditions(currentPrice, timestamp) {
if (this.position === 0) return null;
const lastTrade = this.trades[this.trades.length - 1];
const pnlPercent = this.position > 0
? (currentPrice - lastTrade.entryPrice) / lastTrade.entryPrice
: (lastTrade.entryPrice - currentPrice) / lastTrade.entryPrice;
// Stop loss
if (pnlPercent <= -this.params.stopLoss) {
return this.closeTrade(currentPrice, timestamp, 'STOP_LOSS');
}
// Take profit
if (pnlPercent >= this.params.takeProfit) {
return this.closeTrade(currentPrice, timestamp, 'TAKE_PROFIT');
}
return null;
}
closeTrade(price, timestamp, reason) {
const lastTrade = this.trades[this.trades.length - 1];
const pnl = this.position * price - this.position * lastTrade.entryPrice;
const fee = Math.abs(this.position * price * 0.001);
lastTrade.exitPrice = price;
lastTrade.pnl = pnl - fee;
lastTrade.exitReason = reason;
this.capital += pnl - fee;
this.position = 0;
return lastTrade;
}
// Tính toán metrics hiệu suất
calculatePerformance() {
if (this.trades.length === 0) {
return { message: 'Không có giao dịch nào được thực hiện' };
}
const closedTrades = this.trades.filter(t => t.exitPrice);
const totalPnl = closedTrades.reduce((sum, t) => sum + t.pnl, 0);
const winTrades = closedTrades.filter(t => t.pnl > 0);
const loseTrades = closedTrades.filter(t => t.pnl <= 0);
const avgWin = winTrades.length > 0
? winTrades.reduce((sum, t) => sum + t.pnl, 0) / winTrades.length
: 0;
const avgLoss = loseTrades.length > 0
? Math.abs(loseTrades.reduce((sum, t) => sum + t.pnl, 0) / loseTrades.length)
: 0;
const maxDrawdown = this.calculateMaxDrawdown();
return {
totalTrades: closedTrades.length,
winRate: (winTrades.length / closedTrades.length * 100).toFixed(2) + '%',
totalPnl: totalPnl.toFixed(2),
avgWin: avgWin.toFixed(2),
avgLoss: avgLoss.toFixed(2),
profitFactor: avgLoss > 0 ? (avgWin * winTrades.length / (avgLoss * loseTrades.length)).toFixed(2) : '∞',
maxDrawdown: maxDrawdown.toFixed(2),
finalCapital: this.capital.toFixed(2),
returnPercent: ((this.capital - 10000) / 10000 * 100).toFixed(2) + '%'
};
}
calculateMaxDrawdown() {
let peak = 10000;
let maxDrawdown = 0;
for (const trade of this.trades) {
if (trade.pnl !== 0) {
const equity = 10000 + trade.pnl;
if (equity > peak) peak = equity;
const drawdown = (peak - equity) / peak;
if (drawdown > maxDrawdown) maxDrawdown = drawdown;
}
}
return maxDrawdown * 100;
}
}
// Ví dụ chạy backtest
const strategy = new MicroStructureStrategy(10000);
// Giả lập dữ liệu
const mockOrderBook = {
imbalance: 0.35,
totalBidDepth: 150,
totalAskDepth: 100
};
strategy.updatePrice(42150.00, Date.now());
strategy.updateOFI(0.28);
const entrySignal = strategy.checkEntryConditions(mockOrderBook);
console.log('Entry Signal:', entrySignal);
if (entrySignal.signal !== 'NONE') {
const trade = strategy.executeTrade(entrySignal.signal, 42150.00, Date.now());
console.log('Trade Executed:', trade);
}
Backtest Engine hoàn chỉnh
Giờ chúng ta kết hợp tất cả lại thành một backtest engine hoàn chỉnh, xử lý dữ liệu thực từ Tardis.
class TardisBacktestEngine {
constructor(config = {}) {
this.tardis = new TardisClient(config.tardisApiKey);
this.orderBookProcessor = new L2OrderBookProcessor();
this.strategy = new MicroStructureStrategy(config.initialCapital || 10000);
// Cấu hình
this.config = {
exchange: config.exchange || 'binance',
symbol: config.symbol || 'BTCUSDT',
startDate: config.startDate,
endDate: config.endDate,
...config
};
// Metrics
this.metrics = {
ticksProcessed: 0,
latency: [],
errors: []
};
}
async loadHistoricalData() {
console.log(Đang tải dữ liệu từ ${this.config.startDate} đến ${this.config.endDate}...);
try {
const [orderBookData, tradesData] = await Promise.all([
this.tardis.getHistoricalOrderBook(
this.config.exchange,
this.config.symbol,
this.config.startDate,
this.config.endDate
),
this.tardis.getHistoricalTrades(
this.config.exchange,
this.config.symbol,
this.config.startDate,
this.config.endDate
)
]);
console.log(Đã tải ${orderBookData.length} order book updates);
console.log(Đã tải ${tradesData.length} trades);
return { orderBookData, tradesData };
} catch (error) {
console.error('Lỗi khi tải dữ liệu:', error.message);
throw error;
}
}
async runBacktest(onProgress) {
const { orderBookData, tradesData } = await this.loadHistoricalData();
// Sort theo timestamp
orderBookData.sort((a, b) => a.timestamp - b.timestamp);
tradesData.sort((a, b) => a.timestamp - b.timestamp);
const totalTicks = orderBookData.length;
let tradeIndex = 0;
console.log(Bắt đầu backtest với ${totalTicks} ticks...);
for (let i = 0; i < totalTicks; i++) {
const tick = orderBookData[i];
const startTime = Date.now();
try {
// Cập nhật order book
if (tick.type === 'snapshot') {
this.orderBookProcessor.updateFromSnapshot(tick);
} else {
this.orderBookProcessor.updateFromDelta(tick);
}
// Cập nhật OFI
const ofi = this.orderBookProcessor.calculateOFI();
this.strategy.updateOFI(ofi);
// Cập nhật giá từ trades gần nhất
while (tradeIndex < tradesData.length &&
tradesData[tradeIndex].timestamp <= tick.timestamp) {
const trade = tradesData[tradeIndex];
this.strategy.updatePrice(trade.price, trade.timestamp);
// Kiểm tra exit conditions
const exitTrade = this.strategy.checkExitConditions(
trade.price,
trade.timestamp
);
if (exitTrade) {
console.log(EXIT: ${exitTrade.exitReason} @ ${exitTrade.exitPrice});
}
tradeIndex++;
}
// Kiểm tra entry conditions (mỗi 100 ticks để tiết kiệm compute)
if (i % 100 === 0) {
const orderBookState = this.orderBookProcessor.getDepthSummary();
const signal = this.strategy.checkEntryConditions(orderBookState);
if (signal.signal !== 'NONE') {
const lastPrice = this.strategy.priceHistory.slice(-1)[0]?.price;
if (lastPrice) {
const trade = this.strategy.executeTrade(
signal.signal,
lastPrice,
tick.timestamp
);
if (trade) {
console.log(ENTRY: ${signal.signal} @ ${trade.entryPrice});
}
}
}
}
this.metrics.ticksProcessed++;
// Progress reporting
if (onProgress && i % 1000 === 0) {
const progress = ((i / totalTicks) * 100).toFixed(1);
onProgress({
progress,
ticksProcessed: this.metrics.ticksProcessed,
capital: this.strategy.capital.toFixed(2)
});
}
} catch (error) {
this.metrics.errors.push({
timestamp: tick.timestamp,
error: error.message
});
}
// Track latency
const latency = Date.now() - startTime;
this.metrics.latency.push(latency);
}
return this.generateReport();
}
generateReport() {
const performance = this.strategy.calculatePerformance();
const avgLatency = this.metrics.latency.reduce((a, b) => a + b, 0) /
this.metrics.latency.length;
const maxLatency = Math.max(...this.metrics.latency);
return {
performance,
dataQuality: {
ticksProcessed: this.metrics.ticksProcessed,
errors: this.metrics.errors.length,
errorRate: (this.metrics.errors.length / this.metrics.ticksProcessed * 100).toFixed(4) + '%'
},
processingSpeed: {
avgLatencyMs: avgLatency.toFixed(2),
maxLatencyMs: maxLatency,
totalTimeMs: this.metrics.latency.reduce((a, b) => a + b, 0)
},
config: this.config
};
}
// Xuất kết quả ra file
exportResults(report, filename = 'backtest_report.json') {
const fs = require('fs');
fs.writeFileSync(filename, JSON.stringify(report, null, 2));
console.log(Đã lưu report vào ${filename});
}
}
// Chạy backtest
async function main() {
const engine = new TardisBacktestEngine({
tardisApiKey: 'YOUR_TARDIS_API_KEY',
exchange: 'binance',
symbol: 'BTCUSDT',
startDate: '2026-01-15T00:00:00Z',
endDate: '2026-01-16T00:00:00Z',
initialCapital: 10000
});
try {
const report = await engine.runBacktest((progress) => {
console.log(Tiến trình: ${progress.progress}% | Vốn: $${progress.capital});
});
console.log('\n=== BACKTEST REPORT ===');
console.log(JSON.stringify(report.performance, null, 2));
// Lưu report
engine.exportResults(report);
} catch (error) {
console.error('Backtest failed:', error);
}
}
main();
So sánh AI API cho phân tích dữ liệu回测
Trong quá trình xây dựng và tối ưu chiến lược, bạn có thể sử dụng AI để phân tích kết quả, generate code, và debug. Dưới đây là bảng so sánh chi phí thực tế:
| Model | Giá/MTok | Chi phí 10M tokens/tháng | Độ trễ trung bình | Phù hợp cho |
|---|---|---|---|---|
| DeepSeek V3.2 | $0.42 | $4,200 | ~45ms | Code generation, optimization |
| Gemini 2.5 Flash | $2.50 | $25,000 |
Tài nguyên liên quanBài viết liên quan🔥 Thử HolySheep AICổng AI API trực tiếp. Hỗ trợ Claude, GPT-5, Gemini, DeepSeek — một khóa, không cần VPN. |