Vyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.

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

Inšpirátormi za vývojom štatistickej služby pre Tinkoff Investments boli:

O čom sa bude diskutovať?

  • Iba aplikovaná časť o vývoji.
  • Skutočné znalosti a skúsenosti, ktoré sú pri práci s finančnými nástrojmi veľmi dôležité.
  • Prehľad problémov, na ktorých treba pracovať

Chcem teda vypočítať obchodné štatistiky a urobiť to pohodlným spôsobom. 

Vývoj štatistickej služby krok za krokom: 

  1. Pripojenie k Tinkoff Invest API
  2. Čerpanie údajov z Tinkoff Invest API v prehliadači
  3. Prijímanie maklérskych správ a transakcií
  4. Výpočet a výstup zaujímavých informácií
  5. Závery a plány do budúcnosti

Pripojenie k Tinkoff Invest API

Ak sa chcete pripojiť k API, môžete si vziať akékoľvek sdk z dokumentácie https://github.com/Tinkoff/investAPI#sdk . Alebo balík npm ` tinkoff-sdk-grpc-js `. Je dôležité, aby vývojári aktualizovali balík na najnovšiu verziu. Inštalácia

npm a tinkoff-sdk-grpc-js

Kontrola

const { createSdk } = require(‘tinkoff-sdk-grpc-js’);   // Token, ktorý možno získať takto  const TOKEN = ‘YOURAPI’;   // Názov aplikácie, pod ktorou vás možno nájsť v protokoloch TCS. const appName = ‘tcsstat’;   const sdk = createSdk(TOKEN, názov aplikácie); (async () => {     console.log(wait sdk.users.getAccounts()); })();

Výsledok: v konzole sa zobrazí zoznam vašich účtov. Napríklad analyzujme nuansy:Vyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.

  • V zozname účtov je „Investičná banka“, s ktorou nemôžete pracovať pomocou API
  • Upozorňujeme, že polia prichádzajú v tvare camelCase, zatiaľ čo v dokumentácii sú tieto polia uvedené v podhodnote. 
  • Bude to tak všade, takže nemôžete len vziať a skopírovať pole z dokumentácie.

Užitočné:

  • Tento kód nájdete vo vetve projektu

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

Čerpanie údajov z Tinkoff Invest API v prehliadači

Vzal som next.js a socket.io. Toto nie je silné odporúčanie, vyberte si podľa vlastného uváženia. 

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

Okamžite prejdeme na krok priateľstva next+socket+investapi a všetky podrobnosti nájdete v časti Užitočné tohto kroku.  Opíšem podrobnosti: 

  • Na strane nodejs (serveru) je súbor pages/api/investapi.js. Tu vytvoríme server socket.io a pripojíme sa k investapi.
  • Na strane prehliadača (klienta) sa pripojíme k serveru cez socket a vyžiadame si od brokera údaje o účte. 
  • Údaje od makléra dostaneme na server a následne ich pošleme klientovi. Keď sú prijaté na klientovi, zobrazia sa v prehliadači. 

Výsledok:  v konzole prehliadača môžeme vidieť informácie o účtoch. To znamená, že v poslednom kroku sme videli informácie o účtoch v konzole servera (nodejs), v aktuálnom kroku sme tieto informácie preniesli do klienta (prehliadača).

Vyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.

Teraz to urobme tak, že si môžete vybrať účet z prehliadača a ak neexistuje žiadny token, do konzoly sa odošle chyba. Práca je jednoduchá a nič nové, preto uvádzam len odkazy na commity

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

Užitočné:

  • Ako získať priateľov ďalej a zásuvku je podrobne popísané tu
  • Kód priateľstva next+socket+investapi:

https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 Pre koho je vyššie uvedené ťažké, potom zostávame v tejto fáze a zaoberáme sa kódom. Ak máte otázky – pýtajte sa. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2

Prijímanie maklérskych správ a transakcií

Existujú tri spôsoby prijímania maklérskych správ a transakcií

  1. GetBrokerReport
  2. GetDividendsForeignIssuer
  3. GetOperationsByCursor

