중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다.

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

Tinkoff Investments의 통계 서비스 개발에 영감을 준 사람들은 다음과 같습니다.

무엇을 논의할 것인가?

  • 개발에 대해서는 적용되는 부분만.
  • 금융 상품 작업에서 매우 중요한 실제 지식과 경험.
  • 작업할 문제 개요

그래서 거래 통계를 계산해서 편리한 방법으로 하고 싶습니다. 

단계별 통계 서비스 개발: 

  1. Tinkoff 투자 API에 연결
  2. 브라우저에서 Tinkoff Invest API의 데이터 그리기
  3. 중개보고 및 거래 접수
  4. 관심 정보 계산 및 출력
  5. 결론 및 향후 계획

Tinkoff 투자 API에 연결

API에 연결하려면 https://github.com/Tinkoff/investAPI#sdk 문서에서 SDK를 가져올 수 있습니다 . 또는 npm 패키지 ` tinkoff-sdk-grpc-js `. 개발자가 패키지를 최신 버전으로 업데이트하는 것이 중요합니다. 설치하다

npm i tinkoff-sdk-grpc-js

확인 중

const { createSdk } = require(‘tinkoff-sdk-grpc-js’);   // 이렇게 얻을 수 있는 토큰   const TOKEN = ‘YOURAPI’;   // TCS 로그에서 찾을 수 있는 애플리케이션의 이름입니다. const appName = ‘tcsstat’;   const sdk = createSdk(TOKEN, appName); (async () => {     console.log(await sdk.users.getAccounts()); })();

결과: 계정 목록이 콘솔에 표시됩니다. 예를 들어 뉘앙스를 분석해 보겠습니다 .중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다.

  • 계정 목록에는 API를 사용하여 작업할 수 없는 “투자 은행”이 있습니다.
  • 필드는 camelCase로 제공되지만 문서 에서는 이러한 필드가 under_score로 표시됩니다. 
  • 모든 곳에서 이와 같을 것이므로 문서에서 필드를 가져와 복사할 수는 없습니다.

유용한:

  • 프로젝트 브랜치에서 이 코드를 찾을 수 있습니다.

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

브라우저에서 Tinkoff Invest API의 데이터 그리기

next.js와 socket.io를 사용했습니다. 이것은 강력한 권장 사항이 아니므로 재량에 따라 선택하십시오. 

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

우리는 즉시 우정 단계 next+socket+investapi로 진행하고 모든 세부 사항은 이 단계의  유용한 섹션을 참조하십시오. 세부 사항을 설명하겠습니다. 

  • nodejs(서버) 측에는 pages/api/investapi.js 파일이 있습니다. 여기에서 socket.io 서버를 생성하고Investapi에 연결합니다.
  • 브라우저(클라이언트) 측에서 소켓을 통해 서버에 연결하고 브로커에서 계정 데이터를 요청합니다. 
  • 우리는 서버의 브로커로부터 데이터를 받은 다음 클라이언트로 보냅니다. 클라이언트에서 수신하면 브라우저에 표시됩니다. 

결과:  브라우저 콘솔에서 계정에 대한 정보를 볼 수 있습니다. 즉, 마지막 단계에서 우리는 서버 콘솔(nodejs)에서 계정에 대한 정보를 보았고, 현재 단계에서 이 정보를 클라이언트(브라우저)로 전송했습니다.

중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다.

이제 브라우저에서 계정을 선택하고 토큰이 없으면 콘솔에 오류가 전송되도록 만들어 보겠습니다. 작업이 간단하고 새로운 것이 없으므로 커밋에 대한 링크만 제공합니다.

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

유용한:

  • 다음에 친구를 사귀는 방법과 소켓은 여기 에 자세히 설명되어 있습니다 . 
  • 우정 코드 next+socket+investapi:

https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 위의 내용이 어려운 분들을 위해 이 단계에 머물며 코드를 다룹니다. 질문이 있으면 물어보십시오. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2

중개보고 및 거래 접수

중개신고 및 거래접수 방법은 3가지가 있습니다.

  1. GetBrokerReport
  2. GetDividendsForeignIssuer
  3. GetOperationsByCursor

