Tinkov API. Investasi. Langkah pertama

Hampir sejak hari-hari pertama saya menjadi klien Tinkov.

Dan sejak saat itu, keraguan samar menyiksaku - apakah catatan pribadi mencerminkan realitas objektif?

Faktanya adalah saya membeli sekuritas dalam mata uang dolar, tetapi dalam LC harga semua aset ditampilkan dalam dolar, dan total nilai portofolio dalam rubel.

Dan saya tidak mengerti apakah dolar telah tumbuh atau apakah saya investor yang sukses?

Tetapi bagaimana dengan komisi, pajak, dan dividen lainnya?

Saya ingin mengambil semua transaksi saya dan menuliskannya di FIFO, seperti dalam akuntansi saham ... Dan menempatkan dividen yang diterima di atas, dan kemudian memotong pajak.

Dan kemudian saya akan melihat hasil yang saya mengerti.

Ternyata Tinkov memiliki API yang memungkinkan Anda untuk menulis robot perdagangan (saya sama sekali tidak tertarik dengan ini), serta mengunggah data pada portofolio dan operasinya.

API ini memiliki deskripsi resmi, tetapi tidak semuanya jelas bagi saya, saya harus memahaminya.
Hasil dari pertikaian ini hadir untuk perhatian Anda.

Tautan yang berguna: Deskripsi

API
Deskripsi lain

Mendapatkan token dan menginstal perpustakaan


Sebelum Anda mulai, Anda perlu menginstal perpustakaan dan mendapatkan token.

Instalasi Perpustakaan:

pip install -i https://test.pypi.org/simple/ --extra-index-url=https://pypi.org/simple/ tinkoff-invest-openapi-client

Saya mengutip token resmi yang menerima instruksi:

  1. Masuk ke akun Anda di tinkoff.ru
  2. Buka bagian investasi
  3. Pergi ke pengaturan
  4. Fungsi "Konfirmasi transaksi dengan kode" harus dinonaktifkan
  5. Keluarkan token OpenApi untuk pertukaran dan Sandbox. Mungkin sistem akan meminta Anda untuk login lagi, jangan khawatir, ini perlu untuk menghubungkan robot ke platform perdagangan.
  6. Salin token dan simpan, token hanya ditampilkan sekali, Anda tidak akan dapat melihatnya nanti, namun, Anda dapat mengeluarkan token yang jumlahnya tidak terbatas.

Pada saat penulisan, token dikeluarkan pada halaman www.tinkoff.ru/invest/settings , sebuah tombol di bagian bawah halaman.

gambar

Saya memiliki kesalahan dengan token untuk kotak pasir, jadi saya mulai bereksperimen dengan versi tempur. Apa yang saya inginkan (Perhatian: jangan membeli, menjual secara tidak sengaja sesuatu yang ekstra).

Gabung


from openapi_client import openapi

token = '    '  
client = openapi.api_client(token)

Dua baris ini melakukan semua yang kita butuhkan.

Selanjutnya kita bekerja dengan variabel klien.

Apa yang ada di portofolio kami


Dapatkan isi portofolio kami :

pf = client.portfolio.portfolio_get()

Mari kita lihat data dasar elemen pertama:

print('value:', pf.payload.positions[0].average_position_price.value)
print('currency:', pf.payload.positions[0].average_position_price.currency)
print('balance:', pf.payload.positions[0].balance)
print('figi:', pf.payload.positions[0].figi)
print('ticker:', pf.payload.positions[0].ticker)
print('name:', pf.payload.positions[0].name)

Dalam kasus saya, ini adalah:

value: 45.98
currency: USD
balance: 21.0
figi: BBG000BWPXQ8
ticker: BTI
name: British American Tobacco

value -
Saldo harga kertas - Jumlah sekuritas dalam portofolio, nilai dan mata uang - nilai moneternya.

figi - instrumen Keuangan Global the Identifier (Global Financial Instrument Identifier)
ticker - Ticker asset.

Dari data ini, kita dapat mengetahui nama aset yang dapat dibaca manusia.

Untuk permintaan ini, kami tidak memerlukan ini (lihat bidang nama), tetapi dalam kasus lain akan berguna.

Dapatkan nama kertas dengan FIGI dan tiket


#    FIGI
instr = client.market.market_search_by_figi_get('BBG000BWPXQ8') 
instr

Kita mendapatkan:

{'payload': {'currency': 'USD',
             'figi': 'BBG000BWPXQ8',
             'isin': 'US1104481072',
             'lot': 1,
             'min_price_increment': 0.01,
             'name': 'British American Tobacco',
             'ticker': 'BTI',
             'type': 'Stock'},
 'status': 'Ok',
 'tracking_id': 'a1979917d2141916'}

Fungsi API ini berfungsi untuk saya sebagaimana mestinya. Kita melihat bahwa 'BBG000BWPXQ8' -> 'British American Tobacco'.

