Arendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.

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

Tinkoff Investmentsi statistikateenuse arendamise inspireerijad olid:

Mida arutatakse?

  • Ainult rakenduslik osa arengust.
  • Reaalsed teadmised ja kogemused, mis on finantsinstrumentidega töötamisel väga olulised.
  • Ülevaade probleemidest, millega töötada

Niisiis, ma tahan arvutada kaubandusstatistikat ja teha seda mugaval viisil. 

Statistikateenuse samm-sammult arendamine: 

  1. Ühendus Tinkoff Invest API-ga
  2. Andmete joonistamine Tinkoff Invest API-st brauseris
  3. Vahendusaruannete ja tehingute vastuvõtmine
  4. Huvipakkuva teabe arvutamine ja väljastamine
  5. Järeldused ja tulevikuplaanid

Ühendus Tinkoff Invest API-ga

API-ga ühenduse loomiseks võite võtta mis tahes sdk dokumentatsioonist https://github.com/Tinkoff/investAPI#sdk . Või npm pakett ` tinkoff-sdk-grpc-js `. On oluline, et arendajad värskendaksid paketti uusimale versioonile. Installige

npm ma tinkoff-sdk-grpc-js

Kontrollimine

const { createSdk } = nõuda(‘tinkoff-sdk-grpc-js’);   // Token, mille saab hankida niimoodi  const TOKEN = ‘YOURAPI’;   // Rakenduse nimi, mille järgi teid TCS-i logides leiate. const appName = ‘tcsstat’;   const sdk = createSdk(TOKEN, rakenduse nimi); (async () => {     console.log(oota sdk.users.getAccounts()); })();

Tulemus: konsoolis kuvatakse teie kontode loend. Näiteks analüüsime nüansse:Arendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.

  • Kontode loendis on “Investeerimispank”, millega ei saa API-ga töötada
  • Pange tähele, et väljad on kirjas camelCase, samas kui dokumentatsioonis on need väljad esitatud tähega under_score. 
  • See on kõikjal nii, nii et te ei saa lihtsalt võtta ja kopeerida välja dokumentatsioonist.

Kasulik:

  • Selle koodi leiate projekti harust

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

Andmete joonistamine Tinkoff Invest API-st brauseris

Võtsin next.js ja socket.io. See ei ole tugev soovitus, valige oma äranägemise järgi. 

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

Jätkame kohe sõpruse sammuga next+socket+investapi ja vaatame selle sammu jaotist Kasulik , et näha kõiki üksikasju.  Kirjeldan üksikasju: 

  • Nodejs-i (serveri) poolel on fail pages/api/investapi.js. Siin loome socket.io serveri ja loome ühenduse Investapiga.
  • Brauseri (kliendi) poolel loome pesa kaudu ühenduse serveriga ja küsime maaklerilt konto andmeid. 
  • Võtame maaklerilt andmed vastu serveris, seejärel saadame need kliendile. Kui need kliendile vastu võetakse, kuvatakse need brauseris. 

Tulemus:  brauseri konsoolis näeme teavet kontode kohta. See tähendab, et viimases etapis nägime serverikonsoolis (nodejs) teavet kontode kohta, praeguses etapis edastasime selle teabe kliendile (brauserile).

Arendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.

Nüüd teeme nii, et saad brauserist konto valida ja kui tokenit pole, siis saadetakse konsooli tõrge. Töö on lihtne ja ei midagi uut, seega annan ainult kohustuste lingid

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

Kasulik:

  • Kuidas järgmiseks ja socketiga sõbrustada, kirjeldatakse täpsemalt siin
  • Sõpruskood next+socket+investapi:

https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 Kellele eelnev on raske, siis jääme sellesse etappi ja tegeleme koodiga. Kui teil on küsimusi – küsige. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2

Vahendusaruannete ja tehingute vastuvõtmine

Vahendusaruannete ja tehingute saamiseks on kolm meetodit

  1. GetBrokerReport
  2. GetDividendsForeignIssuer
  3. GetOperationsByCursor