처음부터 다음을 아는 것이 중요합니다. 

  • 중개 보고서는 T-3 모드에서 생성됩니다. 거래는 실제 실행 후 거기에 표시됩니다. 
  • 따라서 지난 2일 동안 이 보고서를 요청하면 3일 후에 준비됩니다. 
  • 마지막 날의 거래를 받기 위해서는 거래를 받기 위한 방법을 사용하지만 중개 보고서가 생성된 후 ID와 내용이 변경될 수 있음을 유의하십시오.

GetBrokerReport

중개 보고서를 받으려면 계정 ID, 보고서의 시작 날짜 및 종료 날짜를 가져와야 하지만 31일을 넘지 않아야 합니다. generate _broker_report_request 에서 API에 보고서 생성 요청을 보내고 응답으로 taskId를 받습니다. 그런 다음 이 taskId를 사용하여 get _broker_report_response에서 데이터를 가져옵니다.

그래서 문서에 따르면 실제로는 뉘앙스가 있습니다. 손을 조심하세요:

  • 이 날짜에 대해 정확히 TaskID를 영원히 저장해야 합니다. 
  • 분실하면 요청한 날짜에 대해 생성 요청에 대한 응답으로 보고서가 먼저 오기 때문에, 
  • 그리고 그것은 전혀 오지 않을 것입니다.

코드 작성을 시작하겠습니다.

현재 날짜에서 빼기를 고려하여 날짜를 가져오는 방법

const getDateSubDay = (subDay = 5, 시작 = 참) => {     const 날짜 = 새 날짜();     date.setUTCDate(date.getUTCDate() – subDay);       if (시작) {         date.setUTCHours(0, 0, 0, 0);     } 그렇지 않으면 {         date.setUTCHours(23, 59, 59, 999);     }       반환 날짜; };

보고서 생성 요청 

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

결과:

  • 명령을 처음 실행한 결과 taskId를 얻습니다. 
  • 브로커 측에서 보고서가 생성되기 시작합니다. 준비가 되었는지 알 수 없는 경우 보고를 예상하여 주기적으로 taskId를 가져옵니다.
  • 왜? 보고서가 준비되지 않은 경우 오류가 발생하기 때문입니다. 보고서가 브로커 측에서 준비되지 않은 경우 코드 오류입니다. 처리하십시오: 30058|INVALID_ARGUMENT|작업이 아직 완료되지 않았습니다. 나중에 다시 시도하십시오.

대기하고 보고서를 받는 코드는 다음과 같습니다.

const timer = async time => {     return new Promise(resolve => setTimeout(resolve, time)); }   const getBrokerResponseByTaskId = async (taskId, page = 0) => {     try {         return await (sdk.operations.getBrokerReport)({             getBrokerReportRequest: {                 taskId,                 page,             },         });     } catch (e) {         console.log(‘wait’, e);         대기 타이머(10000);         return await getBrokerResponseByTaskId(taskId, page);     } };

그런 다음 동일한 마법이 발생합니다. 스크립트를 중지하고 다시 시작하면 taskId가 없습니다. 우리는 taskId 요청으로 코드를 실행하지만 더 이상 taskId를 얻지 않고 즉시 보고합니다. 마법! 그리고 항상 이랬다면 모든 것이 잘 될 것입니다. 그러나 한 달 안에 데이터가 전혀 없을 것입니다. 유용한 :

  • 약간의 이론이 여기여기에서 설명됩니다 .
  • 코드를 합치면 초안은 다음과 같이 보일 것입니다.

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

  • 누군가 이 문제를 발견하면 문제 에 오신 것을 환영합니다 . 그들이 이 마법을 고치고 나면, 그것은 힘을 잃고 어떻게든 달라질 것입니다. 그러나 현재(2023년 3월 21일)에는 그대로 작동합니다.

GetDividendsForeignIssuer

누군가는 방법이 이전 방법과 유사하다고 생각할 수 있으며 작업 이름만 변경하는 단일 방법을 사용할 수 있습니다. 그러나 그들은 추측하지 않았습니다!  메서드와 반환된 정보 모두에서 이름 지정이 매우 다릅니다. 그리고 페이지 수는 0부터 시작한 다음 1부터 시작합니다. 이 모든 것을 혼동하지 않으려면 두 가지 다른 방법을 작성하는 것이 더 쉽습니다. 이상한 점은 작업의 논리는 동일합니다. 한가지 방법을 만들려고 했더니 코드가 적었다. 여기에는 예가 없습니다.

