Alarme TradingViewWebHook ligado diretamente ao robô FMZ

Autora:Bem-estar, Criado: 2020-08-07 10:44:17, Atualizado: 2023-10-10 21:09:42

img

Recentemente, cada vez mais utilizadores do TradingView ligaram o sinal do gráfico TradingView à plataforma FMZ (FMZ.COMOs indicadores podem ser usados para negociação programática e automatizada, o que reduz as barreiras para o desenvolvimento de muitas negociações programáticas e quantitativas.TradingViewWebHook.

A solução anterior:https://www.fmz.com/digest-topic/5533.

O plano anterior era estender a interface API da plataforma FMZ para enviar instruções para o robô. Hoje, vamos dar uma olhada em outra solução. Deixe que o pedido de WebHook do alerta TradingView seja enviado diretamente para o robô da plataforma FMZ, para que ele possa enviar diretamente instruções e encomendar transações do robô.

Código fonte da estratégia do robô

A estratégia é escrita em Python. Após o robô ser criado e começar a usar essa estratégia, o robô criará um thread, que iniciará um serviço para monitorar a porta definida. Aguardando solicitações externas e processamento. Quando eu o testei, ele foi testado pelo host no servidor, e o dispositivo onde o host está localizado deve ser acessível de fora. Quando o robô executa a transação, ele usa a interface de ordem de mercado. além disso, essa estratégia também pode ser modificada para implementar olimit orderA fim de ser fácil de entender e simplificado, a ordem de mercado é usada aqui, de modo que a troca deve apoiar a ordem de mercado.

'''
Request format: http://x.x.x.x:xxxx/data?access_key=xxx&secret_key=yyy&type=buy&amount=0.001
Strategy robot parameters:
- Type: Encrypted string, AccessKey, SecretKey, you can use the low-privileged API KEY of the FMZ platform, or you can generate the KEY yourself.
- Type: string, contract ID, ContractType
- Type: numeric value, port number, Port
'''

import _thread
import json
from http.server import HTTPServer, BaseHTTPRequestHandler
from urllib.parse import parse_qs, urlparse

def url2Dict(url):
    query = urlparse(url).query  
    params = parse_qs(query)  
    result = {key: params[key][0] for key in params}  
    return result

class Executor(BaseHTTPRequestHandler):
    def do_POST(self):
        try:
            self.send_response(200)
            self.send_header("Content-type", "application/json")
            self.end_headers()
            dictParam = url2Dict(self.path)
            
            # check
            if len(dictParam) == 4 and dictParam["access_key"] == AccessKey and dictParam["secret_key"] == SecretKey:
                del dictParam["access_key"]
                del dictParam["secret_key"]
                Log("Request received", "parameter:", dictParam, "#FF0000")
                '''
                map[access_key:xxx amount:0.001 secret_key:yyy type:buy]
                '''
                isSpot = True
                if exchange.GetName().find("Futures") != -1:
                    if ContractType != "":
                        exchange.SetContractType(ContractType)
                        isSpot = False 
                    else :
                        raise "No futures contract set"
                
                if isSpot and dictParam["type"] == "buy":
                    exchange.Buy(-1, float(dictParam["amount"]))
                    Log(exchange.GetAccount())
                elif isSpot and dictParam["type"] == "sell":
                    exchange.Sell(-1, float(dictParam["amount"]))
                    Log(exchange.GetAccount())
                elif not isSpot and dictParam["type"] == "long":
                    exchange.SetDirection("buy")
                    exchange.Buy(-1, float(dictParam["amount"]))
                    Log("Holding Position:", exchange.GetPosition())
                elif not isSpot and dictParam["type"] == "short":
                    exchange.SetDirection("sell")
                    exchange.Sell(-1, float(dictParam["amount"]))
                    Log("Holding Position:", exchange.GetPosition())
                elif not isSpot and dictParam["type"] == "cover_long":
                    exchange.SetDirection("closebuy")
                    exchange.Sell(-1, float(dictParam["amount"]))
                    Log("Holding Position:", exchange.GetPosition())
                elif not isSpot and dictParam["type"] == "cover_short":
                    exchange.SetDirection("closesell")
                    exchange.Buy(-1, float(dictParam["amount"]))
                    Log("Holding Position:", exchange.GetPosition())
            
            # Write data response
            self.wfile.write(json.dumps({"state": "ok"}).encode())
        except Exception as e:
            Log("Provider do_POST error, e:", e)


def createServer(host):
    try:
        server = HTTPServer(host, Executor)
        Log("Starting server, listen at: %s:%s" % host)
        server.serve_forever()
    except Exception as e:
        Log("createServer error, e:", e)
        raise Exception("stop")

def main():
    # Start a thread
    try:
        _thread.start_new_thread(createServer, (("0.0.0.0", Port), ))         # Test on VPS server        
    except Exception as e:        
        Log("Error message:", e)
        raise Exception("stop")    
    Log("Account asset information:", _C(exchange.GetAccount))
    while True:
        LogStatus(_D())
        Sleep(2000)

Parâmetros da estratégia:

img

Pedido de alerta do TradingView para o WebHook

A configuração do pedido de alarme é:

http://xxx.xxx.xxx.xxx:80/data?access_key=e3809e173e23004821a9bfb6a468e308&secret_key=45a811e0009d91ad21154e79d4074bc6&type=sell&amount=0.1

Desde que o TradingView enviaPOSTO serviço de acompanhamento deve acompanharPOSTO TradingView permite apenas a porta 80 para ohttp protocol.

  • xxx.xxx.xxx.xxxÉ o endereço IP do dispositivo do host onde o robô está localizado.

  • Oaccess_keyesecret_keyA Comissão considera que a utilização deaccess_keyesecret_keyemWebHookAs solicitações de alarme são as mesmas que as configuradas nos parâmetros do robô.

  • Type, direção de negociação, compra ou venda, abertura ou fechamento, note que os pontos e futuros são distinguidos.

  • amount, o número de operações.

Teste de execução

UtilizaçãowexApppara simular o teste de mercado real.

img img

Fim de ano

Endereço completo da estratégia:https://www.fmz.com/strategy/221850

Oaccess_keyesecret_keyNo âmbito do regime, são apenas para identificação e não há garantia para a utilizaçãohttpEsta solução é apenas uma ideia e uma introdução.httpsA comunicação deve ser utilizada.


Mais.