TradingView - это хороший инструмент для вычисления котировок на рынке.
Вpine
Сценарий тоже мощное существование!
Обратное тестирование, тревога и различные стыковки - это очень полный финансовый инструмент.
Но есть две проблемы, которые нас мучают...
Сегодня наша статья, чтобы взять вас, чтобы решить проблему обмена стыковочных вопросов.
В целом идея такова:
TV ((TradingView)pine
Скрипт -> сигнальная тревогаwebhook
-> местныеwebhook server
запрос пересылки -> бот FMZ получает запрос на работу
Давай шаг за шагом.
Зайдите на сайт TradingView:
Далее, мы сначала создатьAlert
, подробности см. на рисунке ниже
Некоторые аспекты картины необходимо обратить внимание на, при созданииAlert
.
Срок действия,webhook
адрес, иmessage
Содержание должно быть хорошо сделано.
Дата истечения срока действия, эта будет знать на первый взгляд, и она будет недействительна, когда истечет...
Webhook
URL, давайте сначала оставить его пустым, мы заполним его, когда местныйwebhook
Служба завершена.
Message
Здесь лучше, чтобы у нас было ясное объяснение, чтобы позволитьbot
отличить отAlert
messages.
Я обычно устанавливаю его так: XXX стратегия, количество заказов и направление торговли
На данный момент часть TradingView практически закончена!
Далее, давайте возьмем местногоwebhook
Служба выполнена!
Этот вид работы, Google это покажет вам много результатов. эта статья пропустит эту часть, вы можете сделать это самостоятельно.
Вот простой фреймворк для Python:
GitHub: https://github.com/shawn-sterling/gitlab-webhook-receiver
Безопасно, без забот и удобно, но есть и проблемы.
Эта маленькая рамка, это будет!! Самоубийство!! Пожалуйста, обратите внимание на этот вопрос!
Так что я написал еще один скрипт на сервере, когда
Кроме того, TradingView распознает только порт 80, так что не портите сервисный порт.
До сих пор, мы сделалиMessage
отAlert
Далее, как мы достанем Бота?
Я не знаю, обратили ли вы внимание на интерфейс API документа FMZ внизу:
Мы можем передать команды нашему маленькому боту через API! Пример конкретного запроса здесь, красный ящик - это запрос, который нам нужен.
Здесь тоже нужно немного подготовиться. FMZ API (аватар->настройки учетной записи->интерфейс API), Бот, который был запущен (мы хотим получить его ID, поэтому мы сначала создаем новый ID), номер в URL общего робота является ID.
Затем мы преобразуем сервис webhook так, что после получения сообщения оно будет автоматически перенаправлено на бота FMZ.
Наконец, не забудьте заполнить заполненную формуwebhook
адрес в Alert TradingView ((формат: 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)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()
Все вышеописанное описано внедрение коммуникации, наша стратегия торговли ботом также должна быть обработана соответственно, чтобы мы могли зафиксировать наш процесс приема сигнала.
Например, сообщение оповещения, разработанное в начале, Вы можете играть его в соответствии с вашими предпочтениями и конкретными потребностями.
Код следующий: получите информацию, отфильтруйте ее, выполните операцию и закончите.
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;
}
}
}
Эта статья закончена, надеюсь, она поможет вам!