Trình báo động TradingViewWebHook được kết nối trực tiếp với robot FMZ

Tác giả:Tốt, Tạo: 2020-08-07 10:44:17, Cập nhật: 2023-10-10 21:09:42

img

Gần đây, ngày càng có nhiều người dùng TradingView đã kết nối tín hiệu biểu đồ TradingView với nền tảng FMZ (FMZ.COMCác chỉ báo có thể được sử dụng trực tiếp cho giao dịch lập trình và tự động hóa, làm giảm các rào cản cho nhiều chương trình và phát triển giao dịch định lượng. Có một số chương trình thiết kế để thực hiện giao dịch tự động trên các giao dịch trực tuyến.TradingViewWebHook.

Giải pháp trước đây:https://www.fmz.com/digest-topic/5533.

Kế hoạch trước đó là mở rộng giao diện API của nền tảng FMZ để gửi hướng dẫn cho robot. Hôm nay, chúng ta hãy xem xét một giải pháp khác. Hãy để yêu cầu WebHook báo động của TradingView được gửi trực tiếp đến robot nền tảng FMZ, để nó có thể trực tiếp gửi hướng dẫn và đặt hàng giao dịch robot.

Mã nguồn chiến lược robot

Chiến lược được viết bằng Python. Sau khi robot được tạo ra và bắt đầu sử dụng chiến lược này, robot sẽ tạo ra một chủ đề, sẽ bắt đầu một dịch vụ để giám sát cổng đặt. Chờ cho các yêu cầu bên ngoài và xử lý. Khi tôi thử nghiệm nó, nó đã được kiểm tra bởi máy chủ trên máy chủ, và thiết bị nơi máy chủ nằm phải có thể truy cập từ bên ngoài. Khi robot thực hiện giao dịch, nó sử dụng giao diện lệnh thị trường. ngoài ra, chiến lược này cũng có thể được sửa đổi để thực hiệnlimit orderĐể dễ hiểu và hợp lý, lệnh thị trường được sử dụng ở đây, vì vậy sàn giao dịch phải hỗ trợ lệnh thị trường.

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

Các thông số chiến lược:

img

Yêu cầu báo động WebHook của TradingView

Cài đặt yêu cầu báo động là:

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

Kể từ khi TradingView gửiPOSTyêu cầu, dịch vụ giám sát phải theo dõiPOSTyêu cầu, và TradingView chỉ cho phép cổng 80 chohttp protocol.

  • xxx.xxx.xxx.xxxlà địa chỉ IP thiết bị của máy chủ nơi robot nằm. điền vào địa chỉ IP cụ thể của thiết bị của bạn, bạn cần phải nhận thức được rằng nó phải được truy cập từ mạng ngoài.

  • Cácaccess_keysecret_keycó thể tự tạo ra, miễn làaccess_keysecret_keytrongWebHookyêu cầu báo động là giống như những cấu hình trên các thông số robot.

  • Type, hướng giao dịch, mua hoặc bán, mở hoặc đóng, lưu ý rằng điểm và tương lai được phân biệt. Nếu đó là tương lai, lưu ý rằng mã hợp đồng tương lai phải được đặt trên các thông số robot, và đối tượng trao đổi được cấu hình cần phải là một trao đổi tương lai.

  • amount, số lượng giao dịch.

Kiểm tra chạy

Sử dụngwexAppđể mô phỏng thử nghiệm thị trường thực tế.

img img

Kết thúc

Địa chỉ chiến lược đầy đủ:https://www.fmz.com/strategy/221850

Cácaccess_keysecret_keytrong chương trình chỉ để xác định, và không có bảo đảm cho việc sử dụnghttpGiải pháp này chỉ là một ý tưởng và một giới thiệu. Trong các ứng dụng thực tế, các cân nhắc an ninh nên được thêm vào vàhttpsgiao tiếp nên được sử dụng.


Thêm nữa