GetOperationsByCursor

세 가지 중 내가 가장 좋아하는 것. 가장 정확하지는 않지만 가장 적절합니다. 계정 생성 시작부터 가능한 최대 날짜(계정 폐쇄 또는 현재 계정 폐쇄)까지 요청합니다. 답을 얻고 커서를 잡고 데이터가 있는 한 다시 요청합니다.  그리고 코드는 위의 예보다 더 간결합니다.

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: 거짓,             withoutOvernights: 거짓,             커서,         };           return await sdk.operations.getOperationsByCursor(reqData);     } catch (e) {         대기 타이머(60000);         return await getOperationsByCursor(sdk, accountId, from, to, cursor = ”);     } };

실행할 초안은 다음과 같습니다. https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 이제 수신 작업을 추가할 준비가 되었습니다. 우리의 응용 프로그램. 올바르게 완료되면 계정의 전체 존재에 대한 중개 보고서를 받아야 합니다. 그리고 누락된 데이터의 경우 동일한 T-3가 작업에서 다시 로드됩니다. 그러나 이것은 별도의 기사로 분리될 수 있습니다. 접하게 될 주요 뉘앙스 중 하나는 운영 및 중개 보고서를 붙이는 것입니다.

  •  오늘 필요한 날짜에 대한 중개 보고서 및 거래를 받았다면 모두 데이터베이스에 넣으면 문제가 없습니다. 
  • 보고서 및 작업에서 데이터의 다음 부분을 수신하고 기존 데이터베이스와 동기화하기로 결정하면 내일 문제가 발생합니다. 
  • 처리 후 ID 불일치 또는 변경에 대한 많은 뉘앙스
  • 그런 다음 OTC 시장의 경우 ID가 전혀 일치하지 않습니다.
  •  API의 특성으로 인해 다시 일치하지 않는 동기화 도구의 뉘앙스도 있습니다. 그러나 그것은 또 다른 이야기입니다.

애플리케이션에 작업에 대한 정보 가져오기를 추가해 보겠습니다. 주요 질문은 데이터가 처리되고 저장되는 위치입니다.

  •  직접 수행하는 경우 다른 장치에서 동일한 데이터를 소비하게 됩니다. 그런 다음 서버에서 데이터를 처리하고 저장해야 합니다.
  • 많은 다른 사용자가 사용하는 다양한 데이터가 있는 경우 더 중요한 것이 무엇인지 결정해야 합니다. 사용자의 속도 또는 철 절약입니다. 무한한 양의 하드웨어를 감당할 수 있는 사람은 자신의 서버에 있는 모든 것을 계산하고 사용자를 위해 초고속으로 만들어 배터리 및 트래픽과 같은 사용자 리소스를 절약합니다. 이는 전화에서 매우 중요합니다.

결과적으로 브라우저에서 계산하는 것은 원칙적으로 가장 최적의 솔루션이 아닙니다. 따라서 비싸지 않은 것은 서버에서 고려합니다. 나머지는 고객에게 맡깁니다. 나는 정말로 서버에서 커미션을 취하고 계산하고 싶습니다. 그러나 여기에 “상호 작용”이라는 뉘앙스가 있습니다. 수천 개의 작업이 있고 작업을 받는 데 5분이 걸린다고 가정해 보겠습니다. 이때 사용자는 무엇을 갖게 됩니까? 스피너? 진전? 인파는 얼마나 업로드 되었습니까? 프로세스의 사용자가 이미 무언가를 볼 수 있을 때 “활성 대기”를 사용하는 것이 이상적입니다. 결과는 다음과 같습니다 . 중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다.

  • 페이지 로딩
  • 모든 인보이스가 요청됩니다.
  • 그 후 실행된 트랜잭션에 대한 수수료가 있는 모든 트랜잭션이 모든 계정에 대해 요청됩니다. 데이터가 수신되면 브라우저에서 렌더링됩니다.

