Tinkoff Investments statistikas pakalpojuma izstrādes iedvesmotāji bija:
- raksts par Habrē “Ko nesaka Tinkoff Investments”
- platformas lietotāju vēlmju analīze
- raksts par komisiju aprēķināšanu .
- Kas tiks apspriests?
- Statistikas pakalpojuma izstrāde soli pa solim:
- Savienojums ar Tinkoff Invest API
- Datu zīmēšana no Tinkoff Invest API pārlūkprogrammā
- Starpniecības atskaišu un darījumu saņemšana
- GetBrokerReport
- Datuma iegūšanas metode, ņemot vērā atņemšanu no pašreizējā datuma
- Pārskatu ģenerēšanas pieprasījums
- Rezultāts:
- GetDividendsForeignIssuer
- GetOperationsByCursor
- Interesējošās informācijas aprēķināšana un izvadīšana
- Darbs ar cenām
- Nākotnes līgumu izmaksas
- OTC tirgus
- Matemātiskās darbības ar instrumentiem
- Mikroserviss ir gatavs!
- Secinājumi un nākotnes plāni
- https://opexbot.info
Kas tiks apspriests?
- Tikai lietišķā daļa par attīstību.
- Reālas zināšanas un pieredze, kas ir ļoti svarīgas darbā ar finanšu instrumentiem.
- Pārskats par problēmām, pie kurām jāstrādā
Tātad, es vēlos aprēķināt tirdzniecības statistiku un izdarīt to ērtā veidā.
Statistikas pakalpojuma izstrāde soli pa solim:
- Savienojums ar Tinkoff Invest API
- Datu zīmēšana no Tinkoff Invest API pārlūkprogrammā
- Starpniecības atskaišu un darījumu saņemšana
- Interesējošās informācijas aprēķināšana un izvadīšana
- Secinājumi un nākotnes plāni
Savienojums ar Tinkoff Invest API
Lai izveidotu savienojumu ar API, varat ņemt jebkuru sdk no dokumentācijas https://github.com/Tinkoff/investAPI#sdk . Vai npm pakotni ` tinkoff-sdk-grpc-js `. Ir svarīgi, lai izstrādātāji pakotni atjauninātu uz jaunāko versiju. Uzstādīt
npm es tinkoff-sdk-grpc-js
Pārbauda
const { createSdk } = prasīt(‘tinkoff-sdk-grpc-js’); // Token, ko var iegūt šādi const TOKEN = ‘YOURAPI’; // Lietojumprogrammas nosaukums, ar kuru jūs varat atrast TCS žurnālos. const appName = ‘tcsstat’; const sdk = izveidotSdk(TOKEN, lietotnes nosaukums); (async () => { console.log(gaidiet sdk.users.getAccounts()); })();
Rezultāts: konsolē tiks parādīts jūsu kontu saraksts. Piemēram, analizēsim nianses:
- Kontu sarakstā ir “Investīciju banka”, ar kuru nevar strādāt, izmantojot API
- Lūdzu, ņemiet vērā, ka lauki ir norādīti camelCase, savukārt dokumentācijā šie lauki ir norādīti kā under_score.
- Tā būs visur, tāpēc jūs nevarat vienkārši paņemt un nokopēt lauku no dokumentācijas.
Noderīgi:
- Šo kodu varat atrast projekta filiālē
https://github.com/pskucherov/tcsstat/tree/step1 https://github.com/pskucherov/tcsstat/compare/step1
Datu zīmēšana no Tinkoff Invest API pārlūkprogrammā
Paņēmu next.js un socket.io. Tas nav stingrs ieteikums, izvēlieties pēc saviem ieskatiem.
npx create-next-app@latest npm i socket.io socket.io-client
Mēs nekavējoties pārejam pie draudzības soļa nākamais+socket+investapi un visu informāciju skatiet šīs darbības sadaļā Noderīga . Es aprakstīšu detaļas:
- Nodejs (servera) pusē ir fails pages/api/investapi.js. Šeit mēs izveidojam serveri socket.io un izveidojam savienojumu ar investapi.
- Pārlūka (klienta) pusē mēs izveidojam savienojumu ar serveri caur ligzdu un pieprasām konta datus no brokera.
- Mēs saņemam datus no brokera serverī, pēc tam nosūtām tos klientam. Kad tie tiek saņemti klientā, tie tiek parādīti pārlūkprogrammā.
Rezultāts: pārlūkprogrammas konsolē mēs varam redzēt informāciju par kontiem. Tas ir, pēdējā solī mēs redzējām informāciju par kontiem servera konsolē (nodejs), pašreizējā solī mēs pārsūtījām šo informāciju klientam (pārlūkam).
Tagad padarīsim to tā, lai pārlūkprogrammā varētu atlasīt kontu, un, ja marķiera nav, tad uz konsoli tiek nosūtīta kļūda. Darbs ir vienkāršs un nekas jauns, tāpēc dodu tikai saites uz saistībām
- https://github.com/pskucherov/tcsstat/commit/7e1ac57061e5e971588479015b06d8814d6609a9
- https://github.com/pskucherov/tcsstat/commit/b28ac973a57494f5232589b4cb6b9fb13b8af759
Noderīgi:
- Kā iegūt draugus nākamo un socket, ir detalizēti aprakstīts šeit .
- Draudzības kods next+socket+investapi:
https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 Kam iepriekšminētais ir grūti, tad paliekam pie šīs stadijas un nodarbojamies ar kodu. Ja ir jautājumi – jautājiet. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2
Starpniecības atskaišu un darījumu saņemšana
Ir trīs veidi , kā saņemt starpniecības ziņojumus un darījumus
No paša sākuma ir svarīgi zināt:
- Starpniecības atskaite tiek ģenerēta T-3 režīmā, t.i. darījumi tiek parādīti tur pēc to faktiskās izpildes.
- Attiecīgi, ja pieprasīsit šo pārskatu par pēdējām divām dienām, tas būs gatavs trīs dienu laikā.
- Lai veiktu darījumus par pēdējām dienām, izmantojam operāciju saņemšanas metodi, taču atcerieties, ka to id un saturs var mainīties pēc starpniecības atskaites noformēšanas.
GetBrokerReport
Lai saņemtu starpniecības pārskatu, jums ir jāņem konta ID, sākuma datums un pārskata beigu datums, bet ne vairāk kā 31 diena. Mēs nosūtām pieprasījumu ģenerēt atskaiti API ģenerēt _broker_report_request , kā atbildi saņemt uzdevuma ID. Pēc tam, izmantojot šo taskId, mēs iegūstam datus no get _broker_report_response.
- TaskID ir jāsaglabā uz visiem laikiem tieši šiem datumiem.
- Tā kā, ja jūs to pazaudējat, pieprasītajos datumos pārskats vispirms tiks sagatavots kā atbilde uz ģenerēšanas pieprasījumu,
- Un tad tas vispār nesanāks.
Datuma iegūšanas metode, ņemot vērā atņemšanu no pašreizējā datuma
const getDateSubDay = (subDay = 5, start = true) => { const date = new Date (); datums.setUTCDate(datums.getUTCDate() – apakšdiena); if (sākt) { date.setUTCHours(0, 0, 0, 0); } else { date.setUTCHours(23, 59, 59, 999); } atgriešanas datums; };
Pārskatu ģenerēšanas pieprasījums
const brokerReport = gaidīt (sdk.operations.getBrokerReport)({ generBrokerReportRequest: { accountId, from, to, }, });
Rezultāts:
- Pirmās komandas izpildes rezultātā mēs iegūstam uzdevumu ID.
- Pārskatu sāk ģenerēt brokera pusē. Kad tas ir gatavs, nav zināms, mēs gaidām un periodiski izvelkam uzdevuma ID, gaidot ziņojumu.
- Kāpēc? Jo, ja atskaite nav gatava, tā rada kļūdu. Ja brokera pusē ziņojums nav gatavs, tā ir kļūda jūsu kodā. Lūdzu, apstrādājiet: 30058|INVALID_ARGUMENT|uzdevums vēl nav pabeigts, lūdzu, vēlāk mēģiniet vēlreiz
Atskaites gaidīšanas un saņemšanas kods izskatās apmēram šādi.
const taimeris = asinhronais laiks => { return new Promise(atrisināt => setTimeout(atrisināt, laiks)); } const getBrokerResponseByTaskId = async (taskId, page = 0) => { try { return await (sdk.operations.getBrokerReport)({ getBrokerReportRequest: { taskId, page, }, }); } catch (e) { console.log(‘gaidiet’, e); gaidiet taimeri (10000); atgriezties gaidīt getBrokerResponseByTaskId(uzdevuma ID, lapa); } };
Tad notiek tā pati maģija. Mēs pārtraucam savu skriptu, sākam to no jauna, mums nav uzdevuma ID. Mēs izpildām kodu ar pieprasījumu TaskId, bet mēs vairs nesaņemam taskId, bet gan uzreiz atskaiti. Maģija! Un viss būtu labi, ja tā būtu vienmēr. Bet pēc mēneša datu nebūs vispār. Noderīgi :
- Nedaudz teorijas ir izklāstīta šeit un šeit .
- Saliekot kodu kopā, melnraksts izskatīsies apmēram šādi.
https://github.com/pskucherov/tcsstat/tree/step3.1 https://github.com/pskucherov/tcsstat/compare/step3.1
- Ja kāds ar to saskaras, laipni lūdzam šajā jautājumā . Pēc tam, kad viņi labos šo burvību, tā zaudēs savu spēku un būs kaut kā savādāka. Bet uz doto brīdi (21.03.2023) tas darbojas tieši tā.
GetDividendsForeignIssuer
Kāds varētu domāt, ka metode ir līdzīga iepriekšējai un var izmantot vienu metodi, kurā maināt tikai darbību nosaukumus. Bet viņi neuzminēja! Nosaukumi tur ļoti atšķiras gan metodēs, gan atgrieztajā informācijā. Un lappušu skaits sākas no 0, pēc tam no 1. Lai šajā visā neapjuktu, ir vieglāk uzrakstīt divas dažādas metodes. Kas ir dīvaini, jo darba loģika ir tāda pati. Es ilgu laiku spļāvu, kad mēģināju izveidot vienu metodi, un koda bija mazāk. Šeit nebūs piemēru.
GetOperationsByCursor
Mans mīļākais no trim. Lai arī ne visprecīzākais, bet adekvātākais. Mēs veicam pieprasījumu no konta izveides sākuma līdz maksimāli iespējamajam datumam (konta slēgšanai vai pašreizējam). Saņemam atbildi, paņemam kursoru un pieprasām atkārtoti, kamēr ir dati. Un kods ir kodolīgāks nekā iepriekš minētajos piemēros.
const taimeris = asinhronais laiks => { return new Promise(atrisināt => setTimeout(atrisināt, laiks)); } const getOperationsByCursor = async (sdk, accountId, from, to, cursor = ”) => { try { const reqData = { accountId, from, to, limit: 1000, state: sdk.OperationState.OPERATION_STATE_EXECUTED, withoutCommissions: false withoutTrades: false, bezOvernights: false, kursors, }; atgriešanās gaida sdk.operations.getOperationsByCursor(reqData); } noķert (e) { gaidīt taimeri (60000); atgriezties gaidīt getOperationsByCursor(sdk, konta ID, no, uz, kursors = ”); } };
Izpildāmais melnraksts ir šeit: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 Tagad mēs esam gatavi pievienot saņemšanas darbības mūsu pieteikums. Ja tas tiek izdarīts pareizi, jums ir jāsaņem starpniecības pārskati par visu konta pastāvēšanu. Un, lai iegūtu trūkstošos datus, tie paši T-3, pārlādējiet no operācijām. Bet to var sadalīt atsevišķā rakstā. No galvenajām niansēm, ar kurām jūs saskarsities, ir operāciju un starpniecības atskaites līmēšana.
- Ja šodien saņēmāt starpniecības atskaiti un darījumus par nepieciešamajiem datumiem, ielieciet to visu datu bāzē, tad problēmu nav.
- Jums būs problēmas rīt, kad saņemsiet nākamo datu daļu no pārskata un operācijām un nolemsiet tos sinhronizēt ar esošo datu bāzi.
- Daudz nianšu par neatbilstību vai id maiņu pēc apstrādes
- Tad ārpusbiržas tirgum ID vispār nesakrīt.
- Kā arī instrumentu sinhronizācijas nianses, kas atkal nesakrīt, API īpatnību dēļ. Bet tas ir cits stāsts.
Papildināsim mūsu lietojumprogrammai informācijas iegūšanu par darbībām. Galvenais jautājums būs par to, kur dati tiks apstrādāti un uzglabāti.
- Ja darīsit to sev, jūs patērēsit tos pašus datus no dažādām ierīcēm. Pēc tam jums ir jāapstrādā un jāuzglabā dati serverī.
- Ja jums ir daudz dažādu datu, ko patērē daudzi dažādi lietotāji, tad jums ir jāizlemj, kas ir svarīgāks: lietotāju ātrums vai dzelzs ietaupījums jūsu pusē. Ikviens, kurš var atļauties bezgalīgi daudz aparatūras, uzskaita visu savā serverī un padara to lietotājiem īpaši ātru, ietaupot lietotāja resursus, piemēram, akumulatoru un trafiku, kas tālruņos ir ļoti svarīgi.
Savukārt skaitīšana pārlūkprogrammā principā nav optimālākais risinājums. Tāpēc, kas nav dārgs, to mēs uzskatām savā serverī. Pārējo atstājam klienta ziņā. Ļoti gribu ņemt un aprēķināt komisijas maksu serverī. Bet šeit parādās nianse, ko sauc par “interaktivitāti”. Pieņemsim, ka jums ir tūkstošiem operāciju, un to saņemšana aizņem piecas minūtes. Kas lietotājam būs šajā laikā? Spineris? Progress? Infa par to, cik daudz tika augšupielādēts? Ideāli ir izmantot “aktīvo gaidīšanu”, kad lietotājs šajā procesā jau kaut ko redz. Šeit ir rezultāts:
- Lapas ielāde
- Tiek pieprasīti visi rēķini
- Pēc tam visiem kontiem tiek pieprasīti visi darījumi ar komisijām par veiktajiem darījumiem. Kad dati tiek saņemti, tie tiek atveidoti pārlūkprogrammā.
Lai katru reizi nefiltrētu notikumu datus, mēs katram kontam izvelkam savu notikumu. Kā šis:
socket.emit(‘sdk:getOperationsCommissionResult_’ + accountId, { items: data?.items, inProgress: Boolean(nextCursor), });
Uzmetums palaišanai ir pieejams šeit: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 Turpinām. Lieliski, ka esi izlasījis šo rindiņu!
Interesējošās informācijas aprēķināšana un izvadīšana
Atkarīgs no tā, kam kāda informācija ir vajadzīga. Tāpēc es nekavējoties pastāstīšu galvenās nianses, ar kurām jūs saskarsities.
Darbs ar cenām
Ikviens, kurš strādā ar finansēm, zina, ka naudas darījumus drīkst veikt tikai ar veseliem skaitļiem. Vērtību neprecizitātes dēļ pēc komata un kumulatīvās kļūdas ar lielu darbību skaitu. Tāpēc visas cenas ir norādītas šādā MoneyValue formātā
lauks | veids | Apraksts |
---|---|---|
valūta | virkne | Virknes ISO valūtas kods |
vienības | int64 | Summas vesela daļa var būt negatīvs skaitlis |
nano | int32 | Summas daļēja daļa var būt negatīvs skaitlis |
Mēs tos apstrādājam atsevišķi, pēc tam sasniedzam cenas vērtību:
citāts.vienības + citāts.nano / 1e9
Nākotnes līgumu izmaksas
Nākotnes līgumu cena tiek uzrādīta punktos, kad jums ir valūtas nākotne, jums jāzina kurss. Un protams cena punktos un cenas solis. Aprēķinot peļņu no darījumiem, tas var šaut, jo. ja aprēķina kopējo summu, reizinot cenu ar daudzumu. Šeit jums jābūt uzmanīgiem. Pagaidām redzēsim, kā būs. Tas attiecas uz valūtas fjūčeriem, citviet ar šo viss ir ok.
OTC tirgus
Šim tirgum ir daudz īpatnību, tāpēc izpētīsim operācijas uz tā atsevišķi.Kad sāksiet sinhronizēt operācijas, izrādīsies, ka jums ir jāieved figi / ticker vienā formā, lai pareizi saskaņotu instrumentu. Kad sāksiet to sinhronizēt ar brokeru atskaiti, izrādīsies, ka tā paša darījuma tradeID darījumos ir burti sākumā un starpniecības atskaitē tie nav. Tāpēc tos nevar salīdzināt … ahem-ahem … ar salīdzinājumu! Es saskaņoju tirdzniecības laiku, atzīmi un saskaņošanu, ka viens tirdzniecības ID ir ietverts citā. Pareizi, es nezinu. Kurš ar to sastopas un kam tas rūp, nāc pie jautājuma vai sāc jaunu.
Matemātiskās darbības ar instrumentiem
Bez apskates nav iespējams veikt matemātiskas darbības ar visu sarakstu. Lai nepievienotu siltu mīkstajam, mēs vienmēr pārbaudām valūtu un apstrādājam tikai tad, ja esam pārliecināti, ka valūta sakrīt, un punkti tiek konvertēti vēlamajā valūtā. Apbruņojušies ar zināšanām par darbu ar bankas numuriem, mēs aprēķināsim par katru kontu iztērēto komisiju. Piemēram: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4
Mikroserviss ir gatavs!
https://github.com/pskucherov/tcsstat Kā mājasdarbu varat pārbaudīt, vai pakalpojums darbojas ar lēnu savienojumu, kad tiek pārtraukti savienojumi, kad ir atvienots internets, kad kļūdas vai beigušies brokera limiti.
Secinājumi un nākotnes plāni
- Uzzināja par pamatdarbībām un darbu ar Invest API
- Pavadītais laiks ~ 10 stundas
- Grūtības pakāpe ~ junior+ / zema vidējā
Ja turpināsit pilnveidot mikropakalpojumu, jūs varētu nonākt pie kaut kas līdzīgs šim
https://opexbot.info
Tā ir mana attīstība, tiem, kam ir slinkums saprast, skriet un rēķināties ar saviem spēkiem. Es plānoju tur pievienot analīzi pēc lietotāju pieprasījuma. Ja jums patika raksts, abonējiet manu telegrammas kanālu .
Полезная статья. Не могу представить, сколько усилий автора потребовалось, чтобы все описать. Благодарю.