Existe um corretor russo - Tinkoff Bank. Agora, aqui está o problema: o corretor não suporta ordens de obter lucro e parar perdas. De todo. Se você quiser se sentir mais conveniente durante a negociação, precisará de alguma solução alternativa para essa situação, até que os desenvolvedores do Tinkoff Bank finalmente liberem essas ordens como o recurso matador. No artigo, mostrarei minha solução alternativa.
update: 2019-03-22, o Broker publicou a plataforma 3.0.0 (uma grande atualização) no Google Play. Os recursos do changelog recebem ordens de lucro / stop loss
Por que eu decidi postar o artigo aqui? Eu suponho que o Tinkoff Bank e seus produtos são bastante populares entre a multidão de TI na Rússia e provavelmente alguns deles têm a mesma necessidade, mas não têm tempo ou disposição para desenvolver uma solução temporária própria. É por isso que compartilho minha solução e o histórico da solução.
Aqui, devo dizer algo sobre soluções alternativas, fornecidas pelo corretor. Primeiro, o corretor tem pedidos limitados. O recurso foi lançado em fevereiro de 2019 (e os clientes esperaram por quase dois anos). Eles apresentam trabalho dentro de um dia útil. Então, você precisa de todos os dias de negociação configurá-los novamente. Mais uma falha: você não pode definir limites como desejar. Existe alguma faixa de preço e você não pode fazer um pedido limite com o preço fora da faixa. E esse intervalo é extremamente estreito. Em um mercado volátil, isso faz você se sentir inconveniente. Por fim, você não pode criar dois pedidos multidirecionais (no meu caso, mesmo o primeiro pedido limite causa uma falha instantânea do aplicativo móvel do broker e o site do broker não fornece esse recurso).
Segundo, o aplicativo móvel do corretor fornece um recurso: você pode assinar a alteração de preço do ativo. Se o limite (absoluto, em preço ou relativo, em porcentagem) for ultrapassado, você receberá uma notificação. Mas, novamente, você não pode criar dois limites para o ativo.
Minha solução alternativa é bastante simples:
- nós temos limites para um ativo. Nós calculamos os limiares. Se os limites forem ultrapassados, fazemos uma ação manual: vender ou comprar para obter, como resultado, lucro ou perda.
- devemos obter uma fonte de dados, para obter o preço real do ativo
- se o limite for ultrapassado, devemos enviar uma notificação.
Embora pareça bastante simples, há alguns detalhes em minha solução que desejo compartilhar e discutir.
1. Embora minha carteira de valores mobiliários tivesse um ativo, os limites foram definidos no script e a pesquisa de ações foi feita de forma clara, simples e não configurável. Foi uma solução ruim, mas rápida e mostrou que a idéia estava certa. Quando recebo novos ativos no portfólio, carreguei nomes de ações, trocas e limites de um arquivo.
2. Meu primeiro ativo foi uma ação estrangeira, e a ação estrangeira poderia ser comprada ou vendida apenas na bolsa de São Petersburgo. Minha primeira pressa foi analisar o
site da bolsa do SPb .
Há uma classificação descendente de volume, por isso foi fácil de analisar, porque meu ativo sempre estava na primeira página. Mas 8 de março estava quebrado. Não sei por que, mas o TSLA apareceu na 25ª página. O paginador deles usa JavaScript para baixar os dados das páginas. Existe uma solução direta: baixe e analise todas as páginas e encontre o ativo. Mas é preciso muito tempo para baixar e analisar mais de 25 páginas em cada loop.
Em vez disso, decidi adicionar como outra fonte de dados o site tradingview.com. Não é necessário analisar muitas páginas para encontrar seu estoque, porque cada ativo tem sua própria página, como esta:
www.tradingview.com/symbols/NASDAQ-TSLAPresumi que agora meus problemas se foram, mas eu estava errado. Os dados nas páginas são carregados e atualizados apenas com JS. Portanto, as solicitações que eu costumava baixar páginas falharam.
Para esse problema, conheço três soluções diferentes:
PyQT, selênio (webdriver) e uma extensão Requests-HTML. Como eu já tenho o módulo Requests no meu projeto, decidi usar o Requests-HTML.
Para minha forte decepção, não foi muito estável, até que encontrei algumas pistas no StackOverFlow e 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 atenção ao tempo limite, bem como às chamadas fechadas (). A maioria dos exemplos não possui esses detalhes e isso pode causar alguns problemas.
3. Agora, quando baixamos as páginas com dados JS, analisamos e decidimos se precisamos enviar uma notificação, existe apenas uma pergunta: 'Como enviamos uma notificação?'. No meu caso, o sms.ru oferece uma API conveniente e 5 SMS grátis por dia. Inscreva-se em um portão de SMS. Crie uma chave de API. A chave é algo como isto:
24A41EA5-EEEE-CCCC-5555-094143C2EDDD
Enviando a função SMS de uma versão anterior da minha solução:
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)
Isso funciona bem. Eu me deparei com a pergunta: e se já enviámos um SMS. A primeira versão não possui verificações, então envia um SMS dentro de cada loop. Novamente e novamente.
Eu adicionei o contador do SMS, que o script verifica antes de chamar send_message.
global sms_counter sms_counter = sms_counter + 1
Ok, entendemos. Mas, à medida que o novo dia surge, surge um novo problema: como liberar o contador de SMS? Ou, na verdade, quando? Vejo três maneiras diferentes: armazenar o contador no DB (mas minha solução, por enquanto, é sem estado), analisar data / hora para liberar o contador entre dias úteis e reiniciar o script em algum momento entre dois dias úteis. Por enquanto, implementei a variante mais recente, mas no futuro eu posso alterá-la.
Minha solução está funcionando agora, você pode baixá-lo no
GitHub .
Para usuários que não sabem como lidar com scripts Python, ofereço uma
solução empacotada para Windows (cortesia de PyInstaller).
TODOs:
- analisar data e hora para liberar os contadores de SMS em vez de reiniciar o script;
- por enquanto é o aplicativo sem estado, quero adicionar um banco de dados;
- após o nº 2, seria bom rastrear um grande aumento ou diminuir o preço do ativo (em relação ao preço de fechamento do dia anterior da operação);
- expandir caminhos de comunicação (Telegram, Viber, chamadas de voz) e provedores (por questões de confiabilidade, desejo adicionar smsc.ru SMS-gate, porque sms.ru fica preso às vezes e não retorna sms_response, embora o SMS seja enviado).