Background introduction
TradingView is a good market quotes drawing tool.
The pine
script is also a powerful existence!
Backtesting, alarming, and various docking is a very complete financial tool.
But there are two issues that have been plaguing us...
- One is the expensive membership system
- The second is that there are very few exchanges where signals are directly tradable, it seems to be two or three.
Today our article is to take you to solve the problem of exchange docking issues.
Implementation
The overall idea is like this:
TV(TradingView) pine
script -> signal alarm webhook
-> local webhook server
forwarding request -> FMZ bot receives the request to operate
let's go step by step.
Go to TradingView website:
Next, we first create an Alert
, see the figure below for details
Some aspects in the picture need to pay attention to, when generating Alert
.
The validity period, webhook
address, and message
content must be well done.
The expiration date, this one will know at a glance, and it will be invalid when it expires...
Webhook
URL, let's keep it empty first, we will fill it in when the local webhook
service is done.
Message
here, it is best we have a clear explanation, in order to let the bot
distinguish from Alert
messages.
I generally set it like this: XXX strategy, order quantity and trading direction
So far, the TradingView part is basically done!
Next, let's get the local webhook
service job done!
This kind of work, Google it will show you lots of results. this article will skip this part, you can do it by yourself.
here is a simple framework for python:
GitHub: https://github.com/shawn-sterling/gitlab-webhook-receiver
Safe, worry-free and convenient, but there are also issues.
This little frame, it will!! Suicide!! Please pay attention to this issue!
So, I wrote another script on the server, When "die" or "offline" appears in the log, I will restart it. later on, i still feel not safe, so i set it restart regularly. Find an unimportant time every hour... Give it a restart, it has been safely running for two months now and there is no more signal losses.
In addition, TradingView only recognizes the port 80, so don't mess up the service port.
So far, We have done the Message
from Alert
part. Next, how do we get Bot?
I don't know if you have paid attention to the interface API document of FMZ at the bottom:
We can pass some commands to our little Bot through API!
The specific request example is here, the red box is the request we need.
Here also needs some preparation work.
FMZ API (avatar->account settings->API interface),
A Bot that has been started (we want to get its ID, so we create a new ID first), the number in the URL of a general robot is the ID.
Next, we transform the webhook service so that after receiving the message, it will be automatically forwarded to the FMZ Bot.
Finally, don’t forget to fill in the completed webhook
address in the TradingView Alert(format: http://xx.xx.xx.xx:80)
The following is the service
code I changed, you can use it as a reference:
#!/usr/bin/python -tt # -*- coding: UTF-8 -*- from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer import json import logging import logging.handlers import os import re import shutil import subprocess import time import ssl ssl._create_default_https_context = ssl._create_unverified_context try: import md5 import urllib2 from urllib import urlencode except: import hashlib as md5 import urllib.request as urllib2 from urllib.parse import urlencode ############################################################ ##### You will likely need to change some of the below ##### # log file for this script log_file = '/root/webhook/VMA/webhook.log' # Bot api licence accessKey = '' secretKey = '' # HTTP config log_max_size = 25165824 # 24 MB log_level = logging.INFO #log_level = logging.DEBUG # DEBUG is quite verbose listen_port = 80 ##### You should stop changing things unless you know what you are doing ##### ############################################################################## log = logging.getLogger('log') log.setLevel(log_level) log_handler = logging.handlers.RotatingFileHandler(log_file, maxBytes=log_max_size, backupCount=4) f = logging.Formatter("%(asctime)s %(filename)s %(levelname)s %(message)s", "%B %d %H:%M:%S") log_handler.setFormatter(f) log.addHandler(log_handler) class webhookReceiver(BaseHTTPRequestHandler): def run_it(self, cmd): """ runs a command """ p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT) log.debug('running:%s' % cmd) p.wait() if p.returncode != 0: log.critical("Non zero exit code:%s executing: %s" % (p.returncode, cmd)) return p.stdout def bot_conmand(self, method, *args): """ send conmand request to bot api """ d = { 'version': '1.0', 'access_key': accessKey, 'method': method, 'args': json.dumps(list(args)), 'nonce': int(time.time() * 1000), } d['sign'] = md5.md5(('%s|%s|%s|%d|%s' % (d['version'], d['method'], d['args'], d['nonce'], secretKey)).encode('utf-8')).hexdigest() return json.loads(urllib2.urlopen('https://www.fmz.com/api/v1', urlencode(d).encode('utf-8')).read().decode('utf-8')) def do_POST(self): """ receives post, handles it """ log.debug('got post') message = 'OK' self.rfile._sock.settimeout(5) data_string = self.rfile.read(int(self.headers['Content-Length'])) log.info(data_string) self.send_response(200) self.send_header("Content-type", "text") self.send_header("Content-length", str(len(message))) self.end_headers() self.wfile.write(message) log.debug('TV connection should be closed now.') #log.info(self.bot_conmand('GetRobotList', -1, -1, -1)) # GetRobotList(offset, length, robotStatus int)Pass -1 to get all log.info(self.bot_conmand('CommandRobot', 169788, data_string)) # CommandRobot(robotId int64, cmd string)Send commands to the robot def log_message(self, formate, *args): """ disable printing to stdout/stderr for every post """ return def main(): """ the main event. """ try: server = HTTPServer(('', listen_port), webhookReceiver) log.info('started web server...') server.serve_forever() except KeyboardInterrupt: log.info('ctrl-c pressed, shutting down.') server.socket.close() if __name__ == '__main__': main()
Implementation within FMZ platform trading strategy
All the above described the communication implementation, our Bot trading strategy also needs to be processed accordingly, in order for us to fix our receiving signal process.
For example, the Alert Message designed at the beginning, You can play it according to your preferences and specific needs.
The code is as follows, get the information, filter them, do the operation, and end.
function get_Command() { //Responsible function for interaction, interactively update relevant values in time, users can expand by themselves var way = null; //route var cmd = GetCommand(); // Get interactive command API var cmd_arr = cmd.split(","); if (cmd) { // Define the route if (cmd.indexOf("BUY,1") != -1) { way = 1; } if (cmd.indexOf("SELL,1") != -1) { way = 2; } if (cmd.indexOf("BUY,2") != -1) { way = 3; } if (cmd.indexOf("SELL,2") != -1) { way = 4; } // Branch selection operation switch (way) { case 1: xxx break; case 2: xxx break; case 3: xxx break; case 4: xxx break; default: break; } } }
This article is over, hope it can help you!