איגוד יתרות ממספר בורסות קריפטו באפליקציה לנייד
סוחר מחזיק נכסים ב-Binance, Bybit ו-OKX — כל בורסה דורשת פתיחת אפליקציה או כרטיסיית דפדפן נפרדת. זה מבזבז זמן ומגביר את הסיכון לשגיאות בחישוב ידני של הפוזיציה הכוללת. עבור סוחר גדול, איסוף נתונים ידני יכול לקחת עד שעתיים ביום, וטעויות בהמרת טיקר עולות מאות דולרים בחודש. אנו פותרים זאת על ידי יצירת לוח מחוונים מאוחד (תיק קריפטו) ישירות באפליקציה לנייד. המשתמש רואה את הפוזיציה הכוללת לכל טוקן ופירוט לפי בורסה על מסך אחד. הצוות שלנו מתמחה באינטגרציה של API של בורסות: סיפקנו מעל 20 פרויקטים כאלה ל-iOS ואנדרואיד. גישה זו מפחיתה את זמן איסוף הנתונים בממוצע ב-85% בהשוואה לניטור ידני, וחוסכת לסוחר עד 500 דולר בחודש.
כיצד פועלת ארכיטקטורת האיגוד
כל בורסה היא מתאם (adapter) נפרד המיישם פרוטוקול משותף. תבנית זו מאפשרת הוספת בורסות חדשות ללא שינוי בלוגיקה העסקית של המאגד. הנה דוגמה ב-Kotlin לאנדרואיד:
// Android, Kotlin
interface ExchangeAdapter {
suspend fun fetchSpotBalances(): Result<List<Balance>>
suspend fun fetchFuturesBalances(): Result<List<Balance>>
val exchangeId: String
}
data class Balance(
val ticker: String,
val available: BigDecimal,
val locked: BigDecimal,
val exchangeId: String
)
class BinanceAdapter(private val apiKey: String, private val secret: String) : ExchangeAdapter {
override val exchangeId = "binance"
override suspend fun fetchSpotBalances(): Result<List<Balance>> = runCatching {
val timestamp = System.currentTimeMillis()
val queryString = "timestamp=$timestamp&recvWindow=5000"
val signature = HmacSHA256.sign(queryString, secret)
val response = apiClient.get("/api/v3/account?$queryString&signature=$signature")
response.balances
.filter { it.free.toBigDecimal() > BigDecimal.ZERO || it.locked.toBigDecimal() > BigDecimal.ZERO }
.map { Balance(it.asset, it.free.toBigDecimal(), it.locked.toBigDecimal(), exchangeId) }
}
}המאגד מריץ את כל המתאמים במקביל באמצעות // Android, Kotlin interface ExchangeAdapter { suspend fun fetchSpotBalances(): Result<List<Balance>> suspend fun fetchFuturesBalances(): Result<List<Balance>> val exchangeId: String } data class Balance( val ticker: String, val available: BigDecimal, val locked: BigDecimal, val exchangeId: String ) class BinanceAdapter(private val apiKey: String, private val secret: String) : ExchangeAdapter { override val exchangeId = "binance" override suspend fun fetchSpotBalances(): Result<List<Balance>> = runCatching { val timestamp = System.currentTimeMillis() val queryString = "timestamp=$timestamp&recvWindow=5000" val signature = HmacSHA256.sign(queryString, secret) val response = apiClient.get("/api/v3/account?$queryString&signature=$signature") response.balances .filter { it.free.toBigDecimal() > BigDecimal.ZERO || it.locked.toBigDecimal() > BigDecimal.ZERO } .map { Balance(it.asset, it.free.toBigDecimal(), it.locked.toBigDecimal(), exchangeId) } } } (קורוטינות Kotlin או async/await ב-Swift), אוסף תוצאות ומאחד פוזיציות לפי טיקר. בפועל, עם 10 בורסות, האיגוד אורך פחות משתי שניות — פי 4 מהר יותר מאיסוף רציף.
class BalanceAggregator(private val adapters: List<ExchangeAdapter>) {
suspend fun aggregate(): AggregatedPortfolio = coroutineScope {
val results = adapters.map { adapter ->
async {
adapter.fetchSpotBalances()
}
}.awaitAll()
val allBalances = results.flatMap { it.getOrElse { emptyList() } }
// Группируем по тикеру, суммируем
val byTicker = allBalances.groupBy { it.ticker }
val aggregated = byTicker.map { (ticker, positions) ->
AggregatedPosition(
ticker = ticker,
totalAvailable = positions.sumOf { it.available },
byExchange = positions.associateBy { it.exchangeId }
)
}
AggregatedPortfolio(positions = aggregated, fetchedAt = Instant.now())
}
} למה בידוד שגיאות חשוב
שגיאות מבורסה אחת לא צריכות להפיל את המערכת כולה. אם Bybit מחזירה 503, המשתמש צריך לראות נתונים מ-Binance ו-OKX עם תווית "Bybit: נתונים לא זמינים". לכן TaskGroup הוא חובה — לא אופציונלי — כסוג ההחזרה. בממשק המשתמש: כל בורסה מקורית מציגה סטטוס (ירוק/אדום/אפור). מאגד אסינכרוני זה מניב חיסכון של עד פי 4 בזמן בהשוואה לאיסוף רציף.
בעיות שאנו פותרים
פורמטי טיקר שונים. Binance קוראת ל-Tether class BalanceAggregator(private val adapters: List<ExchangeAdapter>) { suspend fun aggregate(): AggregatedPortfolio = coroutineScope { val results = adapters.map { adapter -> async { adapter.fetchSpotBalances() } }.awaitAll() val allBalances = results.flatMap { it.getOrElse { emptyList() } } // Группируем по тикеру, суммируем val byTicker = allBalances.groupBy { it.ticker } val aggregated = byTicker.map { (ticker, positions) -> AggregatedPosition( ticker = ticker, totalAvailable = positions.sumOf { it.available }, byExchange = positions.associateBy { it.exchangeId } ) } AggregatedPortfolio(positions = aggregated, fetchedAt = Instant.now()) } } , חלק מהבורסות משתמשות ב-USDT, אחרות ב-USDT. OKX משתמשת ב-USDt כזוג המסחר עבור TON, עם נכס הבסיס TON-USDT. נדרשת נורמליזציה: טבלת כינויים וטיקר קנוני לכל נכס. המרה שגויה עלולה להוביל לאובדן הפקדה — אנו מבטלים סיכון זה.
מפתחות API ואבטחה. המשתמש מוסיף מספר זוגות מפתחות. כל זוג מוצפן בנפרד באמצעות Android Keystore / iOS Keychain, ומקושר לזיהוי ביומטרי. בעת שליחת בקשה לבורסה, המפתח מפוענח בזיכרון, בשימוש, ואינו נשמר בערימה יותר מהנדרש.
סטיית שעון. Binance ו-Bybit דורשות שה-TON יהיה קרוב לזמן השרת (±5 שניות). בבקשה הראשונה לכל בורסה, אנו מסנכרנים את השעון דרך נקודת הקצה timestamp שלהם ושומרים על היסט (offset).
איך זה נראה בממשק המשתמש
המסך הראשי מציג רשימת נכסים עם פוזיציות כוללות. הקשה על נכס חושפת פירוט לפי בורסה. מסך נוסף מספק פירוט לפי בורסה: כמה בדולרים בכל אחת. עדכונים דרך משיכה לרענון (pull-to-refresh) ואוטומטית כל 5 דקות בזמן שהאפליקציה פעילה.
השוואת פרוטוקולי בורסה
| בורסה | נקודת קצה | אימות | הערות |
|---|---|---|---|
| Binance | /time |
HMAC-SHA256 | recvWindow, סנכרון שעון |
| Bybit V5 | /api/v3/account |
HMAC-SHA256 | accountType: UNIFIED |
| OKX | /v5/account/wallet-balance |
HMAC + passphrase | 3 כותרות אימות |
| Gate.io | /api/v5/account/balance |
HMAC-SHA512 | — |
השוואת גישות איגוד
| גישה | מהירות | בידוד שגיאות | קלות הוספת בורסה |
|---|---|---|---|
| שלנו (מתאמים + מאגד אסינכרוני) | גבוהה (בקשות מקבילות) | מלא (Result<T> לכל מתאם) | נמוכה (פרוטוקול יחיד) |
| איסוף רציף | נמוכה (המתנה לכל תגובה) | חלקי (שגיאה שוברת את השרשרת) | בינונית (לוגיקה במקום אחד) |
| שער API יחיד | בינונית (קפיצת רשת) | תלוי ביישום | גבוהה (יש לתחזק את השער) |
איך להוסיף בורסה חדשה: שלב אחר שלב
- למד את תיעוד הבורסה: נקודות קצה, אימות, מגבלות.
- יישם מחלקה המיישמת
/api/v4/spot/accountsב-Swift (iOS) או Kotlin (אנדרואיד). - הוסף נורמליזציית טיקר לטבלת הכינויים המשותפת.
- בדוק עם ה-API האמיתי.
- שלב בממשק המשתמש ושחרר עדכון.
כמה זמן לוקח האיגוד?
עם 4 בורסות, מחזור האיגוד המלא אורך כשנייה אחת. המשתמש יכול לכפות עדכון דרך משיכה לרענון בכל עת.
למה לבחור ביישום שלנו
- ניסיון של למעלה מ-5 שנים בפיתוח אפליקציות פיננסיות לנייד.
- אנו מבטיחים אבטחה: כל מפתחות ה-API מוצפנים במכשיר, ולעולם לא מועברים לשרת.
- מהנדסים מוסמכים עם ניסיון בפרויקטי קריפטו (iOS, אנדרואיד, Flutter).
מה כלול
- פיתוח מתאמים ל-4 בורסות (או לרשימה שתציין).
- הגדרת אחסון מפתחות מאובטח.
- לוח מחוונים UI הניתן להתאמה אישית.
- אינטגרציית התראות push לשינויי יתרות.
- תיעוד API של המאגד והוראות משתמש.
- חודש תמיכה לאחר המסירה.
לוח זמנים וכיצד להזמין
אינטגרציה של שלוש בורסות עם איגוד ו-UI אורכת בין 5 ל-8 ימי עבודה. כל בורסה נוספת מוסיפה יום אחד. התמחור נקבע באופן אישי לאחר ניתוח דרישות. צור קשר כדי לדון בפרויקט שלך ולקבל הערכה מדויקת. קבל ייעוץ — פשוט פנה אלינו. אנו מציעים גם תמיכה מורחבת והתאמות אישיות לפי בקשה.
מידע נוסף על אבטחה
כל מפתחות ה-API מאוחסנים רק במכשיר המשתמש. בהפעלה הראשונה, נוצר מפתח הצפנה ומקושר לחיישן הביומטרי. הפענוח מתרחש מיד לפני שליחת הבקשה, ולאחר מכן המפתח נמחק. שום נתונים לא מועברים לשרתים שלנו.
מקור: הנחיות סקירת ה-App Store — סעיפים 4.2 ו-5.1 מכסים אבטחה ופונקציונליות של אפליקציות.







