Estamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.

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

Os inspiradores do desenvolvemento do servizo de estatísticas para Tinkoff Investments foron:

Que se vai discutir?

  • Só a parte aplicada sobre o desenvolvemento.
  • Coñecementos e experiencia real, que son moi importantes no traballo con instrumentos financeiros.
  • Visión xeral dos asuntos sobre os que se debe traballar

Entón, quero calcular estatísticas comerciais e facelo dun xeito cómodo. 

Desenvolvemento dun servizo de estatística paso a paso: 

  1. Conexión á API de Tinkoff Invest
  2. Debuxar datos da API de Tinkoff Invest nun navegador
  3. Recepción de informes e transaccións de corretaxe
  4. Cálculo e saída da información de interese
  5. Conclusións e plans de futuro

Conexión á API de Tinkoff Invest

Para conectarse á API, pode tomar calquera sdk da documentación https://github.com/Tinkoff/investAPI#sdk . Ou o paquete npm ` tinkoff-sdk-grpc-js `. É importante que os desenvolvedores actualicen o paquete á última versión. Instalar

npm e tinkoff-sdk-grpc-js

Comprobación

const { createSdk } = require(‘tinkoff-sdk-grpc-js’);   // Token que se pode obter así  const TOKEN = ‘YOURAPI’;   // O nome da aplicación coa que se pode atopar nos rexistros de TCS. const appName = ‘tcsstat’;   const sdk = createSdk(TOKEN, appName); (async () => {     console.log(espera sdk.users.getAccounts()); })();

Resultado: aparecerá unha lista das súas contas na consola. Por exemplo, imos analizar os matices:Estamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.

  • Na lista de contas hai un “Banco de investimento”, co que non podes traballar usando a API
  • Teña en conta que os campos veñen en camelCase, mentres que na documentación estes campos preséntanse en under_score. 
  • Será así en todas partes, polo que non podes simplemente coller e copiar un campo da documentación.

Útil:

  • Podes atopar este código na rama do proxecto

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

Debuxar datos da API de Tinkoff Invest nun navegador

Tomei next.js e socket.io. Esta non é unha recomendación forte, escolle ao teu criterio. 

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

Inmediatamente procedemos ao paso de amizade next+socket+investapi e consultamos a sección Útil deste paso para ver todos os detalles.  Vou describir os detalles: 

  • No lado de nodejs (servidor), hai un ficheiro pages/api/investapi.js. Aquí é onde creamos o servidor socket.io e conectamos a investapi.
  • No lado do navegador (cliente), conectámonos ao servidor a través dun socket e solicitamos datos da conta ao corredor. 
  • Recibimos datos do corredor no servidor e despois enviámolos ao cliente. Cando se reciben no cliente, móstranse no navegador. 

Resultado:  na consola do navegador podemos ver información sobre as contas. É dicir, no último paso, vimos información sobre as contas na consola do servidor (nodejs), no paso actual, transferimos esta información ao cliente (navegador).

Estamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.

Agora imos facelo para que poida seleccionar unha conta do navegador e, se non hai ningún token, envíase un erro á consola. O traballo é sinxelo e nada novo, polo que só dou ligazóns a commits

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

Útil:

  • Como facer amigos a continuación e socket descríbese en detalle aquí
  • Código de amizade next+socket+investapi:

https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 Para quen é difícil o anterior, seguimos nesta fase e tratamos o código. Se tes preguntas, pregunta. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2

Recepción de informes e transaccións de corretaxe

Existen tres métodos para recibir informes e transaccións de corretaxe

  1. GetBrokerReport
  2. GetDividendsForeignIssuer
  3. GetOperationsByCursor

Desde o principio é importante saber: 

  • O informe de corretaxe xérase no modo T-3, é dicir. as operacións móstranse alí despois da súa execución real. 
  • En consecuencia, se solicita este informe durante os dous últimos días, estará listo en tres días. 
  • Para obter transaccións dos últimos días, utilizamos o método para recibir transaccións, pero recorda que a súa identificación e contido poden cambiar despois de xerar o informe de corretaxe.

GetBrokerReport

Para obter un informe de corretaxe, cómpre levar a identificación da conta, a data de inicio e a data de finalización do informe, pero non máis de 31 días. Enviamos unha solicitude para xerar un informe á API en generate _broker_report_request , obtemos un taskId como resposta. Despois diso, usando este taskId, obtemos datos de get _broker_report_response.

Entón di a documentación, en realidade hai matices. Coidado coas mans:
  • Debes gardar o TaskID para sempre exactamente para estas datas. 
  • Xa que se o perdes, para as datas solicitadas, o informe chegará primeiro en resposta á solicitude de xeración, 
  • E entón non chegará en absoluto.