Tetapi pencarian untuk nama aset oleh ticker tidak berhasil untuk saya: (((

instr = client.market.market_search_by_ticker_get('BTI' ) 
print(instr)

Pengembang menyarankan memperbarui perpustakaan, tetapi bahkan setelah itu tidak lepas landas.

Unduh direktori efek


Namun, saya menyelesaikan masalah ini secara radikal. Saya mengunduh dari Tinkov direktori lengkap aset yang diperdagangkan:

#   
bonds = client.market.market_bonds_get() 

#   ETF
etfs = client.market.market_etfs_get() 

#   
stocks = client.market.market_stocks_get() 

instr_list = bonds.payload.instruments + etfs.payload.instruments + stocks.payload.instruments

instr_list[:3]
dapatkan
[{'currency': 'RUB',
  'figi': 'BBG00844BD08',
  'isin': 'RU000A0JU898',
  'lot': 1,
  'min_price_increment': 0.1,
  'name': '  9',
  'ticker': 'RU000A0JU898'}, {'currency': 'RUB',
  'figi': 'BBG00R05JT04',
  'isin': 'RU000A1013Y3',
  'lot': 1,
  'min_price_increment': 0.1,
  'name': ' \xa02',
  'ticker': 'RU000A1013Y3'}, {'currency': 'RUB',
  'figi': 'BBG00PNLY692',
  'isin': 'RU000A100DC4',
  'lot': 1,
  'min_price_increment': 0.1,
  'name': '- 002P  2',
  'ticker': 'RU000A100DC4'}]

Seperti yang Anda lihat, figi dan nama ada di sana. Untuk tujuan saya - lebih dari cukup.

Dapatkan daftar operasi


Tetapi hal yang paling menarik adalah mendapatkan daftar operasi saya. Tindakan berikut termasuk dalam operasi (dalam kasus saya):

  • PayIn - pengisian akun Broker
  • PayOut - Menarik Uang
  • BuyCard - Beli dari kartu
  • Jual - Jual
  • Komisi Pialang - Komisi Pialang
  • Dividen - Pembayaran Dividen
  • Pajak - Pajak
  • TaxDividend- Dividend Taxes
  • ServiceCommission - Biaya Layanan

Kode untuk menurunkan portofolio:

from datetime import datetime
from pytz import timezone

#     30  2016 (      )
d1 = datetime(2016, 9, 30, 0, 0, 0, tzinfo=timezone('Europe/Moscow'))  # timezone  .  - 
d2 = datetime.now(tz=timezone('Europe/Moscow'))  #   
ops = client.operations.operations_get(_from=d1.isoformat(), to=d2.isoformat())
Mari kita lihat apa yang terjadi. Dalam kasus saya, elemen ini menarik
ops.payload.operations[217]
Itulah dia
{'commission': {'currency': 'USD', 'value': -0.42},
 'currency': 'USD',
 'date': datetime.datetime(2018, 11, 7, 10, 55, 53, 648913, tzinfo=tzoffset(None, 10800)),
 'figi': 'BBG000PSKYX7',
 'id': '42281525510',
 'instrument_type': 'Stock',
 'is_margin_call': False,
 'operation_type': 'BuyCard',
 'payment': -141.05,
 'price': 141.05,
 'quantity': 4,
 'status': 'Done',
 'trades': [{'date': datetime.datetime(2018, 11, 7, 10, 55, 53, 648913, tzinfo=tzoffset(None, 10800)),
             'price': 141.05,
             'quantity': 1,
             'trade_id': '42636800'}]}

Kami tertarik pada bidang:

  • tanggal - tanggal transaksi
  • kode aset - figi
  • operation_type - jenis operasi
  • pembayaran - jumlah transaksi. Untuk pajak atau komisi, itu yang ditunjukkannya. harga sementara Tidak ada
  • harga - harga satu kertas
  • kuantitas - jumlah sekuritas yang direncanakan
  • perdagangan - transaksi pertukaran riil

Pertanyaan segera muncul - mengapa kita perlu perdagangan jika ada harga dan kuantitas?

Semuanya tidak begitu sederhana (rencana dan fakta)


Seperti yang saya pahami, kuantitas menunjukkan jumlah kertas yang ingin saya beli. Dan apa yang sebenarnya dibeli terletak pada perdagangan [i]. Jumlah.

Itu jika Anda ingin beralih ke transaksi aktual, Anda perlu memilah apa yang ada dalam perdagangan.

Dalam beberapa kasus, tidak ada - misalnya, untuk pajak atau setoran / penarikan dana.

Untuk mendapatkan bilangan real, Anda perlu melihat transaksi dan bertukar transaksi:

for op in ops.payload.operations: #  
    print(op.figi) # figi    
    print(op.operation_type)   #    
    if op.trades == None:      #    
        print('price:', op.price)       #     
        print('payment:', op.payment)   #  
        print('quantity:', op.quantity) #   
    else:     
        for t in op.trades:                   #     -   
            print('price:', t.price)          #     
            print('quantity:', t.quantity)
    print('--------------')

All Articles