Notifications: action requise pour prendre un profit / stop loss. Dans le cas où votre courtier ne prend pas en charge ces ordres

Il y a un courtier russe - Tinkoff Bank. Maintenant, voici le problème: le courtier ne prend pas en charge les ordres de prise de profit et d'arrêt de perte. Du tout. Si vous souhaitez vous sentir plus à l'aise lors de la négociation, vous avez besoin d'une solution de contournement pour cette situation, jusqu'à ce que les développeurs de Tinkoff Bank publient enfin ces ordres comme fonctionnalité de tueur. Dans l'article, je vais vous montrer ma solution de contournement.
mise à jour: 2019-03-22, la plateforme publiée par Broker 3.0.0 (une mise à jour majeure) dans Google Play. Les fonctionnalités du journal des modifications prennent des ordres de profit / stop loss

Pourquoi ai-je décidé de publier l'article ici? Je suppose que Tinkoff Bank et ses produits sont très populaires parmi les informaticiens en Russie et que certains d'entre eux ont probablement les mêmes besoins mais n'ont pas assez de temps ou de volonté pour développer leur propre solution de contournement temporaire. C'est pourquoi je partage ma solution et l'historique de la solution.

Ici, je devrais dire quelque chose sur les solutions de contournement, qui sont fournies par le courtier. Premièrement, le courtier a des ordres à cours limité. La fonctionnalité a été publiée en février 2019 (et les clients l'ont attendue pendant près de deux ans). Ils proposent de travailler dans un jour ouvrable. Ainsi, vous avez besoin de chaque jour de négociation de les remettre à zéro. Encore un défaut: vous ne pouvez pas fixer de limites comme vous le souhaitez. Il existe une certaine fourchette de prix et vous ne pouvez pas passer une commande à cours limité avec un prix hors de la fourchette. Et cette gamme est extrêmement étroite. Sur un marché volatil, cela vous met mal à l'aise. Enfin, vous ne pouvez pas créer deux commandes multidirectionnelles (dans mon cas, même la première commande à cours limité provoque un crash instantané de l'application mobile du courtier et le site du courtier ne fournit pas cette fonctionnalité).

Deuxièmement, l'application mobile du courtier offre une fonctionnalité: vous pouvez vous abonner à l'évolution du prix de l'actif. Si le seuil (absolu, en prix ou relatif, en pourcentage) est dépassé, vous recevrez une notification. Mais encore une fois, vous ne pouvez pas créer deux seuils pour l'actif.

Ma solution de contournement est assez simple:

  1. nous avons des seuils pour un actif. Nous calculons nous-mêmes les seuils. Si les seuils sont dépassés, nous effectuons une action manuelle: vendre ou acheter pour obtenir, par conséquent, un profit ou une perte.
  2. nous devons obtenir une source de données, pour obtenir le prix réel de l'actif
  3. si le seuil est franchi, nous devons envoyer une notification.

Bien que cela semble assez simple, il y a quelques détails dans ma solution que je veux partager et discuter.

1. Alors que mon portefeuille de titres avait un actif, des seuils ont été définis dans le script et la recherche d'actions a été rendue simple, simple et non configurable du tout. C'était une mauvaise solution, mais rapide et a montré que l'idée était bonne. Lorsque j'obtiens de nouveaux actifs dans le portefeuille, je fais le chargement des noms de stock, des échanges, des seuils à partir d'un fichier.

2. Mon premier actif était une action étrangère, et l'action étrangère ne pouvait être achetée ou vendue qu'en échange à Saint-Pétersbourg. Ma première ruée a été d'analyser le site de l'échange SPb .

Il y a un tri par volume décroissant, donc c'était facile à analyser, car mon actif était toujours sur la première page. Mais le 8 mars, il était cassé. Je ne sais pas pourquoi, mais TSLA est apparu sur une 25e page. Leur paginateur utilise JavaScript pour télécharger les données des pages. Il existe une solution simple: téléchargez et analysez toutes les pages et trouvez l'actif. Mais il faut beaucoup de temps pour télécharger et analyser plus de 25 pages dans chaque boucle.

Au lieu de cela, j'ai décidé d'ajouter comme autre source de données le site tradingview.com. Il n'est pas nécessaire d'analyser beaucoup de pages pour trouver votre stock, car chaque actif a sa propre page, comme celle-ci:
www.tradingview.com/symbols/NASDAQ-TSLA

J'ai supposé que maintenant mes problèmes avaient disparu, mais j'avais tort. Les données sur les pages se chargent et se mettent à jour uniquement avec JS. Ainsi, les demandes que j'ai utilisées pour télécharger des pages ont échoué.

Pour ce problème, je connais trois solutions différentes:

PyQT, sélénium (webdriver) et une extension Requests-HTML. Parce que j'ai déjà un module Requests dans mon projet, j'ai décidé d'utiliser Requests-HTML.

Pour ma forte déception, ce n'était pas très stable, jusqu'à ce que je trouve des indices sur StackOverFlow et autres.

session = HTMLSession() r = session.get(url) my = r.html.render(timeout=30) selector = 'span.tv-symbol-header-quote__value.tv-symbol-header-quote__value--large.js-symbol-last' price = r.html.find(selector)[0].text r.close() session.close() 

Faites attention au timeout, ainsi qu'aux deux appels close (). La plupart des exemples manquent de ces détails, et cela pourrait poser quelques problèmes.

3. Maintenant, lorsque nous avons téléchargé des pages avec des données JS, les avons analysées et décidé, si nous devons envoyer une notification, il n'y a qu'une question: «Comment envoyer une notification?». Dans mon cas, sms.ru propose une API pratique et 5 SMS gratuits par jour. Inscrivez-vous sur une porte SMS. Créez une clé API. La clé quelque chose comme ça:

 24A41EA5-EEEE-CCCC-5555-094143C2EDDD 

Envoi de la fonction SMS à partir d'une version antérieure de ma solution:

 def send_message(mymessage): sms_url = 'https://sms.ru/sms/send?api_id=key&to=number&msg=message&json=1' sms_url = sms_url.replace('key', mykey) sms_url = sms_url.replace('number', mynumber) sms_url = sms_url.replace('message', mymessage) sms_response = requests.get(sms_url) 

Ça marche bien. Je suis tombé sur la question: et si nous avions déjà envoyé un SMS. La première version n'a aucun contrôle, elle envoie donc un SMS dans chaque boucle. Encore et encore.

J'ai ajouté le compteur SMS, que le script vérifie avant d'appeler send_message.

  global sms_counter sms_counter = sms_counter + 1 

D'accord, nous l'avons. Mais au fur et à mesure que le jour se lève, un nouveau problème se pose: comment vider le compteur SMS? Ou, en fait, quand? Je vois trois façons différentes: stocker le compteur dans DB (mais ma solution, pour l'instant, est sans état), analyser la date / heure pour vider le compteur entre les jours de bourse et redémarrer le script à un moment donné entre deux jours de bourse. Pour l'instant, j'ai implémenté la dernière variante, mais à l'avenir, je pourrai la changer.

Ma solution fonctionne maintenant, vous pouvez la télécharger depuis GitHub .

Pour les utilisateurs qui ne savent pas comment gérer les scripts Python, je propose une solution packagée pour Windows (gracieuseté de PyInstaller).

TODO:

  1. analyser la date et l'heure pour vider les compteurs SMS au lieu de redémarrer le script;
  2. pour l'instant c'est l'application sans état, je veux ajouter une base de données;
  3. après # 2, il serait bien de suivre une forte augmentation ou diminution du prix de l'actif (par rapport au cours de clôture de la précédente journée de négoce);
  4. étendre les voies de communication (Telegram, Viber, appels vocaux) et les fournisseurs (pour des raisons de fiabilité, je veux ajouter smsc.ru SMS-gate, car sms.ru est parfois bloqué et ne renvoie pas sms_response, bien que des SMS soient envoyés).

Source: https://habr.com/ru/post/fr443434/


All Articles