אנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.

Программирование

מעוררי ההשראה מאחורי פיתוח שירות הסטטיסטיקה של Tinkoff Investments היו:

על מה נדון?

  • רק החלק היישומי על פיתוח.
  • ידע וניסיון אמיתי, שחשובים מאוד בעבודה עם מכשירים פיננסיים.
  • סקירה כללית של נושאים שכדאי לעבוד עליהם

אז אני רוצה לחשב סטטיסטיקות סחר ולעשות זאת בצורה נוחה. 

פיתוח שירות סטטיסטיקה צעד אחר צעד: 

  1. חיבור ל-Tinkoff Invest API
  2. ציור נתונים מ-Tinkoff Invest API בדפדפן
  3. קבלת דוחות תיווך ועסקאות
  4. חישוב ופלט של מידע מעניין
  5. מסקנות ותוכניות לעתיד

חיבור ל-Tinkoff Invest API

כדי להתחבר ל-API, אתה יכול לקחת כל sdk מהתיעוד https://github.com/Tinkoff/investAPI#sdk . או חבילת npm ` tinkoff-sdk-grpc-js `. חשוב שהחבילה תתעדכן לגרסה העדכנית ביותר על ידי המפתחים. להתקין

npm i tinkoff-sdk-grpc-js

בודק

const { createSdk } = require(‘tinkoff-sdk-grpc-js’);   // אסימון שניתן להשיג כמו זה  const TOKEN = ‘YOURAPI’;   // שם האפליקציה שבאמצעותה ניתן למצוא אותך ביומני TCS. const appName = ‘tcsstat’;   const sdk = createSdk(TOKEN, appName); (async () => {     console.log(await sdk.users.getAccounts()); })();

תוצאה: רשימה של החשבונות שלך תוצג במסוף. לדוגמה, בואו ננתח את הניואנסים:אנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.

  • ברשימת החשבונות ישנו “בנק השקעות”, שאיתו לא ניתן לעבוד באמצעות ה-API
  • שימו לב שהשדות מגיעים ב-camelCase, בעוד בתיעוד שדות אלו מוצגים ב-under_score. 
  • זה יהיה ככה בכל מקום, אז אתה לא יכול פשוט לקחת ולהעתיק שדה מהתיעוד.

מוֹעִיל:

  • אתה יכול למצוא את הקוד הזה בסניף הפרויקט

https://github.com/pskucherov/tcsstat/tree/step1 https://github.com/pskucherov/tcsstat/compare/step1   

ציור נתונים מ-Tinkoff Invest API בדפדפן

לקחתי את next.js ואת socket.io. זו לא המלצה חזקה, בחר לפי שיקול דעתך. 

npx create-next-app@latest npm i socket.io socket.io-client

אנו ממשיכים מיד לשלב הידידות הבא+socket+investapi, ועיין בסעיף שימושי בשלב זה עבור כל הפרטים.  אני אתאר את הפרטים: 

  • בצד nodejs (שרת), יש קובץ pages/api/investapi.js. זה המקום שבו אנו יוצרים את שרת socket.io ומתחברים ל-investapi.
  • בצד הדפדפן (לקוח), אנו מתחברים לשרת באמצעות שקע ומבקשים נתוני חשבון מהברוקר. 
  • אנו מקבלים נתונים מהמתווך בשרת, ואז שולחים אותם ללקוח. כאשר הם מתקבלים בלקוח, הם מוצגים בדפדפן. 

תוצאה:  במסוף הדפדפן נוכל לראות מידע על חשבונות. כלומר בשלב האחרון ראינו מידע על חשבונות בקונסולת השרת (nodejs), בשלב הנוכחי העברנו את המידע הזה ללקוח (דפדפן).

אנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.

עכשיו בואו נעשה את זה כך שתוכל לבחור חשבון מהדפדפן, ואם אין אסימון, אזי נשלחת שגיאה לקונסולה. העבודה פשוטה ולא חדשה, אז אני נותן רק קישורים להתחייבויות

  1. https://github.com/pskucherov/tcsstat/commit/7e1ac57061e5e971588479015b06d8814d6609a9
  2. https://github.com/pskucherov/tcsstat/commit/b28ac973a57494f5232589b4cb6b9fb13b8af759 

מוֹעִיל:

  • כיצד ליצור חברים הבא ושקע מתואר בפירוט כאן
  • קוד ידידות הבא+socket+investapi:

https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 עבור מי שקשה לעיל, אז אנחנו נשארים בשלב זה ומתמודדים עם הקוד. אם יש לך שאלות – שאל. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2

קבלת דוחות תיווך ועסקאות