Od samého začiatku je dôležité vedieť: 

  • Správa o sprostredkovaní sa generuje v režime T-3, t.j. obchody sa tam zobrazujú po ich skutočnom vykonaní. 
  • Ak si teda vyžiadate tento prehľad za posledné dva dni, bude pripravený do troch dní. 
  • Na získanie transakcií za posledné dni používame metódu prijímania transakcií, ale nezabudnite, že ich ID a obsah sa môžu po vygenerovaní správy o sprostredkovaní zmeniť.

GetBrokerReport

Ak chcete získať správu o sprostredkovaní, musíte uviesť ID účtu, dátum začiatku a dátum ukončenia správy, ale nie viac ako 31 dní. Požiadavku na vygenerovanie prehľadu odošleme do rozhrania API v generácii _broker_report_request , ako odpoveď dostaneme taskId. Potom pomocou tohto taskId získame údaje z get _broker_report_response.

Takže dokumentácia hovorí, že v skutočnosti existujú nuansy. Pozor na ruky:
  • Musíte uložiť TaskID navždy presne pre tieto dátumy. 
  • Pretože ak ho stratíte, pre požadované dátumy sa správa najskôr zobrazí ako odpoveď na žiadosť o generovanie, 
  • A potom to nepríde vôbec.
Začnime písať kód

Metóda získania dátumu, berúc do úvahy odpočet od aktuálneho dátumu

const getDateSubDay = (subDay = 5, začiatok = true) => {     const date = new Date();     dátum.setUTCDate(dátum.getUTCDate() – poddeň);       if (start) {         date.setUTCHours(0, 0, 0, 0);     } else {         date.setUTCHours(23, 59, 59, 999);     }       dátum návratu; };

Žiadosť o generovanie správy 

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

výsledok:

  • V dôsledku prvého vykonania príkazu získame taskId. 
  • Report sa začne generovať na strane brokera. Keď nie je známe, že je pripravený, počkáme a pravidelne stiahneme taskId v očakávaní správy.
  • prečo? Pretože ak zostava nie je pripravená, vyhodí chybu. Ak správa nie je pripravená na strane makléra, ide o chybu vo vašom kóde. Spracujte prosím: 30058|INVALID_ARGUMENT|úloha ešte nie je dokončená, skúste to znova neskôr

Kód čakania a prijatia hlásenia vyzerá asi takto.

const timer = async time => {     return new Promise(resolve => setTimeout(resolve, time)); }   const getBrokerResponseByTaskId = async (taskId, page = 0) => {     try {         return wait (sdk.operations.getBrokerReport)({             getBrokerReportRequest: {                 taskId,                 page,             },         });     } catch (e) {         console.log(‘wait’, e);         časovač čakania (10000);         return wait getBrokerResponseByTaskId(taskId, page);     } };

Potom sa stane rovnaká mágia. Zastavíme náš skript, spustíme ho znova, nemáme taskId. Spustíme kód s požiadavkou taskId, ale už nedostaneme taskId, ale hneď správu. Kúzlo! A všetko by bolo v poriadku, keby to tak bolo vždy. Ale o mesiac tam nebudú vôbec žiadne dáta. Užitočné :

  • Trochu teórie je načrtnuté tu a tu .
  • Po zostavení kódu bude koncept vyzerať asi takto.

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

  • Ak sa s tým niekto stretne, vitajte v problematike . Keď túto mágiu opravia, stratí svoju silu a bude akosi iná. Ale momentálne (21.3.2023) to funguje presne tak.

GetDividendsForeignIssuer

Niekto by si mohol myslieť, že metóda je podobná predchádzajúcej a môžete použiť jednu metódu, v ktorej zmeníte iba názov operácií. Ale neuhádli!  Pomenovanie sa tam veľmi líši v metódach aj vo vrátených informáciách. A počet strán začína od 0, potom od 1. Aby ste sa v tom všetkom nezamotali, je jednoduchšie napísať dve rôzne metódy. Čo je zvláštne, pretože logika práce je rovnaká. Pľuval som dlho, keď som sa snažil urobiť jednu metódu a bolo tam menej kódu. Nebudú tu žiadne príklady.

