Hay un corredor ruso: Tinkoff Bank. Ahora aquí está el problema: el corredor no admite las órdenes de tomar ganancias y detener las pérdidas. En absoluto Si desea sentirse más conveniente mientras opera, entonces necesita alguna solución para esta situación, hasta que los desarrolladores de Tinkoff Bank finalmente publiquen esas órdenes como la característica asesina. En el artículo, te mostraré mi solución.
actualización: 2019-03-22, el Broker publicó la plataforma 3.0.0 (una actualización importante) en Google Play. Las características del registro de cambios toman órdenes de ganancias / stop loss
¿Por qué decidí publicar el artículo aquí? Tengo la suposición de que Tinkoff Bank y sus productos son bastante populares entre la multitud de TI en Rusia y probablemente algunos de ellos tienen la misma necesidad, pero no tienen suficiente tiempo o voluntad para desarrollar su propia solución temporal. Es por eso que comparto mi solución y el historial de la solución.
Aquí debería decir algo sobre soluciones provisionales, que son proporcionadas por el corredor. Primero, el corredor tiene órdenes limitadas. La función se lanzó en febrero de 2019 (y los clientes la esperaron durante casi dos años). Cuentan con trabajar dentro de un día comercial. Por lo tanto, necesita que cada día de negociación los establezca de nuevo. Una falla más: no puedes establecer límites como desees. Hay un rango de precios y no puede hacer una orden de límite con un precio fuera del rango. Y este rango es extremadamente estrecho. En un mercado volátil, te hace sentir incómodo. Finalmente, no puede crear dos órdenes multidireccionales (en mi caso, incluso la primera orden límite causa un bloqueo instantáneo de la aplicación móvil del corredor y el sitio del corredor no proporciona esta función).
En segundo lugar, la aplicación móvil del corredor proporciona una función: puede suscribirse a los cambios de precio del activo. Si se supera el umbral (absoluto, en precio o relativo, en porcentaje), recibirá una notificación. Pero, de nuevo, no puede crear dos umbrales para el activo.
Mi solución es bastante simple:
- Tenemos umbrales para un activo. Calculamos umbrales nosotros mismos. Si se superan los umbrales, realizamos una acción manual: vender o comprar para obtener, como resultado, ganancias o pérdidas.
- debemos obtener una fuente de datos, para obtener el precio real del activo
- Si se supera el umbral, debemos enviar una notificación.
Si bien parece bastante simple, hay algunos detalles en mi solución que quiero compartir y discutir.
1. Si bien mi cartera de valores tenía un activo, los umbrales se definieron en el script y la búsqueda de acciones se hizo sencilla, simple y nada configurable. Fue una mala solución, pero rápida y demostró que la idea era correcta. Cuando obtengo nuevos activos en la cartera, cargué nombres de acciones, intercambios, umbrales desde un archivo.
2. Mi primer activo fue una acción extranjera, y la acción extranjera solo se podía comprar o vender en el intercambio de San Petersburgo. Mi primer apuro fue analizar el
sitio del intercambio SPb .
Hay un orden descendente de volumen, por lo que fue fácil de analizar, porque mi activo siempre estaba en la primera página. Pero el 8 de marzo estaba roto. No sé por qué, pero TSLA apareció en una página 25. Su paginador usa JavaScript para descargar los datos de las páginas. Hay una solución directa: descargue y analice todas las páginas y encuentre el activo. Pero se necesita mucho tiempo para descargar y analizar más de 25 páginas dentro de cada ciclo.
En lugar de eso, decidí agregar como otra fuente de datos el sitio tradingview.com. No es necesario analizar muchas páginas para encontrar su stock, porque cada activo tiene su propia página, como esta:
www.tradingview.com/symbols/NASDAQ-TSLASupuse que ahora mis problemas se habían ido, pero estaba equivocado. Los datos en las páginas se cargan y actualizan solo con JS. Entonces, las solicitudes que solía descargar páginas fallaron.
Para este problema conozco tres soluciones diferentes:
PyQT, selenium (webdriver) y una extensión Requests-HTML. Como ya tengo el módulo Solicitudes en mi proyecto, decidí usar Solicitudes-HTML.
Para mi gran decepción, no fue muy estable, hasta que encontré algunas pistas en StackOverFlow y tal.
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()
Preste atención al tiempo de espera, así como a las dos llamadas cercanas (). La mayoría de los ejemplos carecen de estos detalles, y podrían surgir algunos problemas.
3. Ahora, cuando hemos descargado páginas con datos de JS, las analizamos y decidimos si necesitamos enviar una notificación, solo hay una pregunta: "¿Cómo enviamos una notificación?". En mi caso, sms.ru ofrece una API conveniente y 5 SMS gratis por día. Regístrese en una puerta de SMS. Crea una clave API. La clave algo como esto:
24A41EA5-EEEE-CCCC-5555-094143C2EDDD
Envío de la función SMS desde una versión anterior de mi solución:
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)
Funciona bien Me encontré con la pregunta: ¿qué pasa si ya enviamos un SMS? La primera versión carece de controles, por lo que envía un SMS dentro de cada bucle. Una y otra vez
Agregué el contador de SMS, que el script comprueba antes de llamar a send_message.
global sms_counter sms_counter = sms_counter + 1
De acuerdo, lo tenemos. Pero a medida que surja un nuevo día, surge un nuevo problema: ¿cómo vaciar el contador de SMS? O, en realidad, ¿cuándo? Veo tres formas diferentes: almacenar el contador en DB (pero mi solución, por ahora, no tiene estado), analizar la fecha / hora para vaciar el contador entre días comerciales y reiniciar el script en algún momento entre dos días comerciales. Por ahora, implementé la última variante, pero en el futuro, podría cambiarla.
Mi solución ahora funciona, puedes descargarla desde
GitHub .
Para los usuarios que no saben cómo manejar los scripts de Python, ofrezco una
solución empaquetada para Windows (cortesía de PyInstaller).
TODOS:
- analizar la fecha y hora para eliminar los contadores de SMS en lugar de reiniciar el script;
- por ahora es la aplicación sin estado, quiero agregar una base de datos;
- después del n. ° 2, sería bueno realizar un seguimiento de un gran aumento o disminución del precio del activo (en relación con el precio de cierre del día comercial anterior);
- expandir las vías de comunicación (Telegram, Viber, llamadas de voz) y proveedores (para fines de confiabilidad, quiero agregar smsc.ru SMS-gate, porque sms.ru se atasca a veces y no devuelve sms_response, aunque se envía un SMS).