ישנן שלוש שיטות לקבלת דוחות תיווך ועסקאות

  1. GetBrokerReport
  2. GetDividends Foreign Issuer
  3. GetOperationsByCursor

מההתחלה חשוב לדעת: 

  • דוח התיווך מופק במצב T-3, כלומר. העסקאות מוצגות שם לאחר ביצוען בפועל. 
  • בהתאם לכך, אם תבקש את הדוח הזה עבור היומיים האחרונים, הוא יהיה מוכן תוך שלושה ימים. 
  • כדי לקבל עסקאות עבור הימים האחרונים, אנו משתמשים בשיטה לקבלת עסקאות, אך זכור כי המזהה והתוכן שלהן עשויים להשתנות לאחר הפקת דוח התיווך.

GetBrokerReport

כדי לקבל דו”ח תיווך, עליך לקחת את מזהה החשבון, תאריך התחלה ותאריך סיום של הדו”ח, אך לא יותר מ-31 יום. אנו שולחים בקשה להפקת דוח ל-API ב- generere _broker_report_request , קבל taskId בתגובה. לאחר מכן, באמצעות taskId זה, אנו מקבלים נתונים מ- get _broker_report_response. [ספויילר title=”אז התיעוד אומר, במציאות יש ניואנסים. שימו לב לידיים שלכם:”]

  • עליך לשמור את ה-TaskID לנצח בדיוק לתאריכים אלה. 
  • מכיוון שאם תאבד את זה, אז עבור התאריכים המבוקשים הדוח יגיע תחילה בתגובה לבקשת הדור, 
  • ואז זה לא יבוא בכלל.

[/ספוילר] בואו נתחיל לכתוב קוד

שיטה לקבלת התאריך, תוך התחשבות בחיסור מהתאריך הנוכחי

const getDateSubDay = (subDay = 5, start = true) => {     const date = new Date();     date.setUTCDate(date.getUTCDate() – תת-יום);       if (start) {         date.setUTCHours(0, 0, 0, 0);     } else {         date.setUTCHours(23, 59, 59, 999);     }       תאריך החזרה; };

בקשה להפקת דוחות 

const brokerReport = await (sdk.operations.getBrokerReport)({         generateBrokerReportRequest: {             accountId,             from,             to,         }, });

תוֹצָאָה:

  • כתוצאה מהביצוע הראשון של הפקודה, אנו מקבלים את taskId. 
  • הדוח מתחיל להיווצר בצד של המתווך. כאשר הוא מוכן אינו ידוע, אנו ממתינים ומושכים מעת לעת את taskId בציפייה לדוח.
  • למה? כי אם הדוח לא מוכן, הוא זורק שגיאה. אם הדוח לא מוכן מצד המתווך, אז זו שגיאה בקוד שלך. נא לעבד: 30058|INVALID_ARGUMENT|המשימה עדיין לא הושלמה, אנא נסה שוב מאוחר יותר

הקוד להמתנה וקבלת דוח נראה בערך כך.

const טיימר = זמן אסינכרון => {     return new Promise(resolve => setTimeout(resolve, time)); }   const getBrokerResponseByTaskId = async (taskId, page = 0) => {     try {         return await (sdk.operations.getBrokerReport)({             getBrokerReportRequest: {                 taskId,                 page,             },         });     } catch (e) {         console.log(‘wait’, e);         ממתין טיימר (10000);         return await getBrokerResponseByTaskId(taskId, page);     } };

ואז קורה אותו קסם. אנחנו עוצרים את התסריט שלנו, מתחילים אותו שוב, אין לנו taskId. אנחנו מבצעים את הקוד עם בקשת taskId, אבל אנחנו כבר לא מקבלים את taskId, אלא מיד את הדוח. קֶסֶם! והכל היה בסדר אם זה תמיד היה ככה. אבל בעוד חודש לא יהיו נתונים בכלל. שימושי :

  • קצת תיאוריה מתוארת כאן וכאן .
  • חיבור הקוד יחד, הטיוטה תיראה בערך כך.

https://github.com/pskucherov/tcsstat/tree/step3.1 https://github.com/pskucherov/tcsstat/compare/step3.1

  • אם מישהו נתקל בזה, ברוך הבא לנושא . לאחר שיתקנו את הקסם הזה, הוא יאבד את כוחו ויהיה שונה איכשהו. אבל ברגע הנוכחי (21/03/2023) זה עובד בדיוק ככה.

GetDividends Foreign Issuer

