Kehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.

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

Tinkoff Investmentsin tilastopalvelun kehittämisen inspiroijat olivat:

Mistä keskustellaan?

  • Vain sovellettu osa kehityksestä.
  • Todellinen tieto ja kokemus, jotka ovat erittäin tärkeitä rahoitusinstrumenttien kanssa työskentelyssä.
  • Yleiskatsaus ongelmiin, joita on käsiteltävä

Joten haluan laskea kauppatilastot ja tehdä sen kätevällä tavalla. 

Tilastopalvelun kehittäminen askel askeleelta: 

  1. Yhteys Tinkoff Invest API:hen
  2. Tietojen piirtäminen Tinkoff Invest API:sta selaimessa
  3. Välitysraporttien ja transaktioiden vastaanottaminen
  4. Mielenkiintoisen tiedon laskeminen ja tulostaminen
  5. Päätelmät ja tulevaisuuden suunnitelmat

Yhteys Tinkoff Invest API:hen

Voit muodostaa yhteyden sovellusliittymään ottamalla minkä tahansa sdk:n dokumentaatiosta https://github.com/Tinkoff/investAPI#sdk . Tai npm-paketti ` tinkoff-sdk-grpc-js `. On tärkeää, että kehittäjät päivittävät paketin uusimpaan versioon. Asentaa

npm i tinkoff-sdk-grpc-js

Tarkistetaan

const { createSdk } = vaatia(’tinkoff-sdk-grpc-js’);   // Token, joka voidaan saada näin  const TOKEN = ’YOURAPI’;   // Sen sovelluksen nimi, jolla sinut löytyy TCS:n lokeista. const appName = ’tcsstat’;   const sdk = createSdk(TOKEN, sovelluksen nimi); (async () => {     console.log(odota sdk.users.getAccounts()); })();

Tulos: luettelo tileistäsi näkyy konsolissa. Analysoidaanpa esimerkiksi vivahteita:Kehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.

  • Tililuettelossa on ”Investointipankki”, jonka kanssa et voi työskennellä API:lla
  • Huomaa, että kentät ovat camelCase, kun taas dokumentaatiossa nämä kentät esitetään under_score. 
  • Näin on kaikkialla, joten et voi vain ottaa ja kopioida kenttää dokumentaatiosta.

Hyödyllinen:

  • Löydät tämän koodin projektisivuilta

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

Tietojen piirtäminen Tinkoff Invest API:sta selaimessa

Otin next.js:n ja socket.io:n. Tämä ei ole vahva suositus, valitse harkintasi mukaan. 

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

Siirrymme välittömästi ystävyysvaiheeseen next+socket+investapi, ja katso kaikki yksityiskohdat tämän vaiheen  Hyödyllinen- osiosta. Selitän yksityiskohdat: 

  • Nodejs- (palvelin) puolella on pages/api/investapi.js-tiedosto. Täällä luomme socket.io-palvelimen ja muodostamme yhteyden investapiin.
  • Selaimen (asiakas) puolella muodostamme yhteyden palvelimeen socketin kautta ja pyydämme tilitietoja välittäjältä. 
  • Vastaanotamme tiedot välittäjältä palvelimella ja lähetämme ne sitten asiakkaalle. Kun ne vastaanotetaan asiakkaalle, ne näkyvät selaimessa. 

Tulos:  selainkonsolissa näemme tietoja tileistä. Eli viimeisessä vaiheessa näimme tiedot tileistä palvelinkonsolissa (nodejs), nykyisessä vaiheessa siirsimme nämä tiedot asiakkaalle (selaimeen).

Kehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.

Tehdään nyt niin, että voit valita tilin selaimesta, ja jos merkkiä ei ole, niin konsoliin lähetetään virhe. Työ on yksinkertainen eikä mitään uutta, joten annan vain linkit sitoumuksiin

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

Hyödyllinen:

  • Kuinka saada ystäviä seuraavaksi ja socket on kuvattu yksityiskohtaisesti täällä
  • Ystävyyskoodi next+socket+investapi:

https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 Kenelle yllä oleva on vaikeaa, jäämme tähän vaiheeseen ja käsittelemme koodia. Jos sinulla on kysyttävää – kysy. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2

Välitysraporttien ja transaktioiden vastaanottaminen

Välitysraporttien ja transaktioiden vastaanottamiseen on kolme tapaa

  1. GetBrokerReport
  2. GetDividendsForeignIssuer
  3. GetOperationsByCursor

