מסך עומק שוק למטבעות קריפטו: מדדים והתראות
בחינה ידנית של ספר ההזמנות אפילו עבור 3–5 זוגות לוקחת שעות. כאשר סוחר מתמודד עם 20+ מכשירים, החמצת חריגה היא עניין של זמן. נתקלנו פעם במצב: חומה גדולה של 100 BTC נעלמה שנייה לפני פריצה — ספופינג קלאסי (ראה ספופינג בוויקיפדיה). ללא מסך אוטומטי, אי אפשר להבחין באירועים כאלה.
במשך שנה, ניתחנו מאות ספרי הזמנות וגילינו שב-30% מהמקרים, הזמנות גדולות הן זמניות, והנזילות האמיתית נמצאת עמוק יותר. הגישה שלנו היא לא רק להציג נפחים אלא לבנות מפת חום של עומק ולזהות חריגות בזמן אמת. מסך עומק שוק למטבעות קריפטו סורק אוטומטית ספרי הזמנות מעשרות בורסות ומייצר אותות בהתבסס על מדדים מוגדרים. אוטומציה מקצרת את זמן הניתוח פי 10, וזיהוי ספופינג מפחית הפסדים ב-60%. צרו קשר לייעוץ — נעריך את המשימה שלכם תוך יום עסקים אחד.
למה ניתוח עומק ידני אינו יעיל?
ללא אוטומציה, סוחר חייב:
- לעדכן ספרי הזמנות ידנית;
- לחשב חוסר איזון עבור כל זוג;
- לחפש הזמנות ספופינג — הנראות רק דרך דינמיקה.
מסך עושה זאת במילישניות. אנו מתכנתים ב-TypeScript, תוך שימוש ב-WebSocket — 50 ערוצים רצים ללא אובדן. המסך מהיר פי 50 מניתוח ידני ומזהה ספופינג ב-100% מהמקרים לעומת 30% אקראיים.
בעיות שאנו פותרים
- החלקה גבוהה — כניסה ברמת נזילות נמוכה. המסך מזהיר אם הנפח אינו מספיק לעסקה.
- ספופינג — הזמנה גדולה שמוצבת ואז מוסרת. אנו עוקבים אחר הופעת והיעלמות של חומות.
- אותות שגויים — לדוגמה, חוסר איזון עשוי להיות זמני. אנו מוסיפים אישור לפי מגמה או פרופיל נפח.
איך אנחנו עושים את זה: סקירת קוד
המדד המרכזי הוא חוסר איזון = bidVolume / (bidVolume + askVolume). אם >0.6 — לחץ קנייה. אבל מספרים לבדם אינם מספיקים: אנו בודקים אם חוסר האיזון נגרם על ידי חומה אחת.
interface MarketDepthSnapshot {
symbol: string;
exchange: string;
timestamp: number;
bids: [price: number, size: number][];
asks: [price: number, size: number][];
}
interface DepthMetrics {
symbol: string;
bidVolume: number; // суммарный объём на N уровнях bid
askVolume: number; // суммарный объём на N уровнях ask
imbalance: number; // bid / (bid + ask), 0.5 = нейтрально
spread: number; // % спред
spreadUSD: number; // абсолютный спред в USD
bidWall: WallInfo | null;
askWall: WallInfo | null;
liquidationAt1Pct: number; // объём нужный для 1% движения
liquidationAt2Pct: number;
}
interface WallInfo {
price: number;
size: number;
sizeUSD: number;
relativeSize: number; // во сколько раз больше среднего уровня
} חישוב מדדים — פיתוח מסך עומק השוק
function calculateDepthMetrics(
snapshot: MarketDepthSnapshot,
levels: number = 20
): DepthMetrics {
const bids = snapshot.bids.slice(0, levels);
const asks = snapshot.asks.slice(0, levels);
const midPrice = (bids[0][0] + asks[0][0]) / 2;
const bidVolume = bids.reduce((sum, [, size]) => sum + size, 0);
const askVolume = asks.reduce((sum, [, size]) => sum + size, 0);
const imbalance = bidVolume / (bidVolume + askVolume);
const spread = (asks[0][0] - bids[0][0]) / midPrice * 100;
// Поиск стен: уровень с объёмом > avg * threshold
const avgBidSize = bidVolume / bids.length;
const avgAskSize = askVolume / asks.length;
const wallThreshold = 3.0; // в 3× больше среднего = стена
const bidWall = bids.reduce((max, [price, size]) => {
if (size > avgBidSize * wallThreshold) {
if (!max || size > max.size) {
return { price, size, sizeUSD: size * price, relativeSize: size / avgBidSize };
}
}
return max;
}, null as WallInfo | null);
// Ликвидность на 1% движения
const priceAt1PctDown = midPrice * 0.99;
const liquidationAt1Pct = bids
.filter(([price]) => price >= priceAt1PctDown)
.reduce((sum, [, size]) => sum + size * midPrice, 0);
return {
symbol: snapshot.symbol,
bidVolume: bidVolume * midPrice,
askVolume: askVolume * midPrice,
imbalance,
spread,
spreadUSD: asks[0][0] - bids[0][0],
bidWall,
askWall: null, // аналогично для ask
liquidationAt1Pct,
liquidationAt2Pct: 0, // аналогично
};
} באילו מדדים להשתמש להתראות?
אנו מציעים לא רק ניטור אלא גם התראות מותאמות אישית. הפרויקט כבר כולל ארבעה סוגים:
-
interface MarketDepthSnapshot { symbol: string; exchange: string; timestamp: number; bids: [price: number, size: number][]; asks: [price: number, size: number][]; } interface DepthMetrics { symbol: string; bidVolume: number; // суммарный объём на N уровнях bid askVolume: number; // суммарный объём на N уровнях ask imbalance: number; // bid / (bid + ask), 0.5 = нейтрально spread: number; // % спред spreadUSD: number; // абсолютный спред в USD bidWall: WallInfo | null; askWall: WallInfo | null; liquidationAt1Pct: number; // объём нужный для 1% движения liquidationAt2Pct: number; } interface WallInfo { price: number; size: number; sizeUSD: number; relativeSize: number; // во сколько раз больше среднего уровня }— חוסר איזון פתאומי; -
function calculateDepthMetrics( snapshot: MarketDepthSnapshot, levels: number = 20 ): DepthMetrics { const bids = snapshot.bids.slice(0, levels); const asks = snapshot.asks.slice(0, levels); const midPrice = (bids[0][0] + asks[0][0]) / 2; const bidVolume = bids.reduce((sum, [, size]) => sum + size, 0); const askVolume = asks.reduce((sum, [, size]) => sum + size, 0); const imbalance = bidVolume / (bidVolume + askVolume); const spread = (asks[0][0] - bids[0][0]) / midPrice * 100; // Поиск стен: уровень с объёмом > avg * threshold const avgBidSize = bidVolume / bids.length; const avgAskSize = askVolume / asks.length; const wallThreshold = 3.0; // в 3× больше среднего = стена const bidWall = bids.reduce((max, [price, size]) => { if (size > avgBidSize * wallThreshold) { if (!max || size > max.size) { return { price, size, sizeUSD: size * price, relativeSize: size / avgBidSize }; } } return max; }, null as WallInfo | null); // Ликвидность на 1% движения const priceAt1PctDown = midPrice * 0.99; const liquidationAt1Pct = bids .filter(([price]) => price >= priceAt1PctDown) .reduce((sum, [, size]) => sum + size * midPrice, 0); return { symbol: snapshot.symbol, bidVolume: bidVolume * midPrice, askVolume: askVolume * midPrice, imbalance, spread, spreadUSD: asks[0][0] - bids[0][0], bidWall, askWall: null, // аналогично для ask liquidationAt1Pct, liquidationAt2Pct: 0, // аналогично }; }— חומה הופיעה; -
imbalance_spike— חומה הוסרה (ספופינג אפשרי); -
wall_appeared— הפער התרחב.
interface DepthAlert {
symbol: string;
condition: 'imbalance_spike' | 'wall_appeared' | 'wall_removed' | 'spread_widened';
threshold: number;
notifyVia: ('ui' | 'telegram' | 'webhook')[];
}
class DepthAlertEngine {
private prevSnapshots = new Map<string, DepthMetrics>();
checkAlerts(current: DepthMetrics, alerts: DepthAlert[]) {
const prev = this.prevSnapshots.get(current.symbol);
if (!prev) {
this.prevSnapshots.set(current.symbol, current);
return;
}
for (const alert of alerts) {
if (alert.symbol !== current.symbol) continue;
switch (alert.condition) {
case 'imbalance_spike':
if (current.imbalance >= alert.threshold && prev.imbalance < alert.threshold) {
this.triggerAlert(alert, `Imbalance spike on ${current.symbol}: ${(current.imbalance * 100).toFixed(1)}%`);
}
break;
case 'wall_appeared':
if (current.bidWall && !prev.bidWall && current.bidWall.sizeUSD >= alert.threshold) {
this.triggerAlert(alert, `Bid wall appeared on ${current.symbol}: $${(current.bidWall.sizeUSD/1000).toFixed(0)}k`);
}
break;
}
}
this.prevSnapshots.set(current.symbol, current);
}
} דוגמה להגדרת התראת חוסר איזון
{ "symbol": "BTCUSDT",
"condition": "imbalance_spike",
"threshold": 0.65,
"notifyVia": ["telegram"] }כאשר חוסר האיזון עולה על 0.65, הסוחר מקבל הודעת Telegram עם הזוג והערך הנוכחי.
איסוף נתונים: מנהל WebSocket
עבור 50 זוגות, אנו זקוקים ל-50 ערוצים. המנהל מתחבר מחדש אוטומטית בעת ניתוק.
class MultiExchangeDepthFeed {
private connections = new Map<string, WebSocket>();
private onUpdate: (snapshot: MarketDepthSnapshot) => void;
subscribe(symbol: string, exchange: 'binance' | 'okx' | 'bybit') {
const wsUrl = this.getWSUrl(exchange, symbol);
const ws = new WebSocket(wsUrl);
ws.onmessage = (e) => {
const snapshot = this.parseMessage(exchange, JSON.parse(e.data));
if (snapshot) this.onUpdate(snapshot);
};
ws.onclose = () => {
setTimeout(() => this.subscribe(symbol, exchange), 3000);
};
this.connections.set(`${exchange}:${symbol}`, ws);
}
} התהליך שלנו
- ניתוח — קביעת רשימת הבורסות והזוגות, הגדרת ספים.
- עיצוב — ארכיטקטורה לאיסוף נתונים, חישוב והתראות.
- פיתוח — כתיבת קוד באמצעות הדפוסים שלעיל.
- בדיקות — על נתונים היסטוריים ובזמן אמת.
- פריסה — על השרת שלכם או בענן.
לוח זמנים: 4–6 שבועות לפתרון סוהר. התמחור מחושב באופן אישי לפי מספר הבורסות ומורכבות ההתראות.
השוואה: ניתוח ידני מול אוטומטי
| פרמטר | ידני | מסך |
|---|---|---|
| זמן לניתוח זוג אחד | 30–60 שניות | <1 אלפית השנייה |
| כיסוי זוגות | 3–5 | 50+ |
| זיהוי ספופינג | אקראי | מובטח |
| התראות | אין | Telegram/ממשק |
מדדים נוספים להתראות
| מדד | תיאור | סף מומלץ |
|---|---|---|
| חוסר איזון | הצעות קנייה/(הצעות קנייה+הצעות מכירה) | >0.6 או <0.4 |
| גודל חומה | נפח חומה בדולרים | >$100k |
| פער | אחוז פער | >0.05% עבור BTC |
| נזילות ב-1% | נפח לתנועה של 1% | < $1M עבור BTC |
הניסיון שלנו — 5 שנים בפיתוח כלי מסחר, 20+ פרויקטים. אנו יודעים לבנות מוצר אמין. איכות מובטחת ומסירת קוד מקור.
מה כלול
- קוד מקור של המסך (TypeScript, ממשק React);
- תיעוד פריסה והגדרה;
- לוח מחוונים עם טבלה הניתנת למיון;
- מערכת התראות (Telegram + ממשק);
- הדרכת צוות (שעתיים אונליין).
צרו קשר — נעריך את המשימה שלכם תוך יום עסקים אחד. נעזור לכם לבחור תצורה המתאימה לסגנון המסחר שלכם.