Algusest peale on oluline teada: 

  • Vahendusaruanne genereeritakse T-3 režiimis, s.o. tehingud kuvatakse seal pärast nende tegelikku teostamist. 
  • Seega, kui taotlete seda aruannet viimase kahe päeva kohta, on see valmis kolme päevaga. 
  • Viimaste päevade tehingute saamiseks kasutame tehingute vastuvõtmise meetodit, kuid pidage meeles, et nende ID ja sisu võivad pärast vahendusaruande koostamist muutuda.

GetBrokerReport

Vahendusaruande saamiseks tuleb võtta konto ID, aruande algus- ja lõppkuupäev, kuid mitte rohkem kui 31 päeva. Saadame API-le aruande genereerimise taotluse genereerida _broker_report_request , vastuseks saame ülesande ID. Pärast seda saame selle taskId abil andmed saidilt get _broker_report_response.

Nii ütleb dokumentatsioon, et tegelikkuses on nüansse. Vaadake oma käsi:
  • Peate TaskID igaveseks salvestama täpselt nendeks kuupäevadeks. 
  • Kuna kui te selle kaotate, tuleb aruanne soovitud kuupäevade puhul esmalt vastusena genereerimistaotlusele, 
  • Ja siis ei tule üldse.
Hakkame koodi kirjutama

Kuupäeva saamise meetod, võttes arvesse praegusest kuupäevast lahutamist

const getDateSubDay = (alampäev = 5, algus = tõene) => {     const date = new Date();     kuupäev.setUTCDate(kuupäev.getUTCDate() – alampäev);       if (algus) {         date.setUTCHours(0, 0, 0, 0);     } else {         date.setUTCHours(23, 59, 59, 999);     }       tagastamise kuupäev; };

Aruande loomise taotlus 

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

Tulemus:

  • Käsu esmakordse täitmise tulemusena saame ülesandeId. 
  • Raportit hakatakse genereerima maakleri poolel. Kui see on valmis, pole teada, ootame ja tõmbame aruande ootuses perioodiliselt ülesande ID.
  • Miks? Sest kui aruanne pole valmis, annab see vea. Kui aruanne pole maakleri poolel valmis, on see viga teie koodis. Töötle: 30058|INVALID_ARGUMENT|ülesanne pole veel lõpetatud, proovige hiljem uuesti

Aruande ootamise ja vastuvõtmise kood näeb välja umbes selline.

const taimer = async time => {     return new Promise(resolve => setTimeout(resolve, time)); }   const getBrokerResponseByTaskId = async (taskId, page = 0) => {     proovige {         return ootama (sdk.operations.getBrokerReport)({             getBrokerReportRequest: {                 taskId,                 page,             },         });     } catch (e) {         console.log(‘oota’, e);         oota taimer (10000);         return ootama getBrokerResponseByTaskId(taskId, page);     } };

Siis juhtub sama maagia. Peatame oma skripti, käivitame selle uuesti, meil pole ülesande ID-d. Koodi käivitame koos taskId päringuga, kuid me ei saa enam taskId, vaid kohe aruannet. Maagia! Ja kõik oleks hästi, kui see oleks alati nii. Kuid kuu aja pärast pole andmeid üldse. Kasulik :

  • Natuke teooriat on välja toodud siin ja siin .
  • Koodi kokku pannes näeb mustand välja umbes selline.

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

  • Kui keegi sellega kokku puutub, siis tere tulemast selle teema juurde . Pärast seda, kui nad selle maagia parandavad, kaotab see oma jõu ja muutub kuidagi teistsuguseks. Aga praegusel hetkel (21.03.2023) toimib see just nii.

GetDividendsForeignIssuer