Alusta alkaen on tärkeää tietää: 

  • Välitysraportti generoidaan T-3-moodissa, ts. kaupat näytetään siellä niiden todellisen toteutuksen jälkeen. 
  • Jos siis pyydät tätä raporttia kahdelta viimeiseltä päivältä, se on valmis kolmessa päivässä. 
  • Viimeisten päivien tapahtumien saamiseksi käytämme tapahtumien vastaanottotapaa, mutta muista, että niiden tunnus ja sisältö voivat muuttua välitysraportin luomisen jälkeen.

GetBrokerReport

Välitysraportin saamiseksi sinun tulee ottaa tilitunnus, alkamispäivä ja raportin päättymispäivä, mutta enintään 31 päivää. Lähetämme raportin luomista koskevan pyynnön API:lle kohdassa genero _broker_report_request , saat vastauksena tehtävätunnuksen. Sen jälkeen, käyttämällä tätä taskId:tä, saamme dataa get _broker_report_response -palvelusta.

Dokumentaatiossa sanotaan, että todellisuudessa on vivahteita. Varo käsiäsi:
  • Sinun on tallennettava TaskID ikuisesti juuri näitä päivämääriä varten. 
  • Koska jos kadotat sen, pyydettyinä päivinä raportti tulee ensin vastauksena luomispyyntöön, 
  • Ja sitten se ei tule ollenkaan.
Aloitetaan koodin kirjoittaminen

Menetelmä päivämäärän saamiseksi, kun otetaan huomioon vähennys nykyisestä päivämäärästä

const getDateSubDay = (alipäivä = 5, aloitus = tosi) => {     const date = new Date();     päivämäärä.setUTCDate(päiväys.getUTCDate() – alipäivä);       if (alku) {         päivämäärä.setUTCHours(0, 0, 0, 0);     } else {         date.setUTCHours(23, 59, 59, 999);     }       palautuspäivä; };

Raportin luontipyyntö 

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

Tulos:

  • Ensimmäisen komennon suorituksen tuloksena saamme taskId:n. 
  • Raportti alkaa luoda välittäjän puolelta. Kun se on valmis, sitä ei tiedetä, odotamme ja vedämme määräajoin taskId:n raporttia odotellessa.
  • Miksi? Koska jos raportti ei ole valmis, se antaa virheen. Jos raportti ei ole valmis välittäjän puolella, tämä on virhe koodissasi. Käsittele: 30058|INVALID_ARGUMENT|tehtävää ei ole vielä suoritettu, yritä myöhemmin uudelleen

Raportin odottamisen ja vastaanottamisen koodi näyttää suunnilleen tältä.

const timer = async time => {     return new Promise(resolve => setTimeout(resolve, time)); }   const getBrokerResponseByTaskId = async (tehtävätunnus, sivu = 0) => {     yritä {         paluu odottaa (sdk.operations.getBrokerReport)({             getBrokerReportRequest: {                 tehtävätunnus,                 sivu,             },         });     } catch (e) {         console.log(’odota’, e);         odota ajastin (10000);         paluu odottaa getBrokerResponseByTaskId(tehtävätunnus, sivu);     } };

Sitten tapahtuu sama taika. Pysäytämme käsikirjoituksen, aloitamme sen uudelleen, meillä ei ole tehtävätunnusta. Suoritamme koodin taskId-pyynnöllä, mutta emme saa enää taskId:tä, vaan heti raportin. Taika! Ja kaikki olisi hyvin, jos se olisi aina näin. Mutta kuukauden kuluttua ei ole lainkaan tietoja. Hyödyllinen :

  • Hieman teoriaa hahmotellaan täällä ja täällä .
  • Kun koodi yhdistetään, luonnos näyttää suunnilleen tältä.

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

  • Jos joku törmää tähän, niin tervetuloa asiaan . Kun he korjaavat tämän taikuuden, se menettää voimansa ja on jotenkin erilainen. Mutta tällä hetkellä (21.3.2023) se toimii juuri niin.

GetDividendsForeignIssuer

Joku saattaa ajatella, että menetelmä on samanlainen kuin edellinen ja voit käyttää yhtä menetelmää, jossa muutat vain toimintojen nimeä. Mutta he eivät arvannut!  Nimeäminen siellä on hyvin erilainen sekä menetelmissä että palautetuissa tiedoissa. Ja sivumäärä alkaa 0:sta, sitten 1:stä. Jotta ei menisi sekaisin tässä kaikessa, on helpompi kirjoittaa kaksi eri menetelmää. Mikä on outoa, koska työn logiikka on sama. Sylkäisin pitkään, kun yritin tehdä yhtä menetelmää ja koodia oli vähemmän. Tässä ei tule esimerkkejä.

