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úka typu Popis
mena reťazec Reťazec ISO kódu meny
Jednotky int64 Celá časť súčtu môže byť záporné číslo
nano int32 Zlomková č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