美文网首页
利用 tradingview 指标对接发明者实盘机器人

利用 tradingview 指标对接发明者实盘机器人

作者: 发明者量化 | 来源:发表于2020-04-10 09:38 被阅读0次

    还在为TV看到了好策略却无法自动化下单而苦恼么!! 扁豆带你排忧解难~直接打通FMZ Bot~

    今天在这里要讲什么呢~
    大家看标题就对了!

    1. 背景介绍

    TradingView是很好的行情画图工具~
    pine脚本也是各种神仙操作, 强大威武!
    回测, 报警, 各种对接, 是非常完善的一款金融工具了~
    但是有两点一直在困扰着胖友们...
    一是昂贵的会员制度,
    二是信号直接可交易的交易所非常之少, 貌似就两三个.
    今天我们这篇文章就是带大家搞定交易所对接的问题~

    2. 实现方法

    整体的思路呢, 是这样事儿的.
    TV pine脚本 -> 信号报警webhook -> 本地webhook server转发请求 -> FMZ bot接收请求进行操作
    那咱呢, 就一步一步的来呗~
    ...
    首先, 你先有个TV呗,
    https://www.tradingview.com/
    接下来, 我们先建立个Alert, 详情见下图喽,

    图中的几点需要注意, 生成Alert的时候,
    有效期, webhook地址, Message内容, 一定要搞好.
    有效期, 这个一看就知道, 到期了就无效了...
    webhook地址, 这里我们先放下, 等本地的webhook service搞好了再回来填写.
    Message这里, 最好有个设计, 为了bot好区分是哪个Alert传来的信息,
    扁豆这里一般是这些信息 -> XXX策略, 下单量, 方向
    好啦, 到这里, TV部分基本搞定了!
    ...
    接下来我们搞定本地的webhook service!
    这种东西呢, Google一下遍地都是这框架那框架,
    扁豆就不再推荐了, 只说自己的那种.
    是个python的简单框架,
    GitHub: https://github.com/shawn-sterling/gitlab-webhook-receiver
    安全无忧, 简单方便, 当然...也是有坑的,
    这个小框架, 它会!! 自杀!! 这点请务必注意~
    所以呢, 又写了个脚本再server上面,
    当log里面出现die啊, offline啊, 就给他重启下, 后来不保险, 又定时重启了, 每个小时找个不碍事儿的时间...给他重启下, 目前有两个月左右了吧, 没有再出现过丢信号的情况了~
    另外还有一点, TV只认80端口哦~ service不要搞错端口了~
    搞到这里,
    我们已经搞定了从TV拿到了Alert的Message,
    那么我们怎么搞给Bot呢?
    不知道大家有没有注意过FMZ的接口文档最下面~

    我们可以通过api传给自己的小Bot一些Command!
    具体请求例子在这里, 红框部分就是我们需要的请求了~


    这里也同样需要一些准备工作,
    FMZ API(头像->账号设置->API接口),
    一个已经启动的Bot(我们要拿到它的ID, 不管怎么样先新建一个搞个ID), 一般机器人的url里面数字就是ID啦~


    好嘞!!
    到这里!~ 我们改造一下webhook service, 让他在接收了消息之后, 自动转发给我们可爱的FMZ Bot~!
    最后别忘了把搞好的webhook地址回填到TV的Alert中哦~
    (格式: http://xx.xx.xx.xx:80)
    下面是渣渣扁豆改动的service代码, 大家可以参考

    #!/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)传-1代表获取全部
            log.info(self.bot_conmand('CommandRobot', 169788, data_string))  # CommandRobot(robotId int64, cmd string)向机器人发送命令
    
        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()
    

    3. FMZ策略内实现

    上面讲了通信实现,
    那么其实我们的Bot策略中也要做相应的处理,
    来搞定我们的接收信号过程.
    比如一开始设计的Alert Message,
    自己可以按照喜好和具体设计来做一些玩儿法~ 这就看大家的脑洞啦~
    代码如下, 拿到信息, 筛选, 做操作, 结束~

    function get_Command() { //负责交互的函数,交互及时更新 相关数值 ,熟悉的用户可以自行扩展
        var way = null; //路由
        var cmd = GetCommand(); //获取  交互命令API
        var cmd_arr = cmd.split(",");
    
        if (cmd) {
            // 定义路由
            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;
            }
            // 分支选择 操作
            switch (way) {
                case 1: 
                    xxx
                    break;
                case 2: 
                    xxx
                    break;
                case 3: 
                    xxx
                    break;
                case 4: 
                    xxx
                    break;
                default:
                    break;
            }
        }
    }
    

    好啦~ 这次的科普就告一段落啦~
    希望有给大家带来帮助吧!
    顺便打个广告~
    公众号: 扁豆子的量化日志
    欢迎大佬们前来玩儿哈~
    (^U^)ノ~YO

    相关文章

      网友评论

          本文标题:利用 tradingview 指标对接发明者实盘机器人

          本文链接:https://www.haomeiwen.com/subject/msdlmhtx.html