API Tinkov Investissement. Premiers pas

Dès les premiers jours, je suis devenu client de Tinkov Investments.

Et à partir de ce moment, de vagues doutes me tourmentent - le récit personnel reflète-t-il la réalité objective?

Le fait est que j'achète des titres libellés en dollars, mais en LC, les prix de tous les actifs sont affichés en dollars et la valeur totale du portefeuille en roubles.

Et je ne comprends pas si le dollar a augmenté ou suis-je un tel investisseur réussi?

Mais qu'en est-il des commissions, impôts et autres dividendes?

Je voudrais prendre toutes mes transactions et les écrire en FIFO, comme dans la comptabilité des actions ... Et mettre les dividendes reçus en tête, puis déduire les impôts.

Et puis je verrai le résultat que je comprends.

Il s'est avéré que Tinkov dispose d'une API qui vous permet d'écrire des robots de trading (cela ne m'intéresse pas du tout), ainsi que de télécharger des données sur son portefeuille et ses opérations.

Cette API a une description officielle, mais tout n'était pas clair pour moi, je devais la comprendre.
Les résultats de ces confrontations se présentent à votre attention.

Liens utiles: description de l'

API
Une autre description

Obtenir un jeton et installer une bibliothèque


Avant de commencer, vous devez installer la bibliothèque et obtenir un jeton.

Installation de la bibliothèque:

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

Je cite le jeton officiel recevant les instructions:

  1. Connectez-vous à votre compte sur tinkoff.ru
  2. Allez à la section investissement
  3. Aller aux paramètres
  4. La fonction "Confirmation des transactions par code" doit être désactivée
  5. Émettez le jeton OpenApi pour l'échange et le bac à sable. Peut-être que le système vous demandera de vous reconnecter, ne vous inquiétez pas, cela est nécessaire pour connecter le robot à la plateforme de trading.
  6. Copiez le jeton et enregistrez-le, le jeton ne s'affiche qu'une seule fois, vous ne pourrez pas le consulter plus tard, cependant, vous pouvez émettre un nombre illimité de jetons.

Au moment de la rédaction du présent document, le jeton était émis sur la page www.tinkoff.ru/invest/settings , un bouton au bas de la page.

image

J'ai eu des erreurs avec le jeton pour le bac à sable, alors j'ai commencé à expérimenter avec la version de combat. Ce que je vous souhaite (Attention: ne pas acheter, vendre par accident quelque chose en plus).

S'identifier


from openapi_client import openapi

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

Ces deux lignes font tout ce dont nous avons besoin.

Ensuite, nous travaillons avec la variable client.

Que contient notre portefeuille


Obtenez le contenu de notre portfolio:

pf = client.portfolio.portfolio_get()

Voyons les données de base du premier élément:

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)

Dans mon cas, c'est:

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

valeur -
Solde du prix du papier - Le nombre de titres en portefeuille, la valeur et la devise - leur valeur monétaire.

figi - Instrument financier de Global the Identifier (Global Financial Instrument Identifier)
ticker - Ticker asset.

À partir de ces données, nous pouvons trouver le nom lisible par l'homme de l'actif.

Pour cette demande, nous n'en avons pas besoin (voir le champ du nom), mais dans d'autres cas cela sera utile.

Obtenez le nom du journal par FIGI et ticket


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

On a:

{'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'}

Cette fonction API fonctionne pour moi comme il se doit. Nous voyons que «BBG000BWPXQ8» -> «British American Tobacco».

Mais la recherche du nom de l'actif par ticker ne fonctionne pas pour moi: ((((

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

Les développeurs ont suggéré de mettre à jour la bibliothèque, mais même après cela, elle n'a pas décollé.

Téléchargez le répertoire des titres


Cependant, j'ai résolu ce problème radicalement. J'ai téléchargé sur Tinkov un répertoire complet des actifs échangés:

#   
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]
eu
[{'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'}]

Comme vous pouvez le voir, figi et nom sont là. Pour mes besoins - plus que suffisant.

Obtenez une liste des opérations


Mais la chose la plus intéressante est d'obtenir une liste de mes opérations. Les actions suivantes entrent dans l'opération (dans mon cas):

  • PayIn - Réapprovisionnement du compte de courtage
  • PayOut - Retirer de l'argent
  • BuyCard - Achetez à partir d'une carte
  • Vendre - Vendre
  • BrokerCommission - Commission des courtiers
  • Dividende - Paiement du dividende
  • Taxe - Taxes
  • TaxDividend- Taxes sur les dividendes
  • ServiceCommission - Frais de service

Code pour décharger un portfolio:

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())
Voyons ce qui se passe. Dans mon cas, cet élément est intéressant
ops.payload.operations[217]
Voilà ce qu'il est
{'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'}]}

Nous nous intéressons aux domaines:

  • date - date de transaction
  • figi - code d'actif
  • operation_type - type d'opération
  • paiement - le montant de la transaction. Pour les taxes ou commissions, c'est elle qui est indiquée. prix sans
  • prix - prix d'un papier
  • quantité - montant prévu de titres
  • métiers - offres de change réelles

La question s'est immédiatement posée - pourquoi avons-nous besoin de certains métiers s'il y a des prix et des quantités?

Tout n'est pas si simple (plan et fait)


Si je comprends bien, la quantité indique le nombre de papiers que je voulais acheter. Et ce qui est réellement acheté réside dans les échanges [i] .quantité.

Ceux. si vous voulez vous tourner vers des transactions réelles, vous devez trier ce qui se trouve dans les métiers.

Dans certains cas, il n'y en a pas - par exemple, pour les taxes ou les dépôts / retraits de fonds.

Pour obtenir des chiffres réels, vous devez regarder les transactions et échanger des transactions:

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