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ô.
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 order
A 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)
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 enviaPOST
O serviço de acompanhamento deve acompanharPOST
O 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_key
esecret_key
A Comissão considera que a utilização deaccess_key
esecret_key
emWebHook
As 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.
UtilizaçãowexApp
para simular o teste de mercado real.
Endereço completo da estratégia:https://www.fmz.com/strategy/221850
Oaccess_key
esecret_key
No âmbito do regime, são apenas para identificação e não há garantia para a utilizaçãohttp
Esta solução é apenas uma ideia e uma introdução.https
A comunicação deve ser utilizada.