GetOperationsByCursor

Oma suosikkini kolmesta. Vaikka ei tarkin, mutta sopivin. Teemme pyynnön tilin luomisen alusta mahdolliseen enimmäispäivään (tilin sulkemiseen tai nykyiseen). Saamme vastauksen, vie kursori ja pyydämme uudelleen niin kauan kuin dataa on.  Ja koodi on ytimekkäämpi kuin yllä olevissa esimerkeissä.

const timer = async time => {     return new Promise(resolve => setTimeout(resolve, time)); }   const getOperationsByCursor = async (sdk, accountId, from, to, cursor = ”) => {     yritä {         const reqData = {             accountId,             from,             to,             limit: 1000,             state: sdk.OperationState.OPERATION_STATE_EXECUTED,             withoutCommissions: false             ilman kaupat: false,             withoutOvernights: false,             kursori,         };           paluu odottaa sdk.operations.getOperationsByCursor(reqData);     } catch (e) {         odota ajastin(60000);         paluu odottaa getOperationsByCursor(sdk, accountId, from, to, cursor = ”);     } };

Suoritettava luonnos on täällä: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 Nyt olemme valmiita lisäämään vastaanottotoimintoja sovelluksemme. Jos se tehdään oikein, sinun on saatava välitysraportit koko tilin olemassaolosta. Ja puuttuvat tiedot, samat T-3:t, lataa operaatiosta uudelleen. Mutta tämä voidaan jakaa erilliseksi artikkeliksi. Tärkeimmistä kohtaamisista vivahteista on liimaustoimintojen ja välitysraportin liimaaminen.

  •  Jos sait tänään välitysraportin ja tapahtumat vaadituille päivämäärille, laita ne kaikki tietokantaan, ei ole ongelmia. 
  • Sinulla on ongelmia huomenna, kun saat seuraavan osan tietoja raportista ja toiminnoista ja päätät synkronoida ne olemassa olevan tietokannan kanssa. 
  • Paljon vivahteita yhteensopimattomasta tai muuttuvasta tunnisteesta käsittelyn jälkeen
  • Sitten OTC-markkinoilla tunnukset eivät täsmää ollenkaan.
  •  Sekä synkronointiinstrumenttien vivahteet, jotka eivät taaskaan täsmää API:n erityispiirteiden vuoksi. Mutta se onkin toinen tarina.

Lisätään sovellukseemme toimintatietojen saaminen. Pääkysymys on, missä tietoja käsitellään ja säilytetään.

  •  Jos teet sen itse, kulutat samaa dataa eri laitteista. Sitten sinun on käsiteltävä ja tallennettava tiedot palvelimelle.
  • Jos sinulla on paljon erilaista dataa, jota useat eri käyttäjät kuluttavat, sinun on päätettävä, mikä on tärkeämpää: käyttäjien nopeus vai raudan säästö puolellasi. Se, jolla on varaa äärettömään määrään laitteistoa, laskee kaiken palvelimellaan ja tekee siitä erittäin nopean käyttäjille, mikä säästää käyttäjän resursseja, kuten akkua ja liikennettä, mikä on erittäin tärkeää puhelimissa.

Laskeminen selaimessa ei puolestaan ​​ole periaatteessa optimaalisin ratkaisu. Siksi, mikä ei ole kallista, pidämme sitä palvelimellamme. Jätämme loput asiakkaalle. Haluan todella ottaa ja laskea välityspalkkion palvelimelta. Mutta tässä tulee vivahde nimeltä ”vuorovaikutus”. Oletetaan, että sinulla on tuhansia operaatioita ja niiden vastaanottaminen kestää viisi minuuttia. Mitä käyttäjällä on tällä hetkellä? Spinner? Edistystä? Tietoa kuinka paljon ladattiin? On ihanteellista käyttää ”aktiivista odotusta”, kun prosessissa oleva käyttäjä näki jo jotain. Tässä on tulos:Kehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.

  • Sivua ladataan
  • Kaikki laskut pyydetään
  • Tämän jälkeen kaikille tileille pyydetään kaikkia tapahtumia, joissa on suoritetuista tapahtumista palkkioita. Kun tiedot vastaanotetaan, ne hahmonnetaan selaimessa.

