OKX · API מתקדם
חיבור שער בזמן אמת ל-OKX עם WebSocket: למה אסטרטגיה מתקדמת מחליפה את ה-REST polling
אחרי שאסטרטגיה רצה תקופה, סביר שתיתקל במבוכה הזו: הלוגיקה תקינה, אבל הביצוע בחשבון האמיתי תמיד מאחר בחצי קצב. אתה בוהה בקוד, והבעיה בדרך כלל לא באסטרטגיה עצמה אלא בדרך שבה אתה מקבל את השער — עדיין שואל ב-REST שוב ושוב "מה המחיר עכשיו". ל-polling כזה יש השהיה מובנית, ובתדירות גבוהה הוא גם נתקל במגבלת קצב. כדי שהאסטרטגיה תגיב מהר יותר, בדרך כלל צריך להחליף את חיבור השער מ-polling ל-WebSocket push.
במאמר הזה אנחנו (צוות המערכת של MeowQuant) מבהירים איך משתמשים ב-WebSocket ב-OKX: במה הוא נבדל מ-REST polling, למה אסטרטגיה מתקדמת צריכה אותו, אילו ערוצים יש ל-OKX, איך כותבים push עם watch_ticker ו-watch_orders של ccxt.pro, איך מטפלים בחיבור מחדש וב-heartbeat, ו — חשוב מאוד — למי זה מתאים. נאמר מראש את המסקנה: זה תוכן מתקדם, ולאסטרטגיות פשוטות של מתחיל REST מספיק, אל תעלה ל-WS מוקדם מדי רק כדי "להיראות מקצועי".
REST polling מול WebSocket push
ההבדל בין השניים מתבהר באנלוגיה מהחיים. REST polling זה כמו שאתה מצלצל מדי כמה שניות ושואל את הצד השני "יש הודעה חדשה?", וברוב הפעמים התשובה היא "אין", צלצול לחינם; WebSocket זה כמו שיש לך עם הצד השני קו פתוח שלא מנותק, וברגע שיש לו הודעה הוא אומר לך אותה ישירות, ואתה לא צריך לשאול כלום.
במונחים טכניים:
| מימד | REST polling (fetch_) | WebSocket push (watch_) |
|---|---|---|
| דרך קבלת הנתונים | אתה שולח בקשות שוב ושוב ביוזמתך | חיבור ארוך אחד, הבורסה דוחפת ביוזמתה |
| השהיה | מוגבלת במרווח ה-polling, מאחרת מטבעה | הנתון משתנה ונדחף, השהיה נמוכה |
| צריכת בקשות | polling תכוף נתקל בקלות במגבלת קצב | חיבור אחד, כמעט לא צורך מכסת בקשות |
| ההזמנות/החשבון שלך | צריך לבדוק שוב ושוב כדי לדעת אם התבצע | ערוץ פרטי דוחף בזמן אמת ביצוע ושינויי חשבון |
| מורכבות מימוש | סינכרוני, אינטואיטיבי, קל לבדיקה | אסינכרוני, צריך לטפל בחיבור מחדש וב-heartbeat |
| מתאים ל | מתחילים, אסטרטגיות בתדירות נמוכה | מתקדם, אסטרטגיות רגישות לזמן |
בקצרה: REST פשוט אבל איטי, WebSocket מהיר אבל דורש קצת יותר קוד. הבחירה תלויה בכמה האסטרטגיה שלך מתעניינת ב"מהיר".
למה אסטרטגיה צריכה WS
נצמצם את ההשוואה שלמעלה לשלוש נקודות שמהן האסטרטגיה נהנית:
- השהיה נמוכה, תגובה מהירה. המחיר משתנה ונדחף מיד אליך, והאסטרטגיה יכולה להגיב מוקדם יותר. לאסטרטגיות שתופסות תנודות וחוטפות הפרשי מחיר, פער ההשהיה הזה יכול להיות הגבול בין להרוויח ללא להרוויח.
- חיסכון בבקשות, אין מגבלת קצב. WS הוא חיבור ארוך אחד, ולא שולח בקשות שוב ושוב כמו polling, אז מטבעו פחות מפעיל את מגבלת הקצב. כשרוצים לעקוב אחרי הרבה צמדים, היתרון הזה בולט במיוחד.
- לדעת את המצב שלך בזמן אמת. ערוץ פרטי דוחף אליך ביוזמתו ביצוע הזמנות, שינויי פוזיציה ושינויי יתרה, בלי לבדוק שוב ושוב עם
fetch_open_orders. האסטרטגיה מתאימה את עצמה בהתאם בזמן רב יותר, וגם חוסכת בקשות.
אבל שים לב ש"להפיק תועלת" מותנה: האסטרטגיה שלך באמת צריכה להיות רגישה לזמן. אם אתה מריץ רשת בתדירות נמוכה שבודקת פעם בשעה, יתרון ההשהיה של WS חסר משמעות עבורך, ורק מכניס מורכבות לחינם.
הערוצים של WS ב-OKX
הערוצים של ה-WebSocket ב-OKX (API v5) מתחלקים בערך לשני סוגים, והבנת החלוקה הזו תקל על כתיבת הקוד בהמשך:
ערוצים ציבוריים (Public). דוחפים נתוני שוק פומביים, כל אחד יכול להירשם, בלי אימות. הנפוצים:
- שער (tickers): מחיר העסקה האחרון, ביקוש/היצע ראשון, שינוי 24 שעות ועוד.
- נרות (candles): עדכוני נרות בכל פרק זמן.
- עומק ספר (books): עומק ההזמנות של ביקוש והיצע.
- ביצועים (trades): כל עסקה ועסקה שמתרחשת בשוק.
ערוצים פרטיים (Private). דוחפים נתונים הקשורים לחשבון שלך, ולפני ההרשמה צריך אימות עם API Key (אותם שלושה אישורים: apiKey, secret, Passphrase). הנפוצים:
- הזמנות (orders): שינויי סטטוס של ההזמנות שלך ודיווחי ביצוע.
- פוזיציות (positions): שינויים בפוזיציות חוזים.
- חשבון (account): שינויי יתרה, מרג'ין ועוד.
במשפט אחד: ערוץ ציבורי מסתכל על השוק, ערוץ פרטי מסתכל על עצמך. אתה יכול להירשם רק לערוצים ציבוריים לאסטרטגיה מונעת-שער, או להירשם במקביל גם לערוצים פרטיים ולעקוב בזמן אמת אחרי תוצאות ההזמנות שלך.
חיבור שער עם ccxt.pro (watch_ticker)
הדרך הקלה ביותר לחבר WS היא עדיין דרך ccxt — הרחבת ה-WebSocket שלה נקראת ccxt.pro, וכיום היא כבר שולבה בחבילה הראשית. ccxt רגיל עובד דרך REST עם משפחת fetch_; ccxt.pro דרך WS עם משפחת watch_. כי הבסיס הוא חיבור ארוך, הקוד צריך להיכתב אסינכרוני (async).
הקטע הבא נרשם לשער של BTC/USDT, וכל פעם שהמחיר מתעדכן הוא מדפיס:
import asyncio
import ccxt.pro as ccxtpro # גרסת WS, משפחת watch_
async def main():
okx = ccxtpro.okx() # שער ציבורי לא דורש אימות
symbol = 'BTC/USDT'
try:
while True:
ticker = await okx.watch_ticker(symbol) # חוזר רק כשיש שער חדש
print(ticker['symbol'], ticker['last'])
finally:
await okx.close() # סגור את החיבור הארוך ביציאה
asyncio.run(main())
ההבדל המרכזי מ-REST הוא ב-await okx.watch_ticker(...): אתה לא מושך ביוזמתך, אלא "מחכה תלוי ל-push", וחוזר רק כשיש שער חדש. כשאתה שם אותו בלולאת while True הוא הופך לזרם רציף של קבלת שער. שים לב ל-await okx.close() בסוף — חיבור ארוך צריך לסגור ביוזמה כשמסיימים, אל תשאיר אותו תלוי.
חיבור ערוץ הזמנות פרטי (watch_orders)
מעבר לשער הציבורי, משחק מתקדם הוא לעקוב במקביל אחרי ההזמנות שלך. watch_orders ידחוף אליך ברגע שסטטוס הזמנה משתנה (ביצוע חלקי, ביצוע מלא, ביטול), הרבה יותר בזמן מ-fetch_open_orders חוזר. הוא שייך לערוצים הפרטיים, אז צריך לצרף אישורים:
import asyncio
import ccxt.pro as ccxtpro
async def main():
okx = ccxtpro.okx({
'apiKey': 'ה_apiKey_שלך',
'secret': 'ה_secret_שלך',
'password': 'ה_Passphrase_שלך', # ערוץ פרטי דורש אימות
})
try:
while True:
orders = await okx.watch_orders() # נדחף ברגע שהזמנה שלך משתנה
for o in orders:
print(o['symbol'], o['side'], o['status'], o.get('filled'))
finally:
await okx.close()
asyncio.run(main())
עם זה, האסטרטגיה שלך יכולה לקבל את הדיווח ברגע שהזמנה מתבצעת, ולפיו מיד לתלות את ההזמנה הבאה או להתאים פוזיציה, במקום לגלות בסבב ה-polling הבא "אה, ההזמנה ההיא התבצעה". זה קריטי לאסטרטגיות כמו רשת ו-market making שצריכות לתלות הזמנות ברצף מהיר. הערוץ הפרטי משתמש באותו API Key אמיתי שלך (יצירת מפתח במבוא המעשי ל-API), עם הרשאות 'קריאה' ו'מסחר' בלבד, בלי 'משיכה'.
OK30001 מקנה הנחה בעמלות, וזה חל גם על הזמנות דרך API. לחץ כאן להרשמה ל-OKX ולפתיחת API ←
חיבור מחדש ו-heartbeat
הבעיה המעשית הגדולה ביותר בחיבור ארוך: הוא יתנתק. הרשת מקפצת, הבורסה עושה אתחול שגרתי — והחיבור נעלם. כמה יציבה אסטרטגיית WS תלוי במידה רבה באיך אתה מטפל בניתוק. שני דברים חובה לעשות:
heartbeat / keep-alive. פרוטוקול ה-WebSocket מסתמך על ping/pong תקופתי כדי לאשר שהחיבור עוד חי. אם תקופה אין תנועה, הבורסה תחשיב את החיבור כמת ותנתק אותו. למזלנו ccxt.pro בדרך כלל מטפל בקיום בפנים, ואתה בעיקר צריך לוודא שלא תחסום את התוכנה לזמן ארוך ולא תיתקע בשליחה/קבלה של הודעות.
חיבור מחדש + הרשמה מחדש. אם החיבור התנתק צריך להתחבר מחדש אוטומטית, ואחרי החיבור מחדש להירשם שוב לערוצים ולוודא פעם נוספת את המצב האמיתי הנוכחי (למשל למשוך שוב את ההזמנות הפתוחות והפוזיציות), כי את ה-push שהתרחש בזמן הניתוק לא קיבלת. כתיבה נפוצה היא לעטוף את קריאת ה-watch_ ב-try/except, לתפוס חריגות חיבור ולהתחבר ולהירשם שוב:
import asyncio
import ccxt.pro as ccxtpro
async def main():
okx = ccxtpro.okx()
symbol = 'BTC/USDT'
while True:
try:
ticker = await okx.watch_ticker(symbol)
print(ticker['last'])
except ccxtpro.NetworkError as e:
print('חריגת חיבור, מתחבר ונרשם שוב בעוד רגע:', e)
await asyncio.sleep(2) # נסוג צעד לפני חיבור מחדש, אל תפגע בלי הפסקה
# אחרי חיבור מחדש, לפי הצורך ודא שוב את הפוזיציות/ההזמנות הפתוחות הנוכחיות
except Exception as e:
print('חריגה אחרת:', e)
await asyncio.sleep(2)
asyncio.run(main())
העיקר כאן הוא לא כמה יפה הקוד, אלא העיקרון הזה: אחרי ניתוק אל תניח שהמצב לא השתנה, קודם ודא ואז המשך. זה אותו דבר כמו "אחרי חיבור מחדש קודם בדוק סטטוס, אז פעל" שדיברנו עליו בניהול סיכונים באלגו — בזמן אובדן הקשר השוק אולי כבר זז, והמשך עיוור עלול לגרום לבלגן.
בדיקה: השוואת השהיה
fetch_ticker ב-REST כל 3 שניות, ואחד מחבר push עם watch_ticker של ccxt.pro. התוצאה אינטואיטיבית מאוד — בצד ה-polling עדכון המחיר קפץ בבירור "תא-תא", ובין שני עדכונים היה פער של כמעט 3 שניות (כי הוא בדיוק שואל פעם ב-3 שניות); בצד ה-WS המחיר התרענן כמעט ברציפות, השער זז ונדחף, ובתחושה הרבה יותר מהיר. לא מדדנו במדויק מילישניות (סביבת הדמו גם לא מייצגת רשת אמיתית), אבל ש"polling מאחר אחרי push" — זה גלוי לעין. לאסטרטגיה בתדירות נמוכה הפער הזה לא חשוב, אבל לאסטרטגיה שתופסת תנודות וחוטפת הפרשי מחיר, השניות האלה הן חיסרון ממשי. ההשוואה הזו גם אישרה לנו: אסטרטגיה שצריכה WS — תעלה אותו מוקדם; אסטרטגיה שלא צריכה — REST דווקא נוח יותר.
למי זה מתאים
נחזור לשאלה שהכי כדאי לחשוב עליה: אתה צריך WebSocket או לא. הקריטריון שלנו פשוט מאוד —
מצבים שבהם מומלץ קודם REST: אתה מתחיל; האסטרטגיה בתדירות נמוכה (בודקת פעם בכמה דקות או אפילו שעות); הלוגיקה פשוטה ולא רגישה להשהיה. REST סינכרוני, אינטואיטיבי וקל לבדיקה, ולמצבים האלה הוא מספיק לחלוטין, ובלי המהמורות של אסינכרוניות וחיבור מחדש אתה יכול להשקיע את האנרגיה באסטרטגיה עצמה.
מצבים ששווה לעלות ל-WS: האסטרטגיה רגישה להשהיה (תפיסת תנודות, market making, ארביטראז' הפרשים); אתה צריך לעקוב אחרי הרבה צמדים במקביל וה-polling מתחיל להיתקל במגבלת קצב; אתה צריך דיווח ביצוע בזמן אמת כדי לתלות הזמנות ברצף. במצבים האלה, הזמן-אמת והיעילות ש-WS מביא שווים את הקוד הנוסף של אסינכרוניות וחיבור מחדש.
במשפט אחד: אל תעלה ל-WS מוקדם מדי רק כדי להיראות מקצועי. קודם הרץ את האסטרטגיה חלק ב-REST, וכשתיתקל באמת בתקרה של ה-polling — איטי, או נתקל במגבלת קצב — אז שדרג ל-WebSocket; הסדר הזה הכי חוסך מאמץ, והכי פחות תיתקע במורכבות טכנית לפני שהבנת את האסטרטגיה. בכל מקרה, קוד חדש קודם לדמו לאימות.
שאלות נפוצות
מה ההבדל בין REST polling ל-WebSocket push?
REST polling זה שאתה שואל את הבורסה ביוזמתך שוב ושוב 'מה המחיר עכשיו', וכל פעם צריך לשלוח בקשה ולחכות לתגובה — יש גם השהיה וגם נטייה להיתקל במגבלת קצב. WebSocket מקים חיבור ארוך אחד, וכשיש לבורסה נתון חדש היא דוחפת אותו אליך ביוזמתה, ואתה לא צריך לשאול שוב ושוב. לאסטרטגיה שצריכה להגיב מהר לשער, הזמן-אמת והיעילות של push עדיפים בבירור על polling.
למה אסטרטגיה צריכה WebSocket?
שלוש סיבות: ראשית השהיה נמוכה, ברגע שהמחיר משתנה הוא נדחף אליך והתגובה מהירה יותר; שנית חיסכון בבקשות, אין צורך ב-polling בתדירות גבוהה אז פחות נתקלים במגבלת קצב; שלישית ערוצים פרטיים מקבלים בזמן אמת push של ביצוע ההזמנות שלך ושינויי חשבון, בלי לבדוק שוב ושוב. לאסטרטגיות רגישות לזמן כמו רשת, market making ו-high frequency, WS הוא כמעט ציוד תקני. אבל לאסטרטגיות פשוטות בשלב המתחיל, REST polling בדרך כלל מספיק.
אילו ערוצים יש ב-WebSocket של OKX?
בערך שני סוגים. ערוצים ציבוריים דוחפים נתוני שוק פומביים, למשל שער (ticker), נרות, עומק ספר וביצועים, וכל אחד יכול להירשם בלי אימות. ערוצים פרטיים דוחפים נתונים הקשורים לחשבון שלך, למשל עדכוני הזמנות, שינויי פוזיציה ויתרת חשבון, ולפני ההרשמה צריך אימות עם API Key. ציבורי לשוק, פרטי לעצמך.
ccxt.pro וה-ccxt הרגיל הם אותו דבר?
ccxt.pro הוא הרחבת ה-WebSocket של ccxt, שעוטפת גם את ה-WS של כל בורסה לממשק אחיד. ccxt רגיל עובד דרך REST (משפחת fetch_), ccxt.pro דרך WS (משפחת watch_, למשל watch_ticker, watch_orders). כיום ccxt.pro כבר שולב בחבילת ccxt הראשית, ואחרי התקנת ccxt משתמשים בשיטות watch_ אסינכרוניות. הבסיס הוא חיבור ארוך, אז הקוד צריך להיכתב כלולאה אסינכרונית.
מה עושים כשה-WebSocket מתנתק?
חיבור ארוך יתנתק בהכרח — קפיצת רשת, אתחול בורסה. שני דברים לעשות: אחד, heartbeat/keep-alive, לשלוח ping מדי פעם או להישען על מנגנון הקיום של הספרייה, כדי שהחיבור לא ייחשב מת; שתיים, חיבור מחדש, לתפוס חריגת חיבור ולהתחבר אוטומטית, ואחרי החיבור מחדש להירשם שוב לערוצים ולוודא פעם נוספת את המצב האמיתי הנוכחי. בשיטות watch_ של ccxt.pro, שים אותן בלולאת try/except — התנתק, התחבר והירשם שוב — זו כתיבה נפוצה.
מתחיל צריך להתחיל ב-REST או ב-WebSocket?
התחל ב-REST. REST סינכרוני, אינטואיטיבי וקל לבדיקה, ולאסטרטגיות פשוטות של מתחיל (למשל רשת בתדירות נמוכה, בדיקה מתוזמנת) הוא מספיק לחלוטין. WebSocket מכניס מורכבות של אסינכרוניות, חיבור ארוך וחיבור מחדש — וכשהאסטרטגיה שלך באמת רגישה להשהיה, או שה-polling מתחיל להיתקל במגבלת קצב, אז שדרג ל-WS. אל תעלה ל-WS מוקדם מדי רק כדי 'להיראות מקצועי'.
WebSocket הוא כלי טוב, אבל הוא מיועד למי ש"כבר יודע למה הוא צריך אותו". אם אתה עדיין מניח יסודות, קודם הרץ את המבוא המעשי ל-API, התקן את ניהול הסיכונים — אלה חשובים בהרבה ממעבר ל-WS. כשהאסטרטגיה באמת לא מצליחה להאיץ, חזור למאמר הזה.
האסטרטגיה צריכה להאיץ? קודם הכן את החשבון ואת ה-API
WebSocket, ערוצים פרטיים ו-push הזמנות בזמן אמת — התנאי לכולם הוא API Key עם הרשאות מוגדרות נכון. חשבון חדש שנפתח עם קוד ההזמנה נהנה מהנחה בעמלות, וזה חל גם על הזמנות דרך API — קודם הנח את היסודות, ואז דבר על מתקדם.
מחירי נכסי קריפטו תנודתיים מאוד, וחוזים ומינוף עלולים להוביל להפסד מלא של הקרן. מסחר אלגוריתמי ואוטומטי אינו מבטיח רווח, השתמש רק בכסף שאתה יכול להרשות לעצמך להפסיד.