Sviluppemu un microserviziu utilizendu l’API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.

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

L’ispiratori daretu à u sviluppu di u serviziu di statistiche per Tinkoff Investments eranu:

Chì serà discutitu ?

  • Solu a parte applicata nantu à u sviluppu.
  • Cunniscenza vera è sperienza, chì sò assai impurtanti in u travagliu cù strumenti finanziarii.
  • Panoramica di i prublemi per travaglià

Allora, vogliu calculà e statistiche di u cummerciu è fà in una manera còmuda. 

Sviluppà un serviziu di statistiche passu à passu: 

  1. Cunnessione à l’API Tinkoff Invest
  2. Disegnu dati da Tinkoff Invest API in un navigatore
  3. Riceve rapporti di brokerage è transazzione
  4. Càlculu è output di l’infurmazioni d’interessu
  5. Cunclusioni è piani per u futuru

Cunnessione à l’API Tinkoff Invest

Per cunnette à l’API, pudete piglià qualsiasi sdk da a documentazione https://github.com/Tinkoff/investAPI#sdk . O pacchettu npm ` tinkoff-sdk-grpc-js `. Hè impurtante chì u pacchettu hè aghjurnatu à l’ultima versione da i sviluppatori. Installa

npm è tinkoff-sdk-grpc-js

Cuntrolla

const {createSdk} = require(‘tinkoff-sdk-grpc-js’);   // Token chì pò esse acquistatu cusì  cunst TOKEN = ‘YOURAPI’;   // U nome di l’applicazione per quale pudete truvà in i logs TCS. const appName = ‘tcsstat’;   const sdk = createSdk (TOKEN, appName); (async () => {     console.log (attende sdk.users.getAccounts ()); })();

Risultatu: una lista di i vostri cunti serà visualizata in a cunsola. Per esempiu, analizemu e sfumature:Sviluppemu un microserviziu utilizendu l'API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.

  • In a lista di cunti ci hè un “bancu d’investimentu”, cù quale ùn pudete micca travaglià cù l’API
  • Per piacè nutate chì i campi venenu in camelCase, mentri in a documentazione sti campi sò presentati in under_score. 
  • Serà cusì in ogni locu, perchè ùn pudete micca solu piglià è copià un campu da a documentazione.

Utile:

  • Pudete truvà stu codice in u ramu prughjettu

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

Disegnu dati da Tinkoff Invest API in un navigatore

Aghju pigliatu next.js è socket.io. Questa ùn hè micca una raccomandazione forte, sceglite à a vostra discrezione. 

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

Procedemu immediatamente à u passu di l’amicizia next+socket+investapi, è vede a sezione Utile di stu passu per tutti i dettagli.  Descriveraghju i dettagli: 

  • Da u latu nodejs (servitore), ci hè un schedariu pages/api/investapi.js. Hè quì chì creamu u servitore socket.io è cunnette à investapi.
  • Da u latu di u navigatore (cliente), cunnettamu à u servitore per via di un socket è dumandemu i dati di u contu da u broker. 
  • Ricevemu dati da u broker nantu à u servitore, dopu mandà à u cliente. Quandu sò ricevuti nantu à u cliente, sò visualizati in u navigatore. 

Risultatu:  in a cunsola di u navigatore pudemu vede infurmazioni nantu à i cunti. Questu hè, in l’ultimu passu, avemu vistu infurmazione nantu à i cunti in a cunsola di u servitore (nodejs), in u passu attuale, avemu trasfirutu sta informazione à u cliente (navigatore).

Sviluppemu un microserviziu utilizendu l'API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.

Avà facemu cusì chì pudete selezziunà un contu da u navigatore, è se ùn ci hè micca token, allora un errore hè mandatu à a cunsola. U travagliu hè simplice è nunda di novu, per quessa, dà solu ligami à cummette

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

Utile:

  • Cumu fà amici dopu è socket hè descrittu in detail quì
  • Codice d’amicizia next+socket+investapi:

https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 Per quale u sopra hè difficiule, allora fermamu in questu stadiu è trattà cù u codice. Sì avete dumande – dumandate. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2

Riceve rapporti di brokerage è transazzione

Ci sò trè metudi per riceve rapporti di brokerage è transazzione

  1. Get Broker Report
  2. GetDividendsForeign Issuer
  3. GetOperationsByCursor

