TradingViewWebHook estratégia de conexão direta

Autora:Sonhos pequenos, Data: 08.03.2020 às 09:58:19
Tags:

Artigo relacionado:https://www.fmz.com/bbs-topic/5969

Como o servidor HTTPS tem algumas falhas em si, considere usar o ThreadingHTTPServer em vez disso. Referências:https://docs.python.org/3.7/library/http.server.htmlO Python 3.7 é necessário.

Informações sobre o problema do HTTPServer:https://www.zybuluo.com/JunQiu/note/1350528


'''
请求格式:http://x.x.x.x:xxxx/data?access_key=xxx&secret_key=yyy&type=buy&amount=0.001
策略机器人参数:
- 类型:加密字符串,AccessKey , SecretKey ,可以用FMZ平台的低权限的API KEY,或者自己生成KEY也可以。
- 类型:字符串,合约ID,ContractType
- 类型:数值,端口号,Port
'''

import re
import _thread
import json
from http.server import ThreadingHTTPServer, 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_GET(self):
        try:
            dictParam = url2Dict(self.path)
            Log("测试", dictParam)
        except Exception as e:
            Log("Provider do_GET error, e:", e)
    def do_POST(self):
        try:
            self.send_response(200)
            self.send_header("Content-type", "application/json")
            self.end_headers()
            dictParam = url2Dict(self.path)
            
            # 测试POST请求Body信息            
            data = self.rfile.read(200)   # 指定了读取长度
            Log("data:", data)            # 打印POST请求的数据,可以根据请求中的数据具体再让机器人执行对应的操作
            
            # 校验
            if len(dictParam) == 4 and dictParam["access_key"] == AccessKey and dictParam["secret_key"] == SecretKey:
                del dictParam["access_key"]
                del dictParam["secret_key"]
                Log("接收到请求", "参数:", 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 "未设置期货合约"
                                
                q = None
                if exchange.GetName() == "Futures_CTP" and UseMarketOrderForCTP == False:
                    q = ext.NewTaskQueue()
                
                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")
                    if not q:
                        exchange.Buy(-1, float(dictParam["amount"]))
                    else :
                        q.pushTask(exchange, ContractType, "buy", float(dictParam["amount"]), lambda task, ret: Log(task["desc"], ret, "#FF0000"))
                    Log("持仓:", exchange.GetPosition())
                elif not isSpot and dictParam["type"] == "short":
                    exchange.SetDirection("sell")
                    if not q:
                        exchange.Sell(-1, float(dictParam["amount"]))
                    else :
                        q.pushTask(exchange, ContractType, "sell", float(dictParam["amount"]), lambda task, ret: Log(task["desc"], ret, "#FF0000"))
                    Log("持仓:", exchange.GetPosition())
                elif not isSpot and dictParam["type"] == "cover_long":
                    exchange.SetDirection("closebuy")
                    if not q:
                        exchange.Sell(-1, float(dictParam["amount"]))
                    else :
                        q.pushTask(exchange, ContractType, "closebuy", float(dictParam["amount"]), lambda task, ret: Log(task["desc"], ret, "#FF0000"))
                    Log("持仓:", exchange.GetPosition())
                elif not isSpot and dictParam["type"] == "cover_short":
                    exchange.SetDirection("closesell")
                    if not q:
                        exchange.Buy(-1, float(dictParam["amount"]))
                    else :
                        q.pushTask(exchange, ContractType, "closesell", float(dictParam["amount"]), lambda task, ret: Log(task["desc"], ret, "#FF0000"))
                    Log("持仓:", exchange.GetPosition())
                
                if q is not None:
                    while q.size() > 0:
                        q.poll()
                        Sleep(500)
            
            # 处理body数据
            if isDealBodyMsg:
                if exchange.GetName().find("Futures") != -1:
                    Log("data:", data.decode('utf-8'))  # 测试
                    if re.search(r'buy', data.decode('utf-8')):
                        Log("触发buy")
                        exchange.SetContractType(ct)
                        exchange.SetDirection("buy")
                        exchange.Buy(-1, amount)
                    elif re.search(r'sell', data.decode('utf-8')):
                        Log("触发sell")
                        exchange.SetContractType(ct)
                        exchange.SetDirection("sell")
                        exchange.Sell(-1, amount)
            
            # 写入数据应答
            self.wfile.write(json.dumps({"state": "ok"}).encode())
        except Exception as e:
            Log("Provider do_POST error, e:", e)


def createServer(host):
    try:
        server = ThreadingHTTPServer(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():
    # 开启一个线程
    try:
        _thread.start_new_thread(createServer, (("0.0.0.0", Port), ))         # VPS服务器上测试           
    except Exception as e:        
        Log("错误信息:", e)
        raise Exception("stop")    
    if exchange.GetName().find("Futures") != -1:
        exchange.SetContractType(ContractType)
    Log("账户资产信息:", _C(exchange.GetAccount))
    while True:
        if exchange.GetName() == "Futures_CTP":
            if exchange.IO("status"):
                LogStatus(_D(), "CTP连接")
            else:
                LogStatus(_D(), "CTP未连接")
        else:
            LogStatus(_D())
        Sleep(2000)

Mais.

ETH8888/upload/asset/2457669d9c32568732cb7.jpg Abra o disco real e este erro é sugerido, onde está errado

ETH8888/upload/asset/2457669d9c32568732cb7.jpg Abra o disco real e este erro é sugerido, onde está errado

A espada de Hu YanshanT: Posso enviar uma mensagem?

A espada de Hu Yanshan2021/11/21 11:53:33 CMD 199866 buy=0.1, o administrador recebeu esta mensagem, mas não há nenhuma ação no robô

superãoSe você não entendeu, pode traduzir?

O que é isso?Pode-se escrever um exemplo de uma lista completa de sinais de televisão, como obter informações dentro do corpo.

DietQuantProfessor, como mudar para aumentar a moeda binária no disco único?

Sonhos custam oito dígitosMeu Deus, você pode fazer uma simulação de OKv5?

SssxxxdPor favor, professor, uma pergunta: a versão 3.7 é a versão do administrador de implementação? 2021-08-11 11:08:55 Erro Traceback (most recent call last): File "", line 999, in __init_ctx__ File "", line 4, in ImportError: cannot import name 'ThreadingHTTPServer' 2021-08-11 11:08:55 Informações Commodity Futures Trading Library carregado com sucesso 2021-08-11 11:08:55 Informações O hospedeiro que você está usando é a versão 3.5 do ambiente de compilação python.

QQ3390214355Eu não entendo, mas se você pode traduzir, como entrar em contato?

Chen NanshanOlá, professor, como é escrito o endereço do webhook da política de alarme direto na TV?

lanbnMuito bem, obrigada professora, vou experimentar!

lanbnProfessora, olá, você pode me dar um pouco mais de detalhes sobre como escrever um pouco de código no contrato?

Sonhos pequenosA documentação da API FMZ termina com a função OKEX para trocar discos analógicos.

wbe3- pequenos fritosA estratégia para receber sinais de TV, como mudar o disco analógico?

Sonhos pequenosO erro ocorre porque o Python não tem um módulo relacionado ao ThreadingHTTPServer

chave986Não resolveste esse problema?

ETH8888É claro.

Sonhos pequenosNão é recomendável criar um serviço de solicitação de escuta de TV, use a extensão da API do FMZ.

Sonhos pequenosEsta estratégia é usada como um exemplo de commodity futures, se você precisa definir um código de contrato para executar uma moeda digital.

Sonhos pequenosO exemplo da estratégia é direto: um robô estratégico cria um serviço para ouvir as solicitações de sinais da TV. Não. # Teste POST solicita informação do corpo data = self.rfile.read ((200) # Especifica a duração da leitura Log (("data:", data) # Imprime os dados da solicitação POST, que podem ser especificados com base nos dados da solicitação e depois o robô executa as operações correspondentes Não. O código já tem uma anotação, e aqui está o corpo de informações para processar os pedidos enviados pela TV.

Sonhos pequenosA política é a mesma para todos.

Sonhos pequenosConfigure o API KEY do disco OKEX no FMZ, e adicione uma palavra ``exchange no código.

Sonhos pequenosNão entendo, acho que foi um erro, verifique.

Chen NanshanObrigado, se o meu endereço do webhook diz que a direção da transação é comprar, mas a dica do tv strategy alert é vender?

Sonhos pequenosO site https://www.fmz.com/bbs-topic/5969 tem exemplos de artigos e estratégias.

Sonhos pequenoshttps://www.fmz.com/api#exchange.setcontracttype... está na descrição da função e pode ver.

PY008O que é o código do contrato?

Sonhos pequenosNão é cortês.

Sonhos pequenosSe você está fazendo um contrato com uma bolsa, escreva o endereço do webhook na TV: O que é que ele está a fazer? Não. http://x.x.x.x:xxxx/data?access_key=xxx&secret_key=yyy&type=long&amount=1 Não. O contrato é simples: Não. http://x.x.x.x:xxxx/data?access_key=xxx&secret_key=yyy&type=cover_long&amount=1 Não. Lembre-se de definir o código do contrato no parâmetro da política.