리소스 로딩... 로딩...

TradingViewWebHook 알람 FMZ 로봇에 직접 연결

저자:선함, 2020-08-07 10:44:17, 업데이트: 2023-10-10 21:09:42

img

최근에는 점점 더 많은 트레이딩뷰 사용자가 트레이딩뷰 차트 신호를 FMZ 플랫폼에 연결했습니다 (FMZ.COM직접적으로, 지표는 많은 프로그래밍 및 정량적 거래 개발에 대한 장벽을 줄이는 프로그래밍 및 자동화 거래에 사용할 수 있습니다.TradingViewWebHook.

이전 해결책:https://www.fmz.com/digest-topic/5533.

이전 계획은 FMZ 플랫폼의 API 인터페이스를 확장하여 로봇에 명령어를 전송하는 것이었다. 오늘은 다른 솔루션을 살펴보자. TradingView의 알람 WebHook 요청이 FMZ 플랫폼 로봇에 직접 전송되어 명령어를 직접 전송하고 로봇 거래를 주문할 수 있도록 하자.

로봇 전략 소스 코드

전략은 파이썬으로 작성되었습니다. 로봇이 생성되고 이 전략을 사용하기 시작 한 후, 로봇은 스레드를 만들 것입니다. 이 스레드는 설정된 포트를 모니터링하는 서비스를 시작할 것입니다. 외부 요청 및 처리를 기다리고 있습니다. 제가 테스트했을 때, 그것은 서버에 호스트에 의해 테스트되었으며, 호스트가있는 장치는 외부에서 액세스 할 수 있어야합니다. 로봇이 거래를 실행 할 때, 시장 주문 인터페이스를 사용합니다. 또한이 전략은 또한 시장 주문 인터페이스를 구현하기 위해 수정 될 수 있습니다.limit order순서 논리입니다. 이해하기 쉽고 간소화하기 위해 시장 순서를 사용합니다. 그래서 거래소는 시장 순서를 지원해야합니다.

'''
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)

전략 매개 변수

img

트레이딩뷰의 웹허크 경보 요청

경보 요청 설정은:

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

트레이딩뷰가 전송하기 때문에POST요청, 모니터링 서비스는 모니터링해야합니다POST요청, 그리고 TradingView는 단지 포트 80을 허용http protocol.

  • xxx.xxx.xxx.xxx로봇이 위치하는 호스트의 장치 IP 주소가 됩니다. 자신의 장치의 특정 IP 주소를 입력, 당신은 외부 네트워크에서 액세스 할 수 있어야한다는 것을 알아야 합니다.

  • access_key그리고secret_key자율적으로 생성될 수 있습니다.access_key그리고secret_keyWebHook알람 요청은 로봇의 매개 변수와 동일합니다.

  • Type, 거래 방향, 구매 또는 판매, 오픈 또는 폐쇄, 스팟과 선물의 구별을 참고하십시오. 선물이라면 선물 계약 코드가 로봇 매개 변수에 설정되어야하며 구성된 거래 대상은 선물 거래소여야합니다.

  • amount, 거래 수.

실행 테스트

사용wexApp실제 시장 테스트를 시뮬레이션하기 위해서요.

img img

END

전체 전략 주소:https://www.fmz.com/strategy/221850

access_key그리고secret_key이 계획에 포함된 것은 식별에만 해당하며,http이 해결책은 단지 아이디어와 소개일 뿐입니다. 실제 응용에서 보안 고려사항을 추가하고https의사소통을 해야 합니다.


더 많은