Da u principiu hè impurtante di sapè: 

  • U rapportu di brokerage hè generatu in u modu T-3, i.e. i mistieri sò affissati quì dopu a so esecuzione attuale. 
  • Dunque, se dumandate stu rapportu per l’ultimi dui ghjorni, serà pronta in trè ghjorni. 
  • Per fà affari per l’ultimi ghjorni, usemu u metudu per riceve operazioni, ma ricordate chì u so id è u cuntenutu pò cambià dopu à a furmazione di u rapportu di brokerage.

Get Broker Report

Per uttene un rapportu di correlazione, avete bisognu di piglià l’identificatore di u contu, a data di iniziu è a data di fine di u rapportu, ma micca più di 31 ghjorni. Mandemu una dumanda per generà un rapportu à l’API in generate _broker_report_request , uttene un taskId in risposta. Dopu à quessa, utilizendu stu taskId, uttene dati da get _broker_report_response.

Allora a documentazione dice, in realtà ci sò sfumature. Fighjate e vostre mani:
  • Avete bisognu di salvà u TaskID per sempre esattamente per queste date. 
  • Siccomu si perde, allora per e date richieste u rapportu vene prima in risposta à a dumanda di generazione, 
  • È tandu ùn vene micca in tuttu.
Cuminciamu à scrive codice

Metudu per ottene a data, tenendu in contu a sottrazione da a data attuale

const getDateSubDay = (subDay = 5, start = true) => {     const date = new Date ();     date.setUTCDate (date.getUTCDate () – subDay);       if (iniziu) {         date.setUTCHours (0, 0, 0, 0);     } altru {         date.setUTCHours (23, 59, 59, 999);     }       data di ritornu; };

Richiesta di generazione di rapportu 

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

Risultatu:

  • In u risultatu di a prima esecuzione di u cumandamentu, avemu u taskId. 
  • U rapportu cumencia à esse generatu da u broker. Quandu hè prontu hè scunnisciutu, aspittemu è tirà periodicamente u taskId in anticipazione di u rapportu.
  • Perchè? Perchè se u rapportu ùn hè micca prontu, tira un errore. Se u rapportu ùn hè micca prontu da u broker, allora questu hè un errore in u vostru codice. Per piacè prucessu: 30058|INVALID_ARGUMENT| compitu ùn hè micca finitu ancu, per piacè pruvà più tardi

U codice per aspittà è riceve un rapportu pare cusì cusì.

const timer = async time => {     return new Promise (resolve => setTimeout (resolve, time)); }   const getBrokerResponseByTaskId = async (taskId, pagina = 0) => {     try {         return await (sdk.operations.getBrokerReport) ({             getBrokerReportRequest: {                 taskId,                 pagina,             },         });     } catch (e) {         console.log(‘wait’, e);         aspittà timer (10000);         ritornu aspittà getBrokerResponseByTaskId (taskId, pagina);     } };

Allora a stessa magia succede. Firmemu u nostru script, ricuminciamu, ùn avemu micca un taskId. Eseguimu u codice cù a dumanda taskId, ma ùn avemu più u taskId, ma immediatamente u rapportu. Magia ! È tuttu saria bè s’ellu era sempre cusì. Ma in un mesi ùn ci sarà micca dati à tutti. Utile :

  • Un pocu di teoria hè delineata quì è quì .
  • Mettendu u codice inseme, u draft parerà qualcosa cusì.

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

  • Sè qualchissia vene in questu, allora benvenutu à u prublema . Dopu avè riparatu sta magia, perderà u so putere è serà in qualchì manera sfarente. Ma à u mumentu attuale (21/03/2023) funziona cusì cusì.

GetDividendsForeign Issuer

Qualchissia puderia pensà chì u metudu hè simili à u precedente è pudete aduprà un solu metudu in quale solu cambià u nome di l’operazioni. Ma ùn anu micca indovinatu !  A denominazione hè assai sfarente sia in i metudi è in l’infurmazioni restituiti. È u conte di pagina principia da 0, dopu da 1. Per ùn avè micca cunfunditu in tuttu questu, hè più faciule per scrive dui metudi diffirenti. Chì hè stranu, perchè a logica di u travagliu hè a stessa. Aghju sputatu per un bellu pezzu quandu aghju pruvatu à fà un metudu è ci era menu codice. Ùn ci sarà micca esempi quì.