מישהו עלול לחשוב שהשיטה דומה לקודמתה וניתן להשתמש בשיטה בודדת שבה רק משנים את שם הפעולות. אבל הם לא ניחשו!  השם שם שונה מאוד הן בשיטות והן במידע המוחזר. וספירת הדפים מתחילה מ-0, ואז מ-1. כדי לא להתבלבל בכל זה, קל יותר לכתוב שתי שיטות שונות. וזה מוזר, כי ההיגיון של העבודה זהה. ירקתי הרבה זמן כשניסיתי לעשות שיטה אחת והיה פחות קוד. לא יהיו כאן דוגמאות.

GetOperationsByCursor

האהוב עליי מבין השלושה. אמנם לא הכי מדויק, אבל הכי מספק. אנו מגישים בקשה מתחילת יצירת החשבון ועד לתאריך המקסימלי האפשרי (סגירת חשבון או הנוכחי). אנחנו מקבלים את התשובה, לוקחים את הסמן ומבקשים מחדש כל עוד יש נתונים.  והקוד תמציתי יותר מאשר בדוגמאות למעלה.

const טיימר = זמן אסינכרון => {     return new Promise(resolve => setTimeout(resolve, time)); }   const getOperationsByCursor = async (sdk, accountId, from, to, cursor = ”) => {     try {         const reqData = {             accountId,             from,             to,             limit: 1000,             state: sdk.OperationState.OPERATION_STATE_EXECUTED,             withoutCommissions: false,             withoutTrades: false,             withoutOvernights: false,             cursor,         };           return await sdk.operations.getOperationsByCursor(reqData);     } catch (e) {         await timer(60000);         return await getOperationsByCursor(sdk, accountId, from, to, cursor = ”);     } };

הטיוטה להפעלה נמצאת כאן: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 כעת אנו מוכנים להוסיף פעולות קבלה ל האפליקציה שלנו. אם עושים את זה נכון, אז אתה צריך לקבל דוחות תיווך על כל קיום החשבון. ולגבי הנתונים החסרים, אותם T-3s, נטענים מחדש מפעולות. אבל אפשר להפריד את זה למאמר נפרד. מהניואנסים העיקריים שתתקלו בהם הוא הדבקת פעולות ודו”ח תיווך.

  •  אם היום קיבלתם דוח תיווך ועסקאות לתאריכים הנדרשים, שימו הכל במאגר, אז אין בעיות. 
  • יהיו לך בעיות מחר כשתקבל את החלק הבא של הנתונים מהדוח ומהפעולות ותחליט לסנכרן אותם עם מסד הנתונים הקיים. 
  • הרבה ניואנסים לגבי אי התאמה או שינוי מזהה לאחר עיבוד
  • ואז עבור שוק ה-OTC, המזהים אינם תואמים כלל.
  •  כמו גם הניואנסים של סנכרון מכשירים, אשר שוב אינם חופפים, בשל המוזרויות של ה-API. אבל זה כבר סיפור אחר.

בואו נוסיף קבלת מידע על פעולות לאפליקציה שלנו. השאלה העיקרית תהיה היכן יעובדו ויישמרו הנתונים.

  •  אם תעשה זאת בעצמך, תצרוך את אותם נתונים ממכשירים שונים. אז אתה צריך לעבד ולאחסן נתונים בשרת.
  • אם יש לך הרבה נתונים שונים שנצרכים על ידי משתמשים רבים ושונים, אז אתה צריך להחליט מה יותר חשוב: מהירות המשתמשים או חסכון בברזל בצד שלך. מי שיכול להרשות לעצמו כמות אינסופית של חומרה סופר הכל בשרת שלו ועושה את זה סופר מהיר עבור המשתמשים, חוסך משאבי המשתמש, כמו סוללה ותעבורה, וזה מאוד חשוב בטלפונים.

בתורו, ספירה בדפדפן אינה הפתרון האופטימלי ביותר באופן עקרוני. לכן, מה שלא יקר, אנחנו רואים את זה בשרת שלנו. את השאר אנחנו משאירים ללקוח. אני מאוד רוצה לקחת ולחשב את העמלה על השרת. אבל כאן מגיע הניואנס שנקרא “אינטראקטיביות”. נניח שיש לך אלפי פעולות ולוקח חמש דקות לקבל אותן. מה יהיה למשתמש בשלב זה? טוֹוֶה? התקדמות? מידע על כמה הועלה? זה אידיאלי להשתמש ב”המתנה פעילה” כאשר המשתמש בתהליך כבר יכול היה לראות משהו. הנה התוצאה:אנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.

  • טעינת עמוד
  • כל החשבוניות מתבקשות
  • לאחר מכן, כל העסקאות עם עמלות עבור עסקאות שבוצעו מתבקשות עבור כל החשבונות. כאשר הנתונים מתקבלים, הם מוצגים בדפדפן.