GetOperationsByCursor

Môj najobľúbenejší z troch. Síce nie najpresnejšie, ale najprimeranejšie. Žiadosť robíme od začiatku založenia účtu do maximálneho možného dátumu (zrušenie účtu alebo aktuálneho). Dostaneme odpoveď, vezmeme kurzor a znova požiadame, pokiaľ sú k dispozícii údaje.  A kód je stručnejší ako v príkladoch vyššie.

const timer = async time => {     return new Promise(resolve => setTimeout(resolve, time)); }   const getOperationsByCursor = async (sdk, accountId, from, to, kurzor = ”) => {     try {         const reqData = {             accountId,             from,             to,             limit: 1000,             state: sdk.OperationState.OPERATION_STATE_EXECUTED,             withoutCommissions: false,             withoutTrades: false,             withoutOvernights: false,             kurzor,         };           return wait sdk.operations.getOperationsByCursor(reqData);     } catch (e) {         wait timer(60000);         return wait getOperationsByCursor(sdk, accountId, from, to, cursor = ”);     } };

Návrh na spustenie je tu: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 Teraz sme pripravení pridať operácie prijímania do našu aplikáciu. Ak sa to urobí správne, musíte získať správy o sprostredkovaní za celú existenciu účtu. A pre chýbajúce údaje sa tie isté T-3 načítajú z operácií. To sa však dá rozdeliť do samostatného článku. Medzi hlavné nuansy, s ktorými sa stretnete, patrí lepenie operácií a maklérska správa.

  •  Ak ste dnes dostali sprostredkovateľskú správu a transakcie k požadovaným dátumom, vložte to všetko do databázy, potom nie sú žiadne problémy. 
  • Zajtra budete mať problémy, keď dostanete ďalšiu časť údajov zo správy a operácií a rozhodnete sa ich synchronizovať s existujúcou databázou. 
  • Veľa nuancií o nezhode alebo zmene ID po spracovaní
  • Potom pre OTC trh sa ID vôbec nezhodujú.
  •  Rovnako ako nuansy synchronizačných nástrojov, ktoré sa opäť nezhodujú kvôli zvláštnostiam API. Ale to je už iný príbeh.

Pridajme do našej aplikácie získavanie informácií o operáciách. Hlavnou otázkou bude, kde sa budú údaje spracovávať a uchovávať.

  •  Ak to urobíte pre seba, budete konzumovať rovnaké dáta z rôznych zariadení. Potom musíte spracovať a uložiť údaje na serveri.
  • Ak máte veľa rôznych dát spotrebovaných mnohými rôznymi používateľmi, musíte sa rozhodnúť, čo je dôležitejšie: rýchlosť používateľov alebo úspora železa na vašej strane. Ktokoľvek si môže dovoliť nekonečné množstvo hardvéru, počíta všetko na svojom serveri a robí to pre používateľov super rýchlym, čím šetrí zdroje používateľa, ako je batéria a prevádzka, čo je na telefónoch veľmi dôležité.

Počítanie v prehliadači zasa nie je v princípe najoptimálnejším riešením. Čo teda nie je drahé, to zvažujeme na našom serveri. Ostatné necháme na klientovi. Naozaj chcem vziať a vypočítať províziu na serveri. Tu však prichádza nuansa nazývaná „interaktivita“. Povedzme, že máte tisíce operácií a ich prijatie trvá päť minút. Čo bude mať používateľ v tomto čase? Spinner? Pokrok? Infa o tom, koľko sa odovzdalo? Ideálne je použiť „aktívne čakanie“, keď používateľ v procese už niečo vidí. Tu je výsledok:Vyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.

  • Načítavanie stránky
  • Vyžadujú sa všetky faktúry
  • Potom sú pre všetky účty požadované všetky transakcie s províziou za uskutočnené transakcie. Po prijatí údajov sa tieto údaje vykreslia v prehliadači.