GetOperationsByCursor

U mo preferitu di i trè. Ancu s’ellu ùn hè micca u più precisu, ma u più adattatu. Facemu una dumanda da u principiu di creazione di un contu à a data massima pussibule (chjude un contu o l’attuale). Avemu a risposta, pigliate u cursore è ri-dumandu finu à chì ci sò dati.  È u codice hè più cuncisu chè in l’esempii sopra.

const timer = 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,             senzaTrades: false,             senza Overnights: false,             cursore,         };           return await sdk.operations.getOperationsByCursor (reqData);     } catch (e) {         wait timer (60000);         return await getOperationsByCursor (sdk, accountId, from, to, cursor = ”);     } };

U prugettu per eseguisce hè quì: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 Avà simu pronti per aghjunghje operazioni di ricezione à a nostra applicazione. Sè fattu bè, allora avete bisognu di ottene rapporti di brokerage per tutta l’esistenza di u contu. È per i dati mancanti, quelli stessi T-3, ricaricà da l’operazioni. Ma questu pò esse separatu in un articulu separatu. Di i sfumaturi principali chì vi scontru hè di colla l’operazioni è un rapportu di brokerage.

  •  Sè oghje avete ricevutu un rapportu di brokerage è transazzione per e date richieste, mette tuttu in a basa di dati, allora ùn ci sò micca prublemi. 
  • Averete prublemi dumani quandu avete ricevutu a prossima parte di dati da u rapportu è l’operazioni è decide di sincronizà cù a basa di dati esistenti. 
  • Un saccu di sfumature nantu à l’identificazione incompatibile o cambiante dopu a trasfurmazioni
  • Allora per u mercatu OTC, l’id ùn currispondenu à tuttu.
  •  In quantu à i sfumaturi di strumenti di sincronizazione, chì di novu ùn coincidenu micca, per via di e peculiarità di l’API. Ma questu hè un’altra storia.

Aghjunghjemu l’infurmazioni nantu à l’operazione à a nostra applicazione. A quistione principale serà induve i dati seranu trattati è almacenati.

  •  Sè vo fate per sè stessu, vi cunsumà u listessu dati da differente dispusitivi. Allora avete bisognu di processà è almacenà e dati nantu à u servitore.
  • Sè vo avete assai dati differente cunsumati da parechji utilizatori differente, allura vi tocca à decide ciò chì hè più impurtante: a vitezza di l ‘utilizatori o u risparmiu di ferru da u vostru latu. Quellu chì pò permette una quantità infinita di hardware conta tuttu nantu à u so servitore è rende super veloce per l’utilizatori, salvendu e risorse di l’utilizatori, cum’è a bateria è u trafficu, chì hè assai impurtante in i telefoni.

A so volta, cuntà in u navigatore ùn hè micca a suluzione più ottima in principiu. Dunque, ciò chì ùn hè micca caru, avemu cunsideratu nantu à u nostru servitore. Lascemu u restu à u cliente. Vogliu veramente piglià è calculà a cumissioni nantu à u servitore. Ma quì vene a sfumatura chjamata “interattività”. Diciamu chì avete migliaia di operazioni è ci vole cinque minuti per riceve. Chì serà l’utilizatore à questu tempu? Spinner? Prugressu ? Infa quantu hè stata caricata? Hè ideale per aduprà “attesa attiva” quandu l’utilizatore in u prucessu puderia digià vede qualcosa. Eccu u Risultatu:Sviluppemu un microserviziu utilizendu l'API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.

  • Carica di pagina
  • Tutte e fatture sò richieste
  • Dopu quì, tutte e transazzione cù cumissioni per e transazzione eseguite sò dumandate per tutti i cunti. Quandu i dati sò ricevuti, sò resi in u navigatore.

Per ùn filtrà i dati in l’avvenimenti ogni volta, tiramu u nostru propiu avvenimentu per ogni contu. Cum’è què:

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

U prugettu per lancià hè quì: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 Avanzate. Hè bellu chì avete lettu sta linea! 

Càlculu è output di l’infurmazioni d’interessu

