Estem desenvolupant un microservei mitjançant l’API de Tinkoff Invest per automatitzar el treball amb informes d’intermediació i el càlcul de comissions.

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

Els inspiradors darrere del desenvolupament del servei d’estadístiques de Tinkoff Investments van ser:

Què es parlarà?

  • Només la part aplicada sobre desenvolupament.
  • Coneixements i experiència reals, molt importants en el treball amb instruments financers.
  • Visió general dels temes a treballar

Per tant, vull calcular les estadístiques comercials i fer-ho d’una manera convenient. 

Desenvolupament d’un servei d’estadístiques pas a pas: 

  1. Connexió a l’API de Tinkoff Invest
  2. Dibuixant dades de l’API Tinkoff Invest en un navegador
  3. Recepció d’informes i transaccions d’intermediació
  4. Càlcul i sortida d’informació d’interès
  5. Conclusions i plans de futur

Connexió a l’API de Tinkoff Invest

Per connectar-vos a l’API, podeu agafar qualsevol sdk de la documentació https://github.com/Tinkoff/investAPI#sdk . O el paquet npm ` tinkoff-sdk-grpc-js `. És important que els desenvolupadors actualitzin el paquet a la darrera versió. Instal·lar

npm i tinkoff-sdk-grpc-js

Comprovació

const { createSdk } = require(‘tinkoff-sdk-grpc-js’);   // Token que es pot obtenir així  const TOKEN = ‘YOURAPI’;   // El nom de l’aplicació amb la qual es pot trobar als registres del TCS. const appName = ‘tcsstat’;   const sdk = createSdk(TOKEN, appName); (async () => {     console.log(espera sdk.users.getAccounts()); })();

Resultat: es mostrarà una llista dels vostres comptes a la consola. Per exemple, analitzem els matisos:Estem desenvolupant un microservei mitjançant l'API de Tinkoff Invest per automatitzar el treball amb informes d'intermediació i el càlcul de comissions.

  • A la llista de comptes hi ha un “Banc d’inversió”, amb el qual no podeu treballar mitjançant l’API
  • Tingueu en compte que els camps vénen en camelCase, mentre que a la documentació aquests camps es presenten en under_score. 
  • Serà així a tot arreu, de manera que no podeu agafar i copiar un camp de la documentació.

Útil:

  • Podeu trobar aquest codi a la branca del projecte

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

Dibuixant dades de l’API Tinkoff Invest en un navegador

Vaig agafar next.js i socket.io. Aquesta no és una recomanació contundent, trieu a la vostra discreció. 

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

Passem immediatament al pas d’amistat següent+socket+investapi i vegeu la secció Útil d’aquest pas per a tots els detalls.  Descriuré els detalls: 

  • Al costat de nodejs (servidor), hi ha un fitxer pages/api/investapi.js. Aquí és on creem el servidor socket.io i ens connectem a investapi.
  • Al costat del navegador (client), ens connectem al servidor mitjançant un sòcol i sol·licitem dades del compte al corredor. 
  • Rebem dades del corredor al servidor i després les enviem al client. Quan es reben al client, es mostren al navegador. 

Resultat:  a la consola del navegador podem veure informació sobre els comptes. És a dir, en l’últim pas, vam veure informació sobre els comptes a la consola del servidor (nodejs), en el pas actual, vam transferir aquesta informació al client (navegador).

Estem desenvolupant un microservei mitjançant l'API de Tinkoff Invest per automatitzar el treball amb informes d'intermediació i el càlcul de comissions.

Ara fem-ho perquè pugueu seleccionar un compte des del navegador i, si no hi ha cap testimoni, s’envia un error a la consola. El treball és senzill i res nou, així que només dono enllaços a commits

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

Útil:

  • Aquí es descriu detalladament com fer amics i el sòcol
  • Codi d’amistat next+socket+investapi:

https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 Per a qui l’anterior és difícil, romandrem en aquesta etapa i tractarem el codi. Si teniu preguntes, pregunteu. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2

Recepció d’informes i transaccions d’intermediació