Aby sme údaje v udalostiach nefiltrovali zakaždým, pre každý účet vytiahneme vlastnú udalosť. Páči sa ti to:

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

Návrh na spustenie je tu: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 Ideme ďalej. Je skvelé, že ste si prečítali tento riadok! 

Výpočet a výstup zaujímavých informácií

Záleží na tom, kto aké informácie potrebuje. Preto vám okamžite poviem hlavné nuansy, s ktorými sa stretnete.

Práca s cenami 

Každý, kto pracuje s financiami, vie, že peňažné transakcie by sa mali vykonávať len s celými číslami. Kvôli nepresnosti hodnôt za desatinnou čiarkou a kumulatívnej chybe s veľkým počtom operácií. Preto sú všetky ceny prezentované v nasledujúcom formáte MoneyValueVyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.

lúkatypuPopis
menareťazecReťazec ISO kódu meny
Jednotkyint64Celá časť súčtu môže byť záporné číslo
nanoint32Zlomková časť sumy môže byť záporné číslo

Samostatne ich spracovávame, potom ich uvádzame na cenovú hodnotu:

ponuka.jednotky + ponuka.nano / 1e9

Náklady na futures kontrakty

Cena futures je prezentovaná v bodoch, keď máte menovú futures, musíte poznať kurz. A samozrejme cena v bodoch a cenový stupeň. Keď spočítate zisk z transakcií, môže to vystreliť, pretože. ak vypočítate celkovú sumu vynásobením ceny množstvom. Tu si treba dávať pozor. Zatiaľ uvidíme, ako to pôjde. To platí pre menové futures, na iných miestach je s tým všetko v poriadku.Vyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.Vyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.

OTC trh

Tento trh má veľa zvláštností, takže poďme študovať operácie na ňom oddelene. Keď začnete synchronizovať operácie, ukáže sa, že musíte uviesť figi / ticker do rovnakej formy, aby ste správne spárovali nástroj. Keď to začnete synchronizovať s maklérskou správou, ukáže sa, že tradeID tej istej transakcie má v transakciách na začiatku písmená a tie nie sú v sprostredkovateľskej správe. Preto ich nemožno porovnávať … ehm-ehm … porovnaním! Priradil som čas obchodu, ticker a párovanie, že jedno tradeId je obsiahnuté v inom. Dobre, neviem. Kto sa s tým stretne a komu na tom záleží, príďte do čísla alebo založte nové.Vyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.

Matematické operácie na nástrojoch

Bez toho, aby ste sa pozreli, nie je možné vykonávať matematické operácie s celým zoznamom. Aby sme nepridali teplé do mäkkého, menu kontrolujeme a spracovávame vždy len vtedy, ak sme si istí, že sa mena zhoduje, a body sú prepočítané na požadovanú menu. Vyzbrojení znalosťami o práci s bankovými číslami vypočítame províziu vynaloženú na každý z účtov. Takto: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4Vyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.   

Mikroservis je pripravený!

https://github.com/pskucherov/tcsstat Ako domácu úlohu si môžete skontrolovať, či služba funguje s pomalým pripojením, pri prerušení pripojenia, pri odpojení internetu, pri chybách alebo vypršaní limitov na strane brokera. 

Závery a plány do budúcnosti

  • Naučili ste sa základné operácie a prácu s Invest API
  • Čas strávený ~ 10 hodín
  • Úroveň obtiažnosti ~ junior+ / nízka stredná 

Ak budete pokračovať v zdokonaľovaní mikroslužby, môžete skončiť s niečím takýmto

https://opexbot.info

  Toto je môj vývoj, pre tých, ktorí sú príliš leniví na to, aby pochopili, utekali a počítali sami. Plánujem tam pridať analytiku na žiadosť používateľov. Ak sa vám článok páčil, prihláste sa na odber môjho telegramového kanála . Vyvíjame mikroslužbu využívajúcu Tinkoff Invest API na automatizáciu práce s maklérskymi správami a výpočtom provízií.

Pavel
Rate author
Add a comment

  1. Isakiiev

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

    Reply