Comecemos a escribir código

Método para obter a data, tendo en conta a resta da data actual

const getDateSubDay = (subDay = 5, inicio = verdadeiro) => {     const date = data nova ();     data.setUTCDate(date.getUTCDate() – subdía);       if (inicio) {         data.setUTCHours (0, 0, 0, 0);     } else {         date.setUTCHours (23, 59, 59, 999);     }       data de retorno; };

Solicitude de xeración de informes 

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

Resultado:

  • Como resultado da primeira execución do comando, obtemos o taskId. 
  • O informe comeza a xerarse por parte do corredor. Cando está listo é descoñecido, agardamos e tiramos periodicamente o taskId en previsión do informe.
  • Por que? Porque se o informe non está listo, arroxa un erro. Se o informe non está listo por parte do corredor, entón este é un erro no teu código. Procesa: 30058|INVALID_ARGUMENT|tarefa aínda non completada, téntao de novo máis tarde

O código para esperar e recibir un informe é algo así.

const timer = async time => {     return new Promise (resolve => setTimeout (resolve, time)); }   const getBrokerResponseByTaskId = async (taskId, páxina = 0) => {     try {         return await (sdk.operations.getBrokerReport)({             getBrokerReportRequest: {                 taskId,                 page,             },         });     } catch (e) {         console.log(‘esperar’, e);         temporizador de espera (10000);         return await getBrokerResponseByTaskId(taskId, páxina);     } };

Entón ocorre a mesma maxia. Paramos o noso script, comezalo de novo, non temos un taskId. Executamos o código coa solicitude taskId, pero xa non obtemos o taskId, senón inmediatamente o informe. ¡Maxia! E todo estaría ben se sempre fose así. Pero nun mes non haberá ningún dato. Útil :

  • Descríbese aquí e aquí un pouco de teoría .
  • Xuntando o código, o borrador terá un aspecto así.

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

  • Se alguén se atopa con isto, benvido ao problema . Despois de reparar esta maxia, perderá o seu poder e será dalgún xeito diferente. Pero no momento actual (21/03/2023) funciona así.

GetDividendsForeignIssuer

Alguén pode pensar que o método é semellante ao anterior e podes utilizar un único método no que só cambias o nome das operacións. Pero non adiviñaron!  A denominación alí é moi diferente tanto nos métodos como na información devolta. E o reconto de páxinas comeza a partir de 0, despois de 1. Para non confundirse en todo isto, é máis fácil escribir dous métodos diferentes. O que é estraño, porque a lóxica do traballo é a mesma. Cuspín durante moito tempo cando intentei facer un método e había menos código. Aquí non haberá exemplos.

GetOperationsByCursor

O meu favorito dos tres. Aínda que non é o máis preciso, pero si o máis adecuado. Facemos unha solicitude dende o inicio da creación dunha conta ata a data máxima posible (peche dunha conta ou a actual). Obtemos a resposta, collemos o cursor e volvemos solicitar sempre que haxa datos.  E o código é máis conciso que nos exemplos anteriores.

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,             withoutTrades: falso,             senOvernights: falso,             cursor,         };           return await sdk.operations.getOperationsByCursor(reqData);     } catch (e) {         espera temporizador (60000);         return await getOperationsByCursor (sdk, accountId, from, to, cursor = ”);     } };

O borrador para executar está aquí: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 Agora estamos preparados para engadir operacións de recepción a nosa aplicación. Se se fai correctamente, entón cómpre obter informes de corretaxe durante toda a existencia da conta. E para os datos que faltan, eses mesmos T-3, recargan das operacións. Pero isto pódese separar nun artigo separado. Dos principais matices que atoparás é pegar operacións e un informe de corretaxe.

  •  Se hoxe recibiu un informe de corretaxe e transaccións para as datas requiridas, colócao todo na base de datos, entón non hai problemas. 
  • Terá problemas mañá cando reciba a seguinte parte de datos do informe e das operacións e decida sincronizalos coa base de datos existente. 
  • Moitos matices sobre o ID non coincidente ou o cambio despois do procesamento
  • Entón, para o mercado OTC, as identificacións non coinciden en absoluto.
  •  Así como os matices dos instrumentos de sincronización, que de novo non coinciden, debido ás peculiaridades da API. Pero esa é outra historia.

Engadimos obter información sobre as operacións á nosa aplicación. A cuestión principal será onde se procesarán e almacenarán os datos.

  •  Se o fas por ti mesmo, consumiras os mesmos datos de distintos dispositivos. A continuación, cómpre procesar e almacenar datos no servidor.
  • Se tes moitos datos diferentes consumidos por moitos usuarios diferentes, entón tes que decidir o que é máis importante: a velocidade dos usuarios ou o aforro de ferro do teu lado. Quen pode permitirse unha cantidade infinita de hardware conta todo o que hai no seu servidor e fai que sexa súper rápido para os usuarios, aforrandolle recursos, como batería e tráfico, que é moi importante nos teléfonos.