Jotta tapahtumien dataa ei suodateta joka kerta, haemme jokaiselle tilille oman tapahtumamme. Kuten tämä:

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

Aloitusluonnos on täällä: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 Jatketaan. Hienoa, että luit tämän rivin! 

Mielenkiintoisen tiedon laskeminen ja tulostaminen

Riippuu kuka tarvitsee mitä tietoa. Siksi kerron sinulle välittömästi tärkeimmät vivahteet, jotka kohtaat.

Työskentely hintojen kanssa 

Jokainen, joka työskentelee rahoituksen parissa, tietää, että rahatapahtumat tulee suorittaa vain kokonaisluvuilla. Johtuen arvojen epätarkkuudesta desimaalipilkun jälkeen ja kumulatiivisesta virheestä suurella määrällä toimintoja. Siksi kaikki hinnat on esitetty seuraavassa MoneyValue -muodossaKehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.

alatyyppiKuvaus
valuuttamerkkijonoMerkkijono ISO-valuuttakoodi
yksiköitäint64Summan kokonaislukuosa, voi olla negatiivinen luku
nanoint32Murto-osa summasta voi olla negatiivinen luku

Käsittelemme ne erikseen ja tuomme ne sitten hinta-arvoon:

quotation.units + quotation.nano / 1e9

Futuurisopimusten kustannukset

Futuurien hinta esitetään pisteinä, kun sinulla on valuuttafutuuri, sinun on tiedettävä kurssi. Ja tietysti hinta pisteinä ja hintaaskel. Kun lasket liiketoimien tuoton, tämä voi ampua, koska. jos lasket kokonaissumman kertomalla hinta määrällä. Tässä sinun on oltava varovainen. Toistaiseksi katsotaan kuinka käy. Tämä koskee valuuttafutuureja, muissa paikoissa kaikki on ok.Kehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.Kehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.

OTC-markkinat

Näillä markkinoilla on paljon erikoisuuksia, joten tutkitaan operaatioita siitä erikseen.Kun aloitat toimintojen synkronoinnin, käy ilmi, että sinun on tuotava figi / ticker samaan muotoon, jotta instrumentti täsmääsi oikein. Kun aloitat tämän synkronoinnin välitysraportin kanssa, käy ilmi, että saman tapahtuman tradeID:ssä on kirjaimet tapahtuman alussa, eikä niitä ole välitysraportissa. Siksi niitä ei voi verrata… ahem-ahem… vertailulla! Yhdistin kaupankäynnin ajan, tickerin ja vastaavuuden, että yksi tradeId sisältyy toiseen. Aivan, en tiedä. Joka kohtaa tämän ja joka välittää siitä, tulkaa asiaan tai aloita uusi.Kehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.

Matemaattiset operaatiot työkaluilla

On mahdotonta, katsomatta, suorittaa matemaattisia operaatioita koko luettelolla. Jotta emme lisää lämpöä pehmeään, tarkistamme aina valuutan ja prosessin vain, jos olemme varmoja, että valuutta täsmää ja pisteet muunnetaan haluttuun valuuttaan. Pankkinumeroiden kanssa työskentelyn tuntevana laskemme kullekin tilille käytetyn palkkion. Näin: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4Kehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.   

Mikropalvelu on valmis!

https://github.com/pskucherov/tcsstat Kotitehtävänä voit tarkistaa, toimiiko palvelu hitaalla yhteydellä, milloin yhteydet katkeavat, milloin nettiyhteys katkeaa, milloin virheitä tai vanhentuneita rajoja välittäjän puolelta. 

Päätelmät ja tulevaisuuden suunnitelmat

  • Opit perustoiminnoista ja Invest API:n kanssa työskentelystä
  • Aikaa käytetty ~ 10 tuntia
  • Vaikeustaso ~ junior+ / matala keskitaso 

Jos jatkat mikropalvelun hiomista, saatat päätyä tällaiseen

https://opexbot.info

  Tämä on minun kehitystäni, niille, jotka ovat liian laiskoja ymmärtämään, juoksemaan ja luottamaan omaan varaan. Aion lisätä sinne analytiikkaa käyttäjien pyynnöstä. Jos pidit artikkelista, tilaa telegram-kanavani . Kehitämme Tinkoff Invest APIa käyttävää mikropalvelua, joka automatisoi välitysraporttien ja palkkioiden laskemisen.

Pavel
Rate author
Add a comment

  1. Isakiiev

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

    Vastaa