Keegi võib arvata, et meetod on eelmisega sarnane ja saate kasutada ühte meetodit, mille puhul muudate ainult toimingute nime. Aga nad ei arvanud!  Sealne nimetamine on väga erinev nii meetodites kui ka tagastatavas infos. Ja lehekülgede arv algab 0-st, seejärel 1-st. Et selles kõiges mitte segadusse sattuda, on lihtsam kirjutada kaks erinevat meetodit. Mis on kummaline, sest töö loogika on sama. Sülitasin tükk aega, kui proovisin ühte meetodit teha ja koodi oli vähem. Siin ei tule näiteid.

GetOperationsByCursor

Minu lemmik kolmest. Kuigi mitte kõige täpsem, kuid kõige adekvaatsem. Teeme päringu konto loomise algusest kuni maksimaalse võimaliku kuupäevani (konto sulgemine või praegune). Saame vastuse, võtame kursori ja küsime uuesti, kuni andmeid on.  Ja kood on ülevaatlikum kui ülaltoodud näidetes.

const taimer = async time => {     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             ilma tehinguteta: vale,             ilmaOvernights: vale,             kursor,         };           tagasi ootama sdk.operations.getOperationsByCursor(reqData);     } püüda (e) {         ootama taimerit (60000);         return ootama getOperationsByCursor(sdk, kontoId, from, to, cursor = ”);     } };

Käivitav mustand on siin: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 Nüüd oleme valmis lisama vastuvõtutoimingud meie rakendus. Kui see on õigesti tehtud, peate kogu konto olemasolu kohta saama vahendusaruandeid. Ja puuduvate andmete jaoks laadige need samad T-3-d operatsioonidest uuesti. Kuid selle saab jagada eraldi artikliks. Peamistest nüanssidest, millega kokku puutute, on toimingute liimimine ja vahendusaruanne.

  •  Kui täna saite maakleriaruande ja tehingud nõutud kuupäevadeks, pange see kõik andmebaasi, siis pole probleeme. 
  • Teil on probleeme homme, kui saate aruandest ja toimingutest järgmise osa andmeid ja otsustate need olemasoleva andmebaasiga sünkroonida. 
  • Palju nüansse sobimatuse või ID muutmise kohta pärast töötlemist
  • Siis ei ühti börsivälise turu ID-d üldse.
  •  Nagu ka instrumentide sünkroniseerimise nüansid, mis API iseärasuste tõttu jällegi kokku ei lange. Aga see on teine ​​lugu.

Lisame oma rakendusse toimingute kohta teabe hankimise. Peamine küsimus on selles, kus andmeid töödeldakse ja säilitatakse.

  •  Kui teete seda enda jaoks, tarbite samu andmeid erinevatest seadmetest. Seejärel peate andmeid töötlema ja serverisse salvestama.
  • Kui teil on palju erinevaid andmeid, mida tarbivad paljud erinevad kasutajad, siis peate otsustama, mis on olulisem: kas kasutajate kiirus või teie poolel raua kokkuhoid. Kes saab endale lubada lõputult palju riistvara, loeb oma serveris kõik üle ja teeb selle kasutajate jaoks ülikiireks, säästes kasutaja ressursse, nagu akut ja liiklust, mis on telefonide puhul väga oluline.

Omakorda pole brauseris loendamine põhimõtteliselt kõige optimaalsem lahendus. Seetõttu peame seda oma serveris, mis pole kallis. Ülejäänu jätame kliendi hooleks. Ma tõesti tahan võtta ja arvutada vahendustasu serveris. Kuid siin tuleb nüanss, mida nimetatakse interaktiivsuseks. Oletame, et teil on tuhandeid toiminguid ja nende vastuvõtmiseks kulub viis minutit. Mis on kasutajal sel ajal? Spinner? Edusamme? Infa, kui palju üles laaditi? Ideaalne on kasutada “aktiivset ootamist”, kui protsessis olev kasutaja juba midagi näeb. Siin on tulemus:Arendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.

  • Lehekülje laadimine
  • Kõik arved palutakse
  • Pärast seda küsitakse kõikidele kontodele kõiki tehtud tehingute vahendustasudega tehinguid. Andmete vastuvõtmisel renderdatakse need brauseris.

