Inspirasi di balik pengembangan layanan statistik untuk Tinkoff Investments adalah:
- artikel tentang Habré “Apa yang tidak dikatakan Tinkoff Investments”
- analisis keinginan pengguna platform
- artikel tentang perhitungan komisi .
- Apa yang akan dibahas?
- Mengembangkan layanan statistik langkah demi langkah:
- Koneksi ke Tinkoff Invest API
- Menggambar data dari Tinkoff Invest API di browser
- Menerima laporan broker dan transaksi
- GetBrokerReport
- Metode untuk mendapatkan tanggal, dengan mempertimbangkan pengurangan dari tanggal saat ini
- Permintaan pembuatan laporan
- Hasil:
- GetDividendsForeignIssuer
- GetOperationsByCursor
- Perhitungan dan keluaran informasi yang menarik
- Bekerja dengan harga
- Biaya kontrak berjangka
- pasar OTC
- Operasi matematika pada alat
- Layanan mikro sudah siap!
- Kesimpulan dan rencana untuk masa depan
- https://opexbot.info
Apa yang akan dibahas?
- Hanya bagian terapan tentang pengembangan.
- Pengetahuan dan pengalaman nyata, yang sangat penting dalam bekerja dengan instrumen keuangan.
- Ikhtisar masalah untuk dikerjakan
Jadi, saya ingin menghitung statistik perdagangan dan melakukannya dengan cara yang nyaman.
Mengembangkan layanan statistik langkah demi langkah:
- Koneksi ke Tinkoff Invest API
- Menggambar data dari Tinkoff Invest API di browser
- Menerima laporan broker dan transaksi
- Perhitungan dan keluaran informasi yang menarik
- Kesimpulan dan rencana untuk masa depan
Koneksi ke Tinkoff Invest API
Untuk terhubung ke API, Anda dapat mengambil sdk apa saja dari dokumentasi https://github.com/Tinkoff/investAPI#sdk . Atau paket npm ` tinkoff-sdk-grpc-js` . Penting agar paket diperbarui ke versi terbaru oleh pengembang. Install
npm saya tinkoff-sdk-grpc-js
Memeriksa
const { createSdk } = membutuhkan (‘tinkoff-sdk-grpc-js’); // Token yang bisa didapatkan seperti ini const TOKEN = ‘YOURAPI’; // Nama aplikasi tempat Anda dapat ditemukan di log TCS. const namaaplikasi = ‘tcsstat’; const sdk = createSdk(TOKEN, appName); (async () => { console.log(menunggu sdk.users.getAccounts()); })();
Hasil: daftar akun Anda akan ditampilkan di konsol. Misalnya, mari kita analisis nuansanya:
- Dalam daftar akun ada “Bank investasi”, yang tidak dapat Anda gunakan untuk bekerja menggunakan API
- Harap perhatikan bahwa bidang datang dalam bentuk camelCase, sedangkan dalam dokumentasi bidang ini disajikan dalam under_score.
- Akan seperti ini di mana-mana, jadi Anda tidak bisa begitu saja mengambil dan menyalin bidang dari dokumentasi.
Berguna:
- Anda dapat menemukan kode ini di cabang proyek
https://github.com/pskucherov/tcsstat/tree/step1 https://github.com/pskucherov/tcsstat/compare/step1
Menggambar data dari Tinkoff Invest API di browser
Saya mengambil next.js dan socket.io. Ini bukan rekomendasi yang kuat, pilih sesuai kebijaksanaan Anda.
npx create-next-app@ npm terbaru saya socket.io socket.io-client
Kami segera melanjutkan ke langkah persahabatan berikutnya + soket + investasi, dan lihat bagian Berguna dari langkah ini untuk semua detailnya. Saya akan menjelaskan detailnya:
- Di sisi nodejs (server), ada file pages/api/investapi.js. Di sinilah kami membuat server socket.io dan terhubung ke investapi.
- Di sisi browser (klien), kami terhubung ke server melalui soket dan meminta data akun dari broker.
- Kami menerima data dari broker di server, lalu mengirimkannya ke klien. Ketika mereka diterima di klien, mereka ditampilkan di browser.
Hasil: di konsol browser kita dapat melihat informasi tentang akun. Artinya, pada langkah terakhir, kami melihat informasi tentang akun di konsol server (nodejs), pada langkah saat ini, kami mentransfer informasi ini ke klien (browser).
Sekarang mari kita buat agar Anda dapat memilih akun dari browser, dan jika tidak ada token, maka kesalahan dikirim ke konsol. Pekerjaannya sederhana dan bukan hal baru, jadi saya hanya memberikan tautan ke komitmen
- https://github.com/pskucherov/tcsstat/commit/7e1ac57061e5e971588479015b06d8814d6609a9
- https://github.com/pskucherov/tcsstat/commit/b28ac973a57494f5232589b4cb6b9fb13b8af759
Berguna:
- Cara berteman berikutnya dan soket dijelaskan secara rinci di sini .
- Kode pertemanan next+socket+investapi:
https://github.com/pskucherov/tcsstat/commit/a443a4ac1bb4f0aa898f638128755fe7391ee381 Bagi yang di atas sulit, maka kami tetap pada tahap ini dan menangani kodenya. Jika Anda memiliki pertanyaan – tanyakan. https://github.com/pskucherov/tcsstat/tree/step2 https://github.com/pskucherov/tcsstat/compare/step1…step2
Menerima laporan broker dan transaksi
Ada tiga metode untuk menerima laporan dan transaksi perantara
Sejak awal, penting untuk diketahui:
- Laporan broker dihasilkan dalam mode T-3, mis. perdagangan ditampilkan di sana setelah eksekusi sebenarnya.
- Oleh karena itu, jika Anda meminta laporan ini untuk dua hari terakhir, laporan tersebut akan siap dalam tiga hari.
- Untuk membuat kesepakatan untuk hari-hari terakhir, kami menggunakan metode untuk menerima operasi, tetapi ingat bahwa id dan kontennya dapat berubah setelah pembentukan laporan broker.
GetBrokerReport
Untuk mendapatkan laporan perantara, Anda perlu mengambil id akun, tanggal mulai dan tanggal akhir laporan, tetapi tidak lebih dari 31 hari. Kami mengirim permintaan untuk membuat laporan ke API di generate _broker_report_request , dapatkan taskId sebagai tanggapan. Setelah itu, dengan menggunakan taskId ini, kami mendapatkan data dari get _broker_report_response.
- Anda harus menyimpan TaskID selamanya tepat untuk tanggal-tanggal ini.
- Karena jika Anda kehilangannya, maka untuk tanggal yang diminta, laporan pertama kali akan datang sebagai tanggapan atas permintaan pembuatan,
- Dan kemudian itu tidak akan datang sama sekali.
Metode untuk mendapatkan tanggal, dengan mempertimbangkan pengurangan dari tanggal saat ini
const getDateSubDay = (subHari = 5, mulai = true) => { tanggal const = Tanggal baru(); date.setUTCDate(date.getUTCDate() – subHari); if (mulai) { tanggal.setUTCHours(0, 0, 0, 0); } else { tanggal.setUTCHours(23, 59, 59, 999); } tanggal kembali; };
Permintaan pembuatan laporan
const brokerReport = menunggu (sdk.operations.getBrokerReport)({ generateBrokerReportRequest: { accountId, from, to, }, });
Hasil:
- Sebagai hasil dari eksekusi pertama dari perintah tersebut, kami mendapatkan taskId.
- Laporan mulai dibuat di sisi broker. Jika sudah siap tidak diketahui, kami menunggu dan menarik taskId secara berkala untuk mengantisipasi laporan.
- Mengapa? Karena jika laporan tidak siap, itu membuat kesalahan. Jika laporan belum siap di pihak broker, maka ini adalah kesalahan dalam kode Anda. Harap diproses: 30058|INVALID_ARGUMENT|tugas belum selesai, silakan coba lagi nanti
Kode untuk menunggu dan menerima laporan terlihat seperti ini.
const timer = async time => { return new Promise(resolve => setTimeout(resolve, time)); } const getBrokerResponseByTaskId = async (taskId, halaman = 0) => { coba { kembali menunggu (sdk.operations.getBrokerReport)({ getBrokerReportRequest: { taskId, halaman, }, }); } tangkap (e) { console.log(‘tunggu’, e); menunggu waktu (10000); kembali menunggu getBrokerResponseByTaskId(taskId, halaman); } };
Kemudian keajaiban yang sama terjadi. Kami menghentikan skrip kami, memulainya lagi, kami tidak memiliki taskId. Kami mengeksekusi kode dengan permintaan taskId, tetapi kami tidak lagi mendapatkan taskId, tetapi segera laporannya. Sihir! Dan semuanya akan baik-baik saja jika selalu seperti ini. Tapi dalam sebulan tidak akan ada data sama sekali. Berguna :
https://github.com/pskucherov/tcsstat/tree/step3.1 https://github.com/pskucherov/tcsstat/compare/step3.1
- Jika seseorang menemukan ini, selamat datang di masalah ini . Setelah mereka memperbaiki sihir ini, sihir itu akan kehilangan kekuatannya dan akan menjadi berbeda. Tapi saat ini (21/03/2023) berfungsi begitu saja.
GetDividendsForeignIssuer
Seseorang mungkin berpikir bahwa metodenya mirip dengan yang sebelumnya dan Anda dapat menggunakan satu metode di mana Anda hanya mengubah nama operasinya. Tapi mereka tidak menebak! Penamaan di sana sangat berbeda baik dalam metode maupun informasi yang dikembalikan. Dan jumlah halaman dimulai dari 0, lalu dari 1. Agar tidak bingung dengan semua ini, lebih mudah menulis dua metode berbeda. Yang aneh, karena logika kerjanya sama. Saya meludah lama sekali ketika saya mencoba membuat satu metode dan kodenya lebih sedikit. Tidak akan ada contoh di sini.
GetOperationsByCursor
Favorit saya dari ketiganya. Meski bukan yang paling akurat, tapi yang paling memadai. Kami membuat permintaan dari awal pembuatan akun hingga tanggal maksimum yang memungkinkan (menutup akun atau akun saat ini). Kami mendapatkan jawabannya, ambil kursor dan permintaan ulang selama ada data. Dan kodenya lebih ringkas dari pada contoh di atas.
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: false, withoutOvernights: false, kursor, }; kembali menunggu sdk.operations.getOperationsByCursor(reqData); } catch (e) { menunggu timer(60000); kembali menunggu getOperationsByCursor(sdk, accountId, dari, ke, kursor = ”); } };
Draf untuk dijalankan ada di sini: https://github.com/pskucherov/tcsstat/tree/step3.3 https://github.com/pskucherov/tcsstat/compare/step3.3 Sekarang kami siap menambahkan operasi penerimaan ke aplikasi kami. Jika dilakukan dengan benar, maka Anda perlu mendapatkan laporan broker untuk seluruh keberadaan akun tersebut. Dan untuk data yang hilang, T-3 yang sama, dimuat ulang dari operasi. Tapi ini bisa dipisahkan menjadi artikel tersendiri. Nuansa utama yang akan Anda temui adalah merekatkan operasi dan laporan broker.
- Jika hari ini Anda menerima laporan perantara dan transaksi untuk tanggal yang diminta, masukkan semuanya ke dalam database, maka tidak ada masalah.
- Anda akan mengalami masalah besok ketika Anda menerima bagian data berikutnya dari laporan dan operasi dan memutuskan untuk menyinkronkannya dengan database yang ada.
- Banyak nuansa tentang ketidakcocokan atau perubahan id setelah diproses
- Kemudian untuk pasar OTC, id sama sekali tidak cocok.
- Serta nuansa instrumen sinkronisasi, yang lagi-lagi tidak sesuai, karena kekhasan API. Tapi itu cerita lain.
Mari tambahkan mendapatkan informasi tentang operasi ke aplikasi kita. Pertanyaan utamanya adalah di mana data akan diproses dan disimpan.
- Jika Anda melakukannya sendiri, Anda akan menggunakan data yang sama dari perangkat yang berbeda. Maka Anda perlu memproses dan menyimpan data di server.
- Jika Anda memiliki banyak data berbeda yang dikonsumsi oleh banyak pengguna berbeda, maka Anda perlu memutuskan mana yang lebih penting: kecepatan pengguna atau penghematan besi di pihak Anda. Siapa pun yang mampu membeli perangkat keras dalam jumlah tak terbatas menghitung semua yang ada di servernya dan membuatnya sangat cepat bagi pengguna, menghemat sumber daya pengguna, seperti baterai dan lalu lintas, yang sangat penting di ponsel.
Pada gilirannya, menghitung di browser pada prinsipnya bukanlah solusi yang paling optimal. Oleh karena itu, apa yang tidak mahal, kami pertimbangkan di server kami. Kami menyerahkan sisanya kepada klien. Saya sangat ingin mengambil dan menghitung komisi di server. Tapi inilah nuansa yang disebut “interaktivitas”. Katakanlah Anda memiliki ribuan operasi dan butuh lima menit untuk menerimanya. Apa yang akan dimiliki pengguna saat ini? Pemintal? Kemajuan? INFA tentang berapa banyak yang diunggah? Sangat ideal untuk menggunakan “penungguan aktif” saat pengguna dalam proses sudah dapat melihat sesuatu. Inilah Hasilnya:
- Memuat halaman
- Semua tagihan diminta
- Setelah itu, semua transaksi dengan komisi untuk transaksi yang dieksekusi diminta untuk semua akun. Saat data diterima, itu diberikan di browser.
Agar tidak memfilter data dalam acara setiap saat, kami menarik acara kami sendiri untuk setiap akun. Seperti ini:
socket.emit(‘sdk:getOperationsCommissionResult_’ + accountId, { item: data?.items, inProgress: Boolean(nextCursor), });
Draf untuk diluncurkan ada di sini: https://github.com/pskucherov/tcsstat/tree/step3 https://github.com/pskucherov/tcsstat/compare/step2…step3 Selanjutnya. Sangat menyenangkan Anda telah membaca baris ini!
Perhitungan dan keluaran informasi yang menarik
Tergantung siapa yang butuh informasi apa. Oleh karena itu, saya langsung memberi tahu Anda nuansa utama yang akan Anda temui.
Bekerja dengan harga
Setiap orang yang bekerja dengan keuangan tahu bahwa transaksi uang hanya boleh dilakukan dengan bilangan bulat. Karena ketidakakuratan nilai setelah titik desimal dan kesalahan kumulatif dengan sejumlah besar operasi. Itu sebabnya semua harga disajikan dalam format MoneyValue berikut
bidang | jenis | Keterangan |
---|---|---|
mata uang | rangkaian | String kode mata uang ISO |
unit | int64 | Bagian bilangan bulat dari penjumlahan, bisa berupa bilangan negatif |
nano | int32 | Bagian pecahan dari jumlah, bisa berupa angka negatif |
Kami memprosesnya secara terpisah, lalu membawanya ke nilai harga:
kutipan.unit + kutipan.nano / 1e9
Biaya kontrak berjangka
Harga berjangka disajikan dalam poin, ketika Anda memiliki mata uang berjangka, Anda perlu mengetahui kursnya. Dan tentu saja harga dalam poin dan langkah harga. Ketika Anda menghitung untung dari transaksi, ini bisa menembak, karena. jika Anda menghitung jumlah total dengan mengalikan harga dengan kuantitas. Di sini Anda perlu berhati-hati. Untuk saat ini, kita akan lihat bagaimana kelanjutannya. Ini berlaku untuk mata uang berjangka, di tempat lain semuanya baik-baik saja dengan ini.
pasar OTC
Pasar ini memiliki banyak kekhasan, jadi mari kita pelajari operasinya secara terpisah.Ketika Anda mulai menyinkronkan operasi, ternyata Anda perlu membawa figi / ticker ke bentuk yang sama untuk mencocokkan instrumen dengan benar. Ketika Anda mulai menyinkronkan ini dengan laporan broker, ternyata tradeID dari transaksi yang sama memiliki huruf di awal transaksi dan tidak ada dalam laporan broker. Oleh karena itu, mereka tidak dapat dibandingkan … ahem-ahem … dengan perbandingan! Saya mencocokkan waktu perdagangan, ticker, dan mencocokkan satu tradeId yang terkandung di yang lain. Benar, saya tidak tahu. Siapa pun yang menghadapi ini dan siapa yang peduli, datanglah ke masalah atau mulai yang baru.
Operasi matematika pada alat
Tidak mungkin, tanpa melihat, untuk melakukan operasi matematika dengan seluruh daftar. Agar tidak menambah hangat menjadi lunak, kami selalu memeriksa mata uang dan memproses hanya jika kami yakin mata uang tersebut cocok, dan poin dikonversi ke mata uang yang diinginkan. Berbekal pengetahuan tentang bekerja dengan nomor bank, kami akan menghitung komisi yang dihabiskan untuk setiap akun. Seperti ini: https://github.com/pskucherov/tcsstat/tree/step4 https://github.com/pskucherov/tcsstat/compare/step3…step4
Layanan mikro sudah siap!
https://github.com/pskucherov/tcsstat Sebagai pekerjaan rumah, Anda dapat memeriksa apakah layanan bekerja dengan koneksi yang lambat, ketika koneksi terputus, ketika Internet terputus, ketika kesalahan atau batas kedaluwarsa dari pihak broker.
Kesimpulan dan rencana untuk masa depan
- Belajar tentang operasi dasar dan bekerja dengan Invest API
- Waktu yang dihabiskan ~ 10 jam
- Tingkat kesulitan ~ junior+ / rendah menengah
Jika Anda terus menyempurnakan layanan mikro, Anda mungkin akan mengalami hal seperti ini
https://opexbot.info
Ini perkembangan saya, bagi mereka yang terlalu malas untuk memahami, menjalankan dan mengandalkan diri sendiri. Saya berencana menambahkan analitik di sana atas permintaan pengguna. Jika Anda menyukai artikel itu, berlanggananlah ke saluran telegram saya .
Полезная статья. Не могу представить, сколько усилий автора потребовалось, чтобы все описать. Благодарю.