매번 이벤트의 데이터를 필터링하지 않기 위해 각 계정에 대해 자체 이벤트를 가져옵니다. 이와 같이:

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

시작할 초안은 다음과 같습니다. https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 계속 진행합니다. 이 줄을 읽은 것이 좋습니다! 

관심 정보 계산 및 출력

누가 어떤 정보를 필요로 하느냐에 따라 다릅니다. 그러므로 나는 당신이 직면하게 될 주요 뉘앙스를 즉시 알려줍니다.

가격 작업 

금전 거래는 정수로만 이루어져야 한다는 것은 금융 업무를 하는 사람이라면 누구나 알고 있습니다. 소수점 이하 값의 부정확성 및 많은 수의 연산으로 인한 누적 오류로 인해. 그렇기 때문에 모든 가격은 다음 MoneyValue 형식으로 표시됩니다.중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다.

필드 유형 설명
통화 문자열 ISO 통화 코드
단위 int64 합계의 정수 부분, 음수일 수 있음
나노 int32 금액의 소수 부분은 음수일 수 있습니다.

별도로 처리한 다음 가격 값으로 가져옵니다.

quote.units + quote.nano / 1e9

선물 계약 비용

선물의 가격은 포인트로 표시되며 통화 선물이 있는 경우 환율을 알아야 합니다. 물론 포인트 가격과 가격 단계도 있습니다. 거래의 이익을 계산할 때 이것은 촬영할 수 있습니다. 가격에 수량을 곱하여 총 금액을 계산하는 경우. 여기서 조심해야 합니다. 지금은 어떻게 진행되는지 보겠습니다. 이것은 통화 선물에 적용되며 다른 곳에서는 이것으로 모든 것이 괜찮습니다.중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다. 중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다.

OTC 시장

이 시장은 많은 특징을 가지고 있으므로 그것에 대한 작업을 별도로 연구하고 작업을 동기화하기 시작하면 악기를 올바르게 일치시키기 위해 figi/ticker를 동일한 형식으로 가져와야 함을 알 수 있습니다. 이를 중개 보고서와 동기화하기 시작하면 동일한 거래의 tradeID에 거래 시작 부분에 문자가 있고 중개 보고서에는 없는 것으로 판명됩니다. 따라서 비교할 수 없습니다 … 에헴 에헴 … 비교로! 하나의 tradeId가 다른 것에 포함되어 있는 거래 시간, 시세 및 일치를 일치시켰습니다. 맞아, 모르겠어. 누구든 이 문제를 접하고 관심을 갖는 사람은 문제를 해결 하거나 새로운 문제를 시작하세요.중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다.

도구에 대한 수학적 연산

보지 않고 전체 목록으로 수학 연산을 수행하는 것은 불가능합니다. 웜에 소프트를 추가하지 않기 위해 항상 통화를 확인하고 통화가 일치하는 경우에만 처리하며 포인트는 원하는 통화로 변환됩니다. 은행 번호 작업에 대한 지식을 바탕으로 각 계정에 사용되는 수수료를 계산합니다. 이와 같이: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다.    

마이크로서비스가 준비되었습니다!

https://github.com/pskucherov/tcsstat 연결이 느린 경우, 연결이 끊어진 경우, 인터넷 연결이 끊어진 경우, 브로커 측에서 오류가 발생하거나 제한이 만료된 경우 서비스가 작동하는지 숙제로 확인할 수 있습니다. 

결론 및 향후 계획

  • 기본 작업 및 Invest API 작업에 대해 배웠습니다.
  • 소요시간 ~ 10시간
  • 난이도 ~ 주니어+ / 중하 

마이크로서비스를 계속 개선하면 다음과 같은 결과가 나올 수 있습니다.

https://opexbot.info

  이것은 스스로 이해하고 실행하고 계산하기에는 너무 게으른 사람들을 위한 나의 개발입니다. 사용자의 요청에 따라 거기에 분석을 추가할 계획입니다. 기사가 마음에 들면 내 텔레그램 채널을 구독하십시오 . 중개 보고서 작업 및 커미션 계산을 자동화하기 위해 Tinkoff Invest API를 사용하여 마이크로서비스를 개발하고 있습니다.

Pavel
Rate author
Add a comment

  1. Isakiiev

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

    응답