כדי לא לסנן את הנתונים באירועים בכל פעם, אנו מושכים אירוע משלנו לכל חשבון. ככה:

socket.emit(‘sdk:getOperationsCommissionResult_’ + accountId, {                 items: data?.items,                 inProgress: Boolean(nextCursor), });

הטיוטה להפעלה נמצאת כאן: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 להמשיך הלאה. איזה כיף שקראת את השורה הזו! 

חישוב ופלט של מידע מעניין

תלוי מי צריך איזה מידע. לכן, אני מיד אומר לך את הניואנסים העיקריים שאתה תיתקל בהם.

עובדים עם מחירים 

כל מי שעובד עם פיננסים יודע שעסקאות כסף צריכות להתבצע רק עם מספרים שלמים. בשל אי דיוק הערכים לאחר הנקודה העשרונית והשגיאה המצטברת עם מספר רב של פעולות. לכן כל המחירים מוצגים בפורמט MoneyValue הבאאנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.

שדהסוּגתיאור
מַטְבֵּעַחוּטמחרוזת קוד מטבע ISO
יחידותint64חלק שלם של הסכום, יכול להיות מספר שלילי
ננוint32חלק חלקי של הכמות, יכול להיות מספר שלילי

אנו מעבדים אותם בנפרד, ואז מביאים אותם לערך המחיר:

quotation.units + quotation.nano / 1e9

העלות של חוזים עתידיים

מחיר החוזים העתידיים מוצג בנקודות, כאשר יש לך עתיד מטבע, אתה צריך לדעת את השער. וכמובן המחיר בנקודות ומדרגת המחיר. כאשר אתה מחשב את הרווח מעסקאות, זה יכול לירות, כי. אם תחשב את הסכום הכולל על ידי הכפלת המחיר בכמות. כאן אתה צריך להיות זהיר. בינתיים נראה איך זה ילך. זה חל על חוזים עתידיים על מטבעות, במקומות אחרים הכל בסדר עם זה.אנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.אנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.

שוק OTC

לשוק הזה יש הרבה מוזרויות, אז בואו נלמד עליו פעולות בנפרד, כשתתחילו לסנכרן פעולות, יתברר שצריך להביא פיגי/טיקר לאותה צורה כדי להתאים נכון את המכשיר. כשתתחילו לסנכרן את זה עם דו”ח התיווך, יתברר שב- tradeID של אותה עסקה יש אותיות בתחילת העסקאות והן לא נמצאות בדוח התיווך. לכן, אי אפשר להשוות ביניהם… אהמ-אהם… לשם השוואה! התאמתי את זמן המסחר, הטיקר וההתאמה לכך ש- tradeId אחד כלול באחר. נכון, אני לא יודע. מי שנתקל בזה ולמי אכפת ממנו, יבוא לנושא או יתחיל חדש.אנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.

פעולות מתמטיות על כלים

אי אפשר, בלי להסתכל, לבצע פעולות מתמטיות עם כל הרשימה. כדי לא להוסיף חם לרך, אנחנו תמיד בודקים את המטבע ומעבדים רק אם אנחנו בטוחים שהמטבע תואם, והנקודות מומרות למטבע הרצוי. חמושים בידע על עבודה עם מספרי בנקים, נחשב את העמלה שהוצאה על כל אחד מהחשבונות. כך: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4אנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.   

Microservice מוכן!

https://github.com/pskucherov/tcsstat כשיעורי בית, ניתן לבדוק אם השירות עובד עם חיבור איטי, כאשר חיבורים מנותקים, כאשר האינטרנט מתנתק, כאשר שגיאות או מגבלות שפג תוקפן מצד המתווך. 

מסקנות ותוכניות לעתיד

  • למד על פעולות בסיסיות ועבודה עם ה-API של Invest
  • זמן שהושקע ~ 10 שעות
  • דרגת קושי ~ ג’וניור+ / בינוני נמוך 

אם תמשיך לחדד את המיקרו-שירות, אתה עלול להסתיים עם משהו כזה

https://opexbot.info

  זו ההתפתחות שלי, למי שמתעצל להבין, לרוץ ולספור בעצמו. אני מתכנן להוסיף שם אנליטיקס לבקשת המשתמשים. אם אהבתם את המאמר, הירשמו לערוץ הטלגרם שלי . אנו מפתחים שירות מיקרו המשתמש ב-Tinkoff Invest API לאוטומטי של עבודה עם דוחות תיווך וחישוב עמלות.

Pavel
Rate author
Add a comment

  1. Isakiiev

    Полезная статья. Не могу представить, сколько усилий автора потребовалось, чтобы все описать. Благодарю.

    Reply