Et mitte iga kord sündmuste andmeid filtreerida, tõmbame iga konto jaoks oma sündmuse. Nagu nii:

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

Käivitamise mustand on siin: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 Edasi. Tore, et sa seda rida lugesid! 

Huvipakkuva teabe arvutamine ja väljastamine

Oleneb, kes millist infot vajab. Seetõttu ütlen teile kohe peamised nüansid, millega te kokku puutute.

Töö hindadega 

Kõik, kes rahandusega tegelevad, teavad, et rahatehinguid tuleks teha ainult täisarvudega. Komajärgsete väärtuste ebatäpsuse ja suure arvu toimingutega kaasneva kumulatiivse vea tõttu. Seetõttu on kõik hinnad esitatud järgmises MoneyValue formaadisArendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.

valdkonnastüüpKirjeldus
valuutastringString ISO valuutakood
ühikutint64Summa täisarv osa, võib olla negatiivne arv
nanoint32Summa murdosa, võib olla negatiivne arv

Töötleme neid eraldi, seejärel viime need hinnaväärtuseni:

tsitaat.ühikud + tsitaat.nano / 1e9

Futuurlepingute maksumus

Futuuride hind on esitatud punktides, kui teil on valuutafutuur, peate teadma kursi. Ja muidugi hind punktides ja hinnasamm. Tehingute kasumi arvutamisel võib see tulistada, sest. kui arvutate kogusumma korrutades hinna kogusega. Siin peate olema ettevaatlik. Praegu vaatame, kuidas läheb. See kehtib valuutafutuuride kohta, mujal on sellega kõik ok.Arendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.Arendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.

OTC turg

Sellel turul on palju iseärasusi, seega uurime selle kohta tehteid eraldi. Kui hakkate toiminguid sünkroonima, siis selgub, et instrumendi õigeks sobitamiseks peate viima figi / ticker samale vormile. Kui hakkate seda maakleriaruandega sünkroonima, siis selgub, et sama tehingu tradeID-l on tehingute alguses tähed ja neid pole maakleriaruandes. Seetõttu ei saa neid võrrelda … ahem-ahem … võrdlusega! Ma sobitasin kauplemisaja, tähise ja sobitamise, et üks tradeId sisaldub teises. Õige, ma ei tea. Kes sellega kokku puutub ja keda see huvitab, tulge teema juurde või alustage uut.Arendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.

Matemaatilised tehted tööriistadega

Ilma vaatamiseta on võimatu sooritada matemaatilisi tehteid kogu loendiga. Selleks, et mitte soojalt pehmele lisada, kontrollime alati valuutat ja töötleme ainult siis, kui oleme kindlad, et valuuta klapib ning punktid konverteeritakse soovitud valuutasse. Olles teadlik panganumbritega töötamise kohta, arvutame igale kontole kulutatud komisjonitasu. Nagu see: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4Arendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.   

Mikroteenus on valmis!

https://github.com/pskucherov/tcsstat Kodutööna saate kontrollida, kas teenus töötab aeglase ühendusega, millal ühendused katkevad, kui Interneti-ühendus katkeb, millal on maakleri vead või aegunud limiidid. 

Järeldused ja tulevikuplaanid

  • Õppis tundma põhitoiminguid ja Invest API-ga töötamist
  • Aega kulus ~ 10 tundi
  • Raskusaste ~ juunior+ / madal keskmine 

Kui jätkate mikroteenuse täiustamist, võib teil tekkida midagi sellist

https://opexbot.info

  See on minu areng, neile, kes on liiga laisad, et ise aru saada, joosta ja loota. Plaanin sinna kasutajate soovil analüütika lisada. Kui teile artikkel meeldis, siis tellige minu telegrammi kanal . Arendame välja Tinkoff Invest API-t kasutades mikroteenust, et automatiseerida maakleriaruannetega töötamist ja komisjonitasude arvutamist.

Pavel
Rate author
Add a comment

  1. Isakiiev

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

    Reply