A Tinkoff Investments statisztikai szolgáltatásának fejlesztése mögött inspirálók a következők voltak:
- cikk Habréról „Amit nem mond a Tinkoff Investments”
- a platform felhasználói kívánságainak elemzése
- egy cikk a jutalékok kiszámításáról .
- Miről lesz szó?
- Statisztikai szolgáltatás fejlesztése lépésről lépésre:
- Csatlakozás a Tinkoff Invest API-hoz
- Adatok rajzolása a Tinkoff Invest API-ból egy böngészőben
- Ügynöki jelentések és tranzakciók fogadása
- GetBrokerReport
- A dátum lekérésének módja, figyelembe véve az aktuális dátumból való kivonást
- Jelentés generálási kérés
- Eredmény:
- GetDividendsForeignSsuer
- GetOperationsByCursor
- Az érdeklődésre számot tartó információk kiszámítása és kiadása
- Az árakkal való munka
- A határidős szerződések költsége
- OTC piac
- Matematikai műveletek szerszámokon
- A mikroszolgáltatás készen áll!
- Következtetések és tervek a jövőre nézve
- https://opexbot.info
Miről lesz szó?
- Csak az alkalmazott rész a fejlesztésről.
- Valódi tudás és tapasztalat, ami nagyon fontos a pénzügyi eszközökkel való munka során.
- A megoldandó problémák áttekintése
Tehát a kereskedelmi statisztikákat szeretném kiszámítani, és ezt kényelmes módon megtenni.
Statisztikai szolgáltatás fejlesztése lépésről lépésre:
- Csatlakozás a Tinkoff Invest API-hoz
- Adatok rajzolása a Tinkoff Invest API-ból egy böngészőben
- Ügynöki jelentések és tranzakciók fogadása
- Az érdeklődésre számot tartó információk kiszámítása és kiadása
- Következtetések és tervek a jövőre nézve
Csatlakozás a Tinkoff Invest API-hoz
Az API-hoz való csatlakozáshoz a https://github.com/Tinkoff/investAPI#sdk dokumentációból bármelyik sdk-t átveheti . Vagy npm csomag ` tinkoff-sdk-grpc-js `. Fontos, hogy a csomagot a fejlesztők frissítsék a legújabb verzióra. Telepítés
npm a tinkoff-sdk-grpc-js
Ellenőrzés
const { createSdk } = request(‘tinkoff-sdk-grpc-js’); // Az így beszerezhető token const TOKEN = ‘YOURAPI’; // Az alkalmazás neve, amellyel a TCS-naplókban megtalálható. const appName = ‘tcsstat’; const sdk = createSdk(TOKEN, appName); (async () => { console.log(wait sdk.users.getAccounts()); })();
Eredmény: a fiókok listája megjelenik a konzolon. Például elemezzük az árnyalatokat:
- A számlalistában van egy „Befektetési bank”, amellyel nem tud dolgozni az API használatával
- Kérjük, vegye figyelembe, hogy a mezők camelCase-ben jelennek meg, míg a dokumentációban ezek a mezők under_score-ban vannak feltüntetve.
- Ez mindenhol így lesz, tehát nem lehet csak úgy kimásolni egy mezőt a dokumentációból.
Hasznos:
- Ezt a kódot a projekt ágban találja
https://github.com/pskucherov/tcsstat/tree/step1 https://github.com/pskucherov/tcsstat/compare/step1
Adatok rajzolása a Tinkoff Invest API-ból egy böngészőben
Vettem a next.js-t és a socket.io-t. Ez nem erős ajánlás, válasszon saját belátása szerint.
npx create-next-app@latest npm i socket.io socket.io-client
Azonnal folytatjuk a barátság következő+socket+investapi lépést, és minden részletért lásd ennek a lépésnek a Hasznos szakaszát. Leírom a részleteket:
- A nodejs (szerver) oldalon található egy pages/api/investapi.js fájl. Itt hozzuk létre a socket.io szervert, és csatlakozunk az investapihoz.
- A böngésző (kliens) oldalon egy socketen keresztül csatlakozunk a szerverhez és számlaadatokat kérünk a brókertől.
- Az adatokat a brókertől kapjuk a szerveren, majd elküldjük a kliensnek. Amikor a kliensbe érkezik, megjelennek a böngészőben.
Eredmény: a böngésző konzoljában láthatunk információkat a fiókokról. Vagyis az utolsó lépésben a kiszolgálókonzolon (nodejs) láttunk információkat a fiókokról, az aktuális lépésben ezeket az információkat továbbítottuk a kliensnek (böngészőnek).
Most tegyük úgy, hogy a böngészőből kiválaszthat egy fiókot, és ha nincs token, akkor hibaüzenetet küld a konzolnak. A munka egyszerű és semmi újdonság, ezért csak linkeket adok a commitokhoz
- https://github.com/pskucherov/tcsstat/commit/7e1ac57061e5e971588479015b06d8814d6609a9
- https://github.com/pskucherov/tcsstat/commit/b28ac973a57494f5232589b4cb6b9fb13b8af759
Hasznos:
- Itt részletesen le van írva, hogyan lehet barátokat szerezni és a socketet .
- Barátsági kód next+socket+investapi:
https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 Akinek a fenti nehézségekbe ütközik, akkor maradjunk ennél a szakasznál és foglalkozzunk a kóddal. Ha kérdése van – kérdezzen. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2
Ügynöki jelentések és tranzakciók fogadása
Három módszer áll rendelkezésre a közvetítői jelentések és tranzakciók fogadására
Már a kezdetektől fontos tudni:
- A közvetítői jelentés T-3 módban készül, azaz. az ügyletek tényleges végrehajtásuk után jelennek meg ott.
- Ennek megfelelően, ha ezt a jelentést az utolsó két napra kéri, három napon belül elkészül.
- Az utolsó napok tranzakcióinak lekéréséhez a tranzakciók fogadásának módszerét használjuk, de ne feledjük, hogy azok azonosítója és tartalma a közvetítői jelentés elkészítése után változhat.
GetBrokerReport
A közvetítői jelentés megszerzéséhez meg kell adnia a számlaazonosítót, a jelentés kezdő és befejező dátumát, de legfeljebb 31 nap. Jelentés generálására vonatkozó kérést küldünk az API-nak a gener _broker_report_request részben , válaszul kapunk egy taskId-t. Ezt követően, ezzel a taskId-vel, adatokat kapunk a get _broker_report_response-ból.
- A TaskID-t örökre el kell mentenie pontosan ezekre a dátumokra.
- Mivel ha elveszíti, akkor a kért dátumokra a jelentés először a generálási kérésre válaszul érkezik,
- És akkor egyáltalán nem jön.
A dátum lekérésének módja, figyelembe véve az aktuális dátumból való kivonást
const getDateSubDay = (subDay = 5, start = true) => { const date = new Date(); date.setUTCDate(date.getUTCDate() – alnap); if (start) { date.setUTCHours(0, 0, 0, 0); } else { date.setUTCHours(23, 59, 59, 999); } visszaküldési dátum; };
Jelentés generálási kérés
const brokerReport = várakozás (sdk.operations.getBrokerReport)({ generBrokerReportRequest: { accountId, from, to, }, });
Eredmény:
- A parancs első végrehajtásának eredményeként megkapjuk a taskId-t.
- A jelentés a bróker oldalán elkezdődik. Amikor készen áll, nem ismert, várunk, és időnként lehívjuk a taskId-t a jelentésre várva.
- Miért? Mert ha a jelentés nem kész, akkor hibát dob. Ha a jelentés nem áll készen a bróker oldalán, akkor ez egy hiba a kódban. Kérjük, dolgozza fel: 30058|INVALID_ARGUMENT|a feladat még nem fejeződött be, próbálja újra később
A jelentés várásának és fogadásának kódja valahogy így néz ki.
const timer = async time => { return new Promise(resolve => setTimeout(feloldás, idő)); } const getBrokerResponseByTaskId = async (taskId, page = 0) => { try { return await (sdk.operations.getBrokerReport)({ getBrokerReportRequest: { taskId, page, }, }); } catch (e) { console.log(‘vár’, e); várakozás időzítő (10000); return await getBrokerResponseByTaskId(taskId, page); } };
Aztán ugyanaz a varázslat történik. Leállítjuk a szkriptünket, újraindítjuk, nincs feladatazonosítónk. A taskId kéréssel végrehajtjuk a kódot, de már nem a taskId-t kapjuk, hanem azonnal a jelentést. Varázslat! És minden rendben lenne, ha mindig így lenne. De egy hónap múlva már egyáltalán nem lesz adat. Hasznos :
https://github.com/pskucherov/tcsstat/tree/step3.1 https://github.com/pskucherov/tcsstat/compare/step3.1
- Ha valaki találkozik ezzel, üdvözöljük a témában . Miután megjavítják ezt a varázslatot, elveszti az erejét, és valahogy más lesz. De jelen pillanatban (2023.03.21) ez pont így működik.
GetDividendsForeignSsuer
Valaki azt gondolhatja, hogy a metódus hasonló az előzőhöz, és egyetlen metódust is használhat, amelyben csak a műveletek nevét módosítja. De nem sejtették! Az ottani elnevezés nagyon eltérő mind a metódusokban, mind a visszaadott információkban. Az oldalszám pedig 0-tól kezdődik, majd 1-től. Hogy ne keveredjünk össze, egyszerűbb két különböző módszert írni. Ami furcsa, mert a munka logikája ugyanaz. Sokáig köpködtem, amikor megpróbáltam egy módszert készíteni, és kevesebb volt a kód. Itt nem lesz példa.
GetOperationsByCursor
A kedvencem a három közül. Bár nem a legpontosabb, de a legmegfelelőbb. A fiók létrehozásának kezdetétől a maximális lehetséges időpontig (számlazárás vagy jelenlegi) kérünk. Megkapjuk a választ, vedd a kurzort, és addig kérünk újra, amíg van adat. A kód pedig tömörebb, mint a fenti példákban.
const timer = async time => { return new Promise(resolve => setTimeout(feloldás, idő)); } const getOperationsByCursor = async (sdk, accountId, from, to, cursor = ”) => { try { const reqData = { accountId, from, to, limit: 1000, state: sdk.OperationState.OPERATION_STATE_EXECUTED, withoutCommissions: false Kereskedés nélkül: false, withoutOvernights: false, kurzor, }; return await sdk.operations.getOperationsByCursor(reqData); } catch (e) { await timer(60000); return await getOperationsByCursor(sdk, accountId, from, to, cursor = ”); } };
A futtatandó vázlat itt található: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 Most már készen állunk fogadási műveletek hozzáadására alkalmazásunk. Ha helyesen csinálja, akkor közvetítői jelentéseket kell kapnia a számla teljes létezéséről. És a hiányzó adatokért ugyanazokat a T-3-akat töltse be újra a műveletekből. De ez külön cikkre bontható. A főbb árnyalatok, amelyekkel találkozni fog, a műveletek és a közvetítői jelentés ragasztása.
- Ha ma kaptál egy közvetítői jelentést és a szükséges időpontokra vonatkozó tranzakciókat, tedd be az adatbázisba, akkor nincs probléma.
- Problémák lesznek holnap, amikor megkapja a következő adatrészt a jelentésből és a műveletekből, és úgy dönt, hogy szinkronizálja azokat a meglévő adatbázissal.
- Sok árnyalat az össze nem illő vagy feldolgozás utáni azonosító módosításával kapcsolatban
- Aztán az OTC piacon az azonosítók egyáltalán nem egyeznek.
- Valamint a műszerek szinkronizálásának árnyalatai, amelyek az API sajátosságai miatt ismét nem esnek egybe. De ez egy másik történet.
Adjuk hozzá alkalmazásunkhoz a műveletekkel kapcsolatos információk megszerzését. A fő kérdés az lesz, hogy hol fogják feldolgozni és tárolni az adatokat.
- Ha saját magának csinálja, ugyanazt az adatot fogja fogyasztani különböző eszközökről. Ezután adatokat kell feldolgoznia és tárolnia a szerveren.
- Ha sok különböző adatot fogyaszt sok különböző felhasználó, akkor el kell döntenie, mi a fontosabb: a felhasználók sebessége vagy a vasmegtakarítás az Ön oldalán. Aki megengedhet magának végtelen mennyiségű hardvert, az mindent megszámol a szerverén, és szupergyorsítja a felhasználókat, megtakarítva a felhasználói erőforrásokat, például az akkumulátort és a forgalmat, ami a telefonoknál nagyon fontos.
A böngészőben való számolás viszont elvileg nem a legoptimálisabb megoldás. Ezért ami nem drága, azt a szerverünkön tartjuk. A többit a megrendelőre bízzuk. Nagyon szeretném kiszámolni a jutalékot a szerveren. De itt jön az „interaktivitás” nevű árnyalat. Tegyük fel, hogy több ezer művelete van, és ezek fogadása öt percet vesz igénybe. Mi lesz a felhasználónak ebben az időben? Fonógép? Előrehalad? Infa, hogy mennyit töltöttek fel? Ideális az „aktív várakozás” használata, amikor a folyamatban lévő felhasználó már láthat valamit. Íme az Eredmény:
- Oldal betöltése
- Minden számlát kérünk
- Ezt követően minden számlára lekérjük a végrehajtott tranzakciók jutalékos tranzakcióit. Az adatok beérkezésekor azok a böngészőben jelennek meg.
Annak érdekében, hogy ne szűrjük minden alkalommal az események adatait, minden fiókhoz saját eseményt hozunk létre. Mint ez:
socket.emit(‘sdk:getOperationsCommissionResult_’ + accountId, { items: data?.items, inProgress: Boolean(nextCursor), });
Az indítandó tervezet itt található: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 Továbblépés. Nagyon jó, hogy elolvastad ezt a sort!
Az érdeklődésre számot tartó információk kiszámítása és kiadása
Attól függ, kinek milyen információra van szüksége. Ezért azonnal elmondom a főbb árnyalatokat, amelyekkel találkozni fog.
Az árakkal való munka
Mindenki, aki pénzügyekkel dolgozik, tudja, hogy a pénzforgalmat csak egész számokkal szabad végrehajtani. A tizedesvessző utáni értékek pontatlansága és a nagyszámú művelettel járó kumulatív hiba miatt. Ezért minden ár a következő MoneyValue formátumban jelenik meg
terület | típus | Leírás |
---|---|---|
valuta | húr | Karakterlánc ISO pénznemkód |
egységek | int64 | Az összeg egész része, lehet negatív szám |
nano | int32 | Az összeg töredéke, lehet negatív szám |
Ezeket külön-külön feldolgozzuk, majd árértékre hozzuk:
quotation.units + quotation.nano / 1e9
A határidős szerződések költsége
A határidős ügyletek ára pontokban van megadva, ha van határidős deviza, akkor ismerni kell az árfolyamot. És persze az ár pontokban és az árlépés. Amikor kiszámítja a tranzakciókból származó nyereséget, ez lőhet, mert. ha a teljes összeget úgy számítja ki, hogy az árat megszorozza a mennyiséggel. Itt óvatosnak kell lenni. Egyelőre meglátjuk, hogy alakul. Ez a határidős devizaügyletekre vonatkozik, máshol minden rendben van ezzel.
OTC piac
Ennek a piacnak nagyon sok sajátossága van, ezért vizsgáljuk meg a műveleteket külön.A műveletek szinkronizálásának megkezdésekor kiderül, hogy a figi / ticker-t ugyanabba a formába kell hozni, hogy helyesen illeszkedjen a hangszerhez. Amikor elkezdi szinkronizálni ezt a brókerjelentéssel, akkor kiderül, hogy ugyanannak a tranzakciónak a tradeID-je a tranzakciók elején betűket tartalmaz, és ezek nincsenek a közvetítői jelentésben. Ezért nem lehet őket összehasonlítani … ahem-ahem … összehasonlítással! Egyeztetettem a kereskedési időt, a tickert és a párosítást, hogy az egyik tradeId egy másikban szerepel. Igaz, nem tudom. Aki ezzel találkozik, és akit érdekel, térjen rá a kérdésre , vagy kezdjen újat.
Matematikai műveletek szerszámokon
Megtekintés nélkül lehetetlen matematikai műveleteket végrehajtani a teljes listával. Annak érdekében, hogy ne adjunk meleget a lágyhoz, mindig ellenőrizzük a pénznemet és csak akkor dolgozzuk fel, ha biztosak vagyunk benne, hogy a pénznem egyezik, és a pontokat átváltjuk a kívánt pénznemre. A bankszámokkal való munka ismeretében kiszámoljuk az egyes számlákra fordított jutalékot. Így: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4
A mikroszolgáltatás készen áll!
https://github.com/pskucherov/tcsstat Házi feladatként ellenőrizheti, hogy a szolgáltatás működik-e lassú kapcsolat mellett, mikor szakadnak meg a kapcsolatok, mikor szakad meg az internet, mikor van hiba vagy lejárt a korlát a bróker részéről.
Következtetések és tervek a jövőre nézve
- Tanult az alapműveletekről és az Invest API használatáról
- Eltöltött idő ~ 10 óra
- Nehézségi szint ~ junior+ / alacsony közép
Ha folytatja a mikroszolgáltatás finomítását, valami ilyesmihez vezethet
https://opexbot.info
Ez az én fejlesztésem, azoknak, akik lusták érteni, futni és számítani magukra. Azt tervezem, hogy a felhasználók kérésére hozzáadom az elemzést. Ha tetszett a cikk, akkor iratkozz fel a távirati csatornámra .
Полезная статья. Не могу представить, сколько усилий автора потребовалось, чтобы все описать. Благодарю.