Á súa vez, contar no navegador non é a solución máis óptima en principio. Polo tanto, o que non é caro, considerámolo no noso servidor. O resto deixámolo ao cliente. Realmente quero tomar e calcular a comisión no servidor. Pero aquí vén o matiz chamado “interactividade”. Digamos que tes miles de operacións e tardas cinco minutos en recibilas. Que terá o usuario neste momento? Spinner? ¿Progreso? Infa sobre canto se cargou? O ideal é usar a “espera activa” cando o usuario no proceso xa pode ver algo. Aquí está o resultado:Estamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.

  • Cargando páxina
  • Todas as facturas son solicitadas
  • Despois diso, todas as transaccións con comisións por transaccións executadas son solicitadas para todas as contas. A medida que se reciben os datos, móstranse no navegador.

Para non filtrar os datos dos eventos cada vez, tiramos o noso propio evento para cada conta. Como isto:

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

O borrador para lanzar está aquí: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 Seguindo. É xenial que leas esta liña! 

Cálculo e saída da información de interese

Depende de quen necesite que información. Polo tanto, cóntoche inmediatamente os principais matices que atoparás.

Traballando cos prezos 

Todos os que traballan con finanzas saben que as transaccións de diñeiro só se deben realizar con números enteiros. Debido á imprecisión dos valores despois do punto decimal e ao erro acumulado cunha gran cantidade de operacións. É por iso que todos os prezos preséntanse no seguinte formato MoneyValueEstamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.

campotipoDescrición
moedacordaCadena de código de moeda ISO
unidadesint64A parte enteira da suma pode ser un número negativo
nanoint32A parte fraccionaria da cantidade pode ser un número negativo

Procesámolos por separado, despois traémolos ao valor do prezo:

cotización.unidades + cotización.nano / 1e9

O custo dos contratos de futuros

O prezo dos futuros preséntase en puntos, cando tes un futuro de moeda, debes coñecer a taxa. E por suposto o prezo en puntos e o escalón de prezo. Cando calculas o beneficio das transaccións, isto pode disparar, porque. se calculas o importe total multiplicando o prezo pola cantidade. Aquí hai que ter coidado. De momento, veremos como vai. Isto aplícase aos futuros de moeda, noutros lugares todo está ben con isto.Estamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.Estamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.

mercado OTC

Este mercado ten moitas peculiaridades, así que imos estudar as operacións sobre el por separado. Cando comeces a sincronizar operacións, resultará que tes que traer figi / ticker ao mesmo formulario para facer coincidir correctamente o instrumento. Cando comeces a sincronizar isto co informe de corretaxe, resultará que o tradeID da mesma transacción ten letras ao principio nas transaccións e non están no informe de corretaxe. Polo tanto, non se poden comparar… ahem-ahem… ¡por comparación! Coincidei co tempo de comercio, co ticker e a coincidencia de que un tradeId está contido noutro. Certo, non o sei. Quen se atope con isto e quen lle importe, veña ao tema ou inicie un novo.Estamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.

Operacións matemáticas sobre ferramentas

É imposible, sen mirar, realizar operacións matemáticas con toda a lista. Para non engadir calor a suave, sempre comprobamos a moeda e procesamos só se estamos seguros de que a moeda coincide e os puntos convértense á moeda desexada. Armados co coñecemento de traballar con números bancarios, calcularemos a comisión gastada en cada unha das contas. Así: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4Estamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.   

O microservizo está listo!

https://github.com/pskucherov/tcsstat Como deberes, pode comprobar se o servizo funciona cunha conexión lenta, cando as conexións están rotas, cando a Internet está desconectada, cando hai erros ou límites caducados por parte do corredor. 

Conclusións e plans de futuro

  • Coñecer as operacións básicas e traballar coa API Invest
  • Tempo empregado ~ 10 horas
  • Nivel de dificultade ~ junior+ / medio baixo 

Se continúas perfeccionando o microservizo, podes acabar con algo así

https://opexbot.info

  Este é o meu desenvolvemento, para aqueles que teñen preguiza para entender, correr e contar por si mesmos. Penso engadir analíticas alí a petición dos usuarios. Se che gustou o artigo, subscríbete á miña canle de Telegram . Estamos a desenvolver un microservizo mediante a API de Tinkoff Invest para automatizar o traballo cos informes de corretaxe e o cálculo de comisións.

Pavel
Rate author
Add a comment

  1. Isakiiev

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

    Reply