Dipende da quale hà bisognu di quale infurmazione. Dunque, vi dicu subitu i sfumaturi principali chì vi scontru.

U travagliu cù i prezzi 

Tutti quelli chì travaglianu cù finanzii sapi chì e transazzione di soldi deve esse realizatu solu cù numeri sanu. A causa di l’imprecisione di i valori dopu à u puntu decimale è l’errore cumulativu cù un gran numaru di operazioni. Hè per quessa chì tutti i prezzi sò presentati in u seguente formatu MoneyValueSviluppemu un microserviziu utilizendu l'API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.

camputipuDescrizzione
munitastringaString codice di valuta ISO
unitàint64Parte entera di a summa, pò esse un numeru negativu
nanuint32Parte fraccionaria di a quantità, pò esse un numeru negativu

I processemu separatamente, poi purtemu à u valore di u prezzu:

quotazione.unità + quotazione.nano / 1e9

U costu di i cuntratti futuri

U prezzu di futuri hè prisentatu in punti, quandu avete un futuru di munita, avete bisognu di sapè a tarifa. E sicuru u prezzu in punti è u passu di prezzu. Quandu calculate u prufittu da e transazzione, questu pò sparà, perchè. se calcule a quantità tutale multiplichendu u prezzu per a quantità. Quì ci vole à esse attentu. Per avà, videremu cumu si passa. Questu hè applicatu à i futuri di valuta, in altri lochi tuttu hè bè cù questu.Sviluppemu un microserviziu utilizendu l'API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.Sviluppemu un microserviziu utilizendu l'API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.

Mercatu OTC

Stu mercatu hà assai peculiarità, dunque studiemu l’operazioni nantu à questu per separatamente. Quandu avete principiatu à sincronizà l’operazioni, vi scoprerà chì avete bisognu di purtà figi / ticker à a listessa forma per currispondenu currettamente à u strumentu. Quandu avete principiatu à sincronizà questu cù u rapportu di brokerage, vi sarà chì u tradeID di a listessa transazzione hà lettere à u principiu in e transazzione è ùn sò micca in u rapportu di brokerage. Dunque, ùn ponu esse paragunati … ahem-ahem … per paragone ! Aghju accumpagnatu u tempu di cummerciu, ticker è currispundenza chì un tradeId hè cuntenutu in un altru. Giustu, ùn sò micca. Quellu chì scontra questu è chì si preoccupa, vene à u prublema o principià un novu.Sviluppemu un microserviziu utilizendu l'API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.

Operazioni matematiche nantu à l’arnesi

Hè impussibile, senza circà, per fà operazioni matematiche cù tutta a lista. Per ùn aghjunghje micca caldu à morbidu, avemu sempre verificatu a munita è prucessu solu s’è no simu sicuru chì a munita currisponde, è i punti sò cunvertiti in a valuta desiderata. Armatu di cunniscenze nantu à u travagliu cù i numeri bancari, calculeremu a cumissioni spesa nantu à ognunu di i cunti. Cume questu: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4Sviluppemu un microserviziu utilizendu l'API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.   

U microserviziu hè prontu!

https://github.com/pskucherov/tcsstat Cum’è un travagliu in casa, pudete verificà se u serviziu funziona cù una cunnessione lenta, quandu e cunnessione sò rotte, quandu l’Internet hè disconnected, quandu l’errore o i limiti scaduti da parte di u broker. 

Cunclusioni è piani per u futuru

  • Amparatu nantu à e operazioni basiche è travaglià cù l’API Invest
  • U tempu passatu ~ 10 ore
  • Livellu di difficultà ~ junior+ / bassu mediu 

Se continuate à raffinà u microserviziu, pudete finisce cù qualcosa cum’è questu

https://opexbot.info

  Questu hè u mo sviluppu, per quelli chì sò troppu pigri per capiscenu, curriri è cuntà per sè stessu. Pensu di aghjunghje analitiche quì à a dumanda di l’utilizatori. Se ti piace l’articulu, allora abbonate à u mo canale di telegram . Sviluppemu un microserviziu utilizendu l'API Tinkoff Invest per automatizà u travagliu cù rapporti di brokerage è calculà e cumissioni.

Pavel
Rate author
Add a comment

  1. Isakiiev

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

    Reply