Hi ha tres mètodes per rebre informes i transaccions d’intermediació

  1. GetBrokerReport
  2. GetDividendsForeignIssuer
  3. GetOperationsByCursor

Des del primer moment és important saber: 

  • L’informe d’intermediació es genera en la modalitat T-3, és a dir. les operacions es mostren allà després de la seva execució real. 
  • En conseqüència, si sol·liciteu aquest informe durant els dos darrers dies, estarà llest en tres dies. 
  • Per obtenir transaccions dels darrers dies, utilitzem el mètode per rebre transaccions, però recordeu que el seu identificador i contingut poden canviar després de generar l’informe d’intermediació.

GetBrokerReport

Per obtenir un informe d’intermediació, cal que introduïu l’identificador del compte, la data d’inici i la data de finalització de l’informe, però no més de 31 dies. Enviem una sol·licitud per generar un informe a l’API a generate _broker_report_request , obtenim un taskId com a resposta. Després d’això, utilitzant aquest taskId, obtenim dades de get _broker_report_response.

Així diu la documentació, en realitat hi ha matisos. Vigileu les vostres mans:
  • Heu de desar el TaskID per sempre exactament per a aquestes dates. 
  • Atès que si el perdeu, per a les dates sol·licitades, primer arribarà l’informe en resposta a la sol·licitud de generació, 
  • I aleshores no arribarà gens.
Comencem a escriure codi

Mètode per obtenir la data, tenint en compte la resta de la data actual

const getDateSubDay = (subDia = 5, inici = true) => {     const data = data nova ();     date.setUTCDate(date.getUTCDate() – subDia);       if (inici) {         date.setUTCHours (0, 0, 0, 0);     } else {         date.setUTCHours(23, 59, 59, 999);     }       data de retorn; };

Sol·licitud de generació d’informes 

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

Resultat:

  • Com a resultat de la primera execució de l’ordre, obtenim el taskId. 
  • L’informe es comença a generar per part del corredor. Quan estigui llest no se sap, esperem i tirem periòdicament el taskId en previsió de l’informe.
  • Per què? Perquè si l’informe no està preparat, genera un error. Si l’informe no està preparat per part del corredor, es tracta d’un error al vostre codi. Si us plau, processeu: 30058|INVALID_ARGUMENT|la tasca encara no s’ha completat; torneu-ho a provar més tard

El codi per esperar i rebre un informe té un aspecte semblant a aquest.

const timer = temps asincrònic => {     retorna nova promesa (resolució => setTimeout (resolució, temps)); }   const getBrokerResponseByTaskId = async (taskId, pàgina = 0) => {     try {         return await (sdk.operations.getBrokerReport)({             getBrokerReportRequest: {                 taskId,                 page,             },         });     } catch (e) {         console.log(‘espera’, e);         temporitzador d’espera (10000);         return await getBrokerResponseByTaskId(taskId, pàgina);     } };

Aleshores passa la mateixa màgia. Aturem el nostre script, el tornem a començar, no tenim un taskId. Executem el codi amb la sol·licitud taskId, però ja no obtenim el taskId, sinó immediatament l’informe. Màgia! I tot aniria bé si sempre fos així. Però d’aquí a un mes no hi haurà dades. Útil :

  • Una mica de teoria es descriu aquí i aquí .
  • Ajuntant el codi, l’esborrany semblarà a aquest.

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

  • Si algú es troba amb això, benvingut al problema . Després de reparar aquesta màgia, perdrà el seu poder i serà d’alguna manera diferent. Però en el moment actual (21/03/2023) funciona així.

GetDividendsForeignIssuer

Algú podria pensar que el mètode és semblant a l’anterior i podeu utilitzar un únic mètode en el qual només canvieu el nom de les operacions. Però no ho van endevinar!  La denominació és molt diferent tant en els mètodes com en la informació retornada. I el recompte de pàgines comença des de 0, després des d’1. Per no confondre’s en tot això, és més fàcil escriure dos mètodes diferents. La qual cosa és estrany, perquè la lògica del treball és la mateixa. Vaig escopir durant molt de temps quan vaig intentar fer un mètode i hi havia menys codi. Aquí no hi haurà exemples.

GetOperationsByCursor

El meu preferit dels tres. Encara que no és el més precís, però sí el més adequat. Realitzem una sol·licitud des de l’inici de la creació d’un compte fins a la data màxima possible (tancar un compte o l’actual). Obtenim la resposta, agafem el cursor i tornem a sol·licitar sempre que hi hagi dades.  I el codi és més concís que en els exemples anteriors.

const timer = temps asincrònic => {     retorna nova promesa (resolució => setTimeout (resolució, temps)); }   const getOperationsByCursor = async (sdk, accountId, from, to, cursor = ”) => {     try {         const reqData = {             accountId,             from,             to,             limit: 1000,             state: sdk.OperationState.OPERATION_STATE_EXECUTED,             withoutCommissions: false,             sense Operacions: fals,             senseOvernights: fals,             cursor,         };           return await sdk.operations.getOperationsByCursor(reqData);     } catch (e) {         await timer (60000);         return await getOperationsByCursor(sdk, accountId, from, to, cursor = ”);     } };

L’esborrany per executar és aquí: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 Ara estem preparats per afegir operacions de recepció a la nostra aplicació. Si es fa correctament, haureu d’obtenir informes d’intermediació durant tota l’existència del compte. I per a les dades que falten, aquests mateixos T-3, es recarreguen des de les operacions. Però això es pot separar en un article separat. Dels principals matisos que trobareu és enganxar les operacions i un informe d’intermediació.

  •  Si avui heu rebut un informe d’intermediació i transaccions per a les dates requerides, poseu-ho tot a la base de dades, no hi ha problemes. 
  • Demà tindreu problemes quan rebeu la següent part de dades de l’informe i les operacions i decidiu sincronitzar-les amb la base de dades existent. 
  • Molts matisos sobre l’identificador no coincident o el canvi després del processament
  • Aleshores, per al mercat OTC, els identificadors no coincideixen gens.
  •  Així com els matisos dels instruments de sincronització, que de nou no coincideixen, a causa de les peculiaritats de l’API. Però això és una altra història.

Afegim obtenir informació sobre les operacions a la nostra aplicació. La pregunta principal serà on es processaran i emmagatzemaran les dades.

  •  Si ho fas per tu mateix, consumiràs les mateixes dades de diferents dispositius. Aleshores, heu de processar i emmagatzemar dades al servidor.
  • Si teniu moltes dades diferents consumides per molts usuaris diferents, heu de decidir què és més important: la velocitat dels usuaris o l’estalvi de ferro al vostre costat. Qui es pot permetre una quantitat infinita de maquinari compta tot el que hi ha al seu servidor i ho fa molt ràpid per als usuaris, estalviant-li recursos, com ara bateria i trànsit, que és molt important als telèfons.

Al seu torn, comptar al navegador no és la solució més òptima en principi. Per tant, el que no és car, ho considerem al nostre servidor. La resta la deixem al client. Tinc moltes ganes de prendre i calcular la comissió al servidor. Però aquí ve el matís anomenat “interactivitat”. Suposem que tens milers d’operacions i trigues cinc minuts a rebre-les. Què tindrà l’usuari en aquest moment? Spinner? Progrés, progressar? Infa sobre quant s’ha penjat? És ideal utilitzar l'”espera activa” quan l’usuari en procés ja pot veure alguna cosa. Aquí teniu el resultat:Estem desenvolupant un microservei mitjançant l'API de Tinkoff Invest per automatitzar el treball amb informes d'intermediació i el càlcul de comissions.

  • S’està carregant la pàgina
  • Es demanen totes les factures
  • Després d’això, es demanen totes les transaccions amb comissions per a les transaccions executades per a tots els comptes. A mesura que es reben les dades, es mostren al navegador.

Per no filtrar les dades dels esdeveniments cada vegada, fem el nostre propi esdeveniment per a cada compte. Com això:

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

L’esborrany per llançar és aquí: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 Seguint endavant. És genial que hagis llegit aquesta línia! 

Càlcul i sortida d’informació d’interès

Depèn de qui necessiti quina informació. Per tant, de seguida us explico els principals matisos que trobareu.

Treballant amb preus 

Tothom que treballa amb finances sap que les transaccions de diners només s’han de fer amb números sencers. A causa de la imprecisió dels valors després del punt decimal i l’error acumulat amb un gran nombre d’operacions. És per això que tots els preus es presenten en el següent format MoneyValueEstem desenvolupant un microservei mitjançant l'API de Tinkoff Invest per automatitzar el treball amb informes d'intermediació i el càlcul de comissions.

camptipusDescripció
monedacordaCadena de codi de moneda ISO
unitatsint64Part entera de la suma, pot ser un nombre negatiu
nanoint32Una fracció de la quantitat, pot ser un nombre negatiu

Els processem per separat i després els portem al valor del preu:

quota.unitats + quota.nano / 1e9

El cost dels contractes de futurs

El preu dels futurs es presenta en punts, quan tens un futur de divises, has de conèixer la taxa. I per descomptat el preu en punts i el pas de preu. Quan calculeu el benefici de les transaccions, això pot disparar, perquè. si calculeu l’import total multiplicant el preu per la quantitat. Aquí cal anar amb compte. De moment, veurem com va. Això s’aplica als futurs de divises, en altres llocs tot està bé amb això.Estem desenvolupant un microservei mitjançant l'API de Tinkoff Invest per automatitzar el treball amb informes d'intermediació i el càlcul de comissions.Estem desenvolupant un microservei mitjançant l'API de Tinkoff Invest per automatitzar el treball amb informes d'intermediació i el càlcul de comissions.

Mercat OTC

Aquest mercat té moltes peculiaritats, així que estudiem-ne les operacions per separat, quan comenci a sincronitzar les operacions, resultarà que cal portar figi/ticker a la mateixa forma per tal de fer coincidir correctament l’instrument. Quan comenceu a sincronitzar-ho amb l’informe d’intermediació, resultarà que el tradeID de la mateixa transacció té lletres al principi de les transaccions i no es troben a l’informe d’intermediació. Per tant, no es poden comparar… ahem-ahem… per comparació! Vaig fer coincidir l’hora de comerç, el ticker i la coincidència que un tradeId es troba en un altre. D’acord, no ho sé. Qui es trobi amb això i a qui li importa, vingui al tema o en comenci un de nou.Estem desenvolupant un microservei mitjançant l'API de Tinkoff Invest per automatitzar el treball amb informes d'intermediació i el càlcul de comissions.

Operacions matemàtiques sobre eines

És impossible, sense mirar, realitzar operacions matemàtiques amb tota la llista. Per no afegir calent a suau, sempre comprovem la moneda i el processem només si estem segurs que la moneda coincideix i els punts es converteixen a la moneda desitjada. Armats amb coneixements sobre el treball amb números bancaris, calcularem la comissió gastada en cadascun dels comptes. Així: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4Estem desenvolupant un microservei mitjançant l'API de Tinkoff Invest per automatitzar el treball amb informes d'intermediació i el càlcul de comissions.   

El microservei està preparat!

https://github.com/pskucherov/tcsstat Com a deures, podeu comprovar si el servei funciona amb una connexió lenta, quan les connexions estan trencades, quan es desconnecta Internet, quan hi ha errors o límits vençuts per part del corredor. 

Conclusions i plans de futur

  • Aprendre sobre les operacions bàsiques i el treball amb l’API d’Invest
  • Temps dedicat ~ 10 hores
  • Nivell de dificultat ~ júnior+ / mitjà baix 

Si continueu perfeccionant el microservei, és possible que acabeu amb alguna cosa com això

https://opexbot.info

  Aquest és el meu desenvolupament, per a aquells que són massa mandrós per entendre, córrer i comptar pel seu compte. Penso afegir-hi analítiques a petició dels usuaris. Si t’ha agradat l’article, subscriu-te al meu canal de Telegram . Estem desenvolupant un microservei mitjançant l'API de Tinkoff Invest per automatitzar el treball amb informes d'intermediació i el càlcul de comissions.

Pavel
Rate author
Add a comment

  1. Isakiiev

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

    Reply