Разработка социального технологического стартапа, часть I: Публикуем сигналы MetaTrader 5 в Твиттере

laplacianlab | 27 августа, 2014

Сегодня мы поговорим о том, как привязать терминал MetaTrader 5 к аккаунту в Твиттере для того, чтобы публиковать сигналы вашего эксперта. Мы разрабатываем Social Decision Support System (Социальную систему поддержки принятия решений), далее SDSS, в PHP на основе веб-сервиса RESTful. В основе этой идеи лежит концепция автоматической торговли или, так называемая торговля при помощи компьютеров. Мы хотим, чтобы автоматические торговые сигналы эксперта проходили через фильтры когнитивных способностей разума человека.

В этой статье мы покажем, как связать терминал MetaTrader 5 с внешним веб-сервисом на примере из практики. Мы публикуем в Твиттере сигналы, которые генерирует эксперт.

В основе этой идеи лежит концепция автоматической торговли или, так называемая торговля при помощи компьютеров. У компьютеров XXI века нет когнитивных способностей, но они прекрасно обрабатывают информацию и выполняют инструкции. В таком случае, почему бы нам не создать компьютерные системы, которые бы использовали человеческий интеллект для принятия решений? Этот подход основывается на модели Human-based computation (Вычисления с привлечением человеческих способностей), далее HBC, и фокусируется он преимущественно на разработке инструментов поддержки принятия решений, а не на кодировании алгоритмов принятия решений.

Изначально я думал о создании RSS канала с торговыми сигналами, которые генерирует мои эксперты. Речь идет о среднесрочной и долгосрочной торговых системах, поскольку эта концепция не подходит для скальпинговых систем. Человек, который имеет доступ к ленте, должен подтверждать соответствие торговых сигналов робота текущей ситуации на рынке, и только после прохождения такой проверки они могут попасть на рынок в виде торговых ордеров. Однако вскоре я понял, что это можно сделать более социально-ориентированным. Я подумал: "А почему бы мне не публиковать мои торговые сигналы в Твиттере?". Таким образом, я создал свою Social Decision Support System (SDSS).

Рисунок 1. Архитектура SDSS

Рис. 1. Архитектура SDSS

Кроме того, если вы планируете запустить технологический стартап, имеющий отношение к торговле на Forex, в этой статье вы найдете идеи, которые могут пригодиться. Вы можете рассматривать ее как пособие для того, чтобы написать SaaS (Software as a Service), основанное на SDSS.

Поскольку статья получалась слишком большой, для удобства чтения она была разбита на две части. В первой части внимание сосредоточено на структуре веб-сервиса, протоколе передачи данных между терминалом MetaTrader 5 и приложением для Твиттера и, наконец, интеграции веб-приложения и Твиттера. Во второй части рассмотрим прослойку MQL5 диаграммы, показанной выше. Именно она и будет конечным потребителем RESTful веб-сервиса SDSS. В частности, мы напишем код для фреймворка MQL5-RESTful точно так, как описано в статье MQL5-RPC. Удаленный вызов процедур из MQL5: доступ к Web-сервисам и анализ данных Automated Trading Championship 2011.

Эта статья, кроме всего прочего, социально ориентированная. Ваши комментарии к ней будут учитываться при написании второй части, а посему они приветствуются.


1. Примечания к архитектуре SDSS

1.1. MetaTrader 5 на сервере

Это терминал MetaTrader 5, запущенный на компьютере, который работает круглосуточно. Этот компьютер может быть как виртуальным выделенным сервером (VPS) или выделенным сервером (DS). MetaTrader 5 на сервере связывается с приложением Твиттер через веб-сервис RESTful. Форматом для обмена данными выбран JSON. Во второй части статьи мы сосредоточимся на прослойке MQL5, работающей с веб-сервисом в соответствии с протоколом передачи данных, который мы определим ниже.

1.2. Приложение Твиттер

Как уже было сказано, в первой части мы будем писать приложение SDSS для Твиттера. Это PHP веб-приложение, которое принимает сигналы из терминала MetaTrader 5, хранит их в базе данных MySQL и публикует в аккаунте Твиттера. Это приложение, однако, можно расширить, чтобы найти решение многим проблемам, требующим для этого человеческие способности.

Например, чтобы оценить надежность эксперта с точки зрения человека, вы, скорее всего, захотите собрать информацию и написать онтологию сигналов, полученных из 'MetaTrader 5 на сервере' и отсортированных людьми. Затем мы подсчитаем надежность конкретного сигнала (твита), основываясь на ретвитах и соответствующих закладках в избранном. Конечно, эта идея не может быть раскрыта в одной статье, но теоретически это возможно. Это только приложение, основанное на Human Based computation (HBC) модели.

1.3. Твиттер

Согласно Википедии, Твиттер - популярная социальная сеть, в которой можно вести микроблоги и посылать и читать короткие, до 140 знаков сообщения, которые называются твитами.



2. Спецификация RESTful веб-сервиса

2.1. Описание REST

REST, SOAP и XML-RPC - три самых используемых архитектурных шаблона для создания веб-сервиса. Поскольку в современных Web 2.0 приложениях этот шаблон используется для разработки собственных сервисов, мы будем также писать код SDSS на основе REST. Я бы порекомендовал глубже ознакомиться с этим вопросом. Статья The Twitter REST API даёт исчерпывающую информацию. Вкратце, REST - это обмен HTTP вызовов с использованием JSON или XML в качестве формата обмена данными.

В отличие от SOAP и XML-RPC, REST очень легко реализовать и, кроме того, он самый быстрый. Он также самый простой, потому, что не требует спецификации протокола в отличие от XML-RPC и SOAP. Это значит, что разработчику не нужно учить псевдоязык XML для развертывания сервиса. С другой стороны, REST может использовать JSON в качестве формата обмена данными между клиентом и сервером, что позволяет минимизировать время отклика. И в самом деле, любой объект, представленный в виде JSON, всегда занимает меньше места, чем тот же самый объект, представленный в виде XML. Это результат того, что JSON более семантичен или, иными словами, у JSON меньше семантических элементов, чем у XML для того, чтобы представлять информацию.

2.2. Справка по SDSS API

Вы уже читали документ под названием The Twitter REST API? Принимая во внимание все сказанное, спецификация API Твиттера может дать нам несколько идей, которые мы сможем применить в нашем SDSS API. Напомню, что мы не будем затрагивать ничего сложного, поскольку цель данной статьи - не полноценное развертывание SDSS для использования в технологическом стартапе, а демонстрация его практического применения в реальной жизни, где можно соединить терминал MetaTrader 5 с внешним веб-сервисом. Соответственно, в этом разделе мы создадим очень простой API с одним-единственным REST-методом, использующим HTTP POST-запрос. Это задумано для получения, хранения в базах данных и публикации сигналов эксперта на аккаунте в Твиттере.

2.2.1. Основное

API должен хоститься на вашем домене http://api.sdss-your-startup.com и быть доступным по протоколам HTTP или HTTPS. В POST-запросах параметры должны передаваться в формате JSON.

2.2.2. Ресурсы REST

 Ресурсы URLОписание
POST signal/addhttp://api.sdss-your-startup.com /signal/addПосылает сигнал эксперта в приложение Твиттер. Это запрос, который посылает терминал MetaTrader 5 для того, чтобы SDSS сохранил и опубликовал торговый сигнал в Твиттере.

Как уже было сказано во введении, эта статья является социально-ориентированной, поэтому я призываю вас перечислить здесь REST-методы, которые вы хотите реализовать в вашей SDSS. Оставляйте комментарии и поделитесь своими идеями с MQL5 сообществом.

2.2.3. POST signal/add

 ParameterОписание
ea_id

Идентификатор эксперта, отправляющего новый сигнал. Например: 12345

symbol

Символ, используемый в данной транзакции. Например: EURUSD

opeartion

Операция, которую предстоит совершить. Пример: BUY или SELL

value

Значение символа на момент транзакции. Например: 1.3214

Пример запроса:

{
    "ea_id": 1,
    "symbol": "AUDUSD",
    "operation": "BUY",
    "value": 0.9281    
}

В этом примере есть два важных момента, на которые нужно обратить внимание. С одной стороны, давайте предположим, что в наличии только один терминал MetaTrader 5, посылающий сигналы в приложение Твиттер. По этой причине нет необходимости в идентификаторе терминала. А если по прошествии времени мы решим усложнить систему и расширить стартап, возможно, мы захотим соединить несколько терминалов к приложению Твиттер.

В этом случае мы добавим поле, которое назовем mt5_id для того, чтобы обозначить соответствующий терминал MetaTrader 5. С другой стороны, следует заметить, что этот вызов, описанный выше, нужно защитить механизмом проверки подлинности (Basic HTTP Authentication по SSL, аутентификация с использованием токена или OAuth). Мы пропустим эту часть, но об этом нужно помнить. Имейте в виду, что без механизма проверки подлинности между терминалом MetaTrader 5 и приложением Твиттер, любой, кто знает протокол передачи данных, может послать торговый сигнал в приложение Твиттер, как показано на рис. 1.


3. Проектирование базы данных веб-приложения

Спецификация REST API позволила нам увидеть, как работает система, и поэтому сейчас мы можем понять структуру базы данных:

# Создание базы данных MySQL...

CREATE DATABASE IF NOT EXISTS sdss;

use sdss;

# Измените пароль пользователя в процессе

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES, 
CREATE TEMPORARY TABLES ON `sdss`.* TO 'laplacianlab'@'localhost' IDENTIFIED BY 'password'; 

CREATE TABLE IF NOT EXISTS eas (
    id mediumint UNSIGNED NOT NULL AUTO_INCREMENT, 
    name VARCHAR(32),
    description TEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
) ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS signals (
    id int UNSIGNED NOT NULL AUTO_INCREMENT,
    id_ea mediumint UNSIGNED NOT NULL,
    symbol VARCHAR(10) NOT NULL,
    operation VARCHAR(6) NOT NULL,
    value DECIMAL(9,5) NOT NULL,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (id_ea) REFERENCES eas(id)
) ENGINE=InnoDB;

# Передать данные образцов...

INSERT INTO eas(name, description) VALUES
('Bollinger Bands', '<p>Робот, основанный на линиях Боллинджера. Работает с графиками H4.</p>'),
('Two EMA', '<p>Робот, основанный на пересечении двух скользящих средних. Работает с графиками H4.</p>');

4. Программирование PHP RESTful Web-сервисов

По словам разработчиков, Slim - это микрофреймворк на PHP, который позволяет быстро писать простые, но мощные веб-приложения и API. Да, вы совершенно все правильно поняли! Мы собираемся написать наш RESTful API на Slim, используя малое количество строк кода. Напоминаю, что для простоты и наглядности мы собираемся написать код только для одного HTTP POST метода. Особенности работы Slim вы можете найти в официальной документации.

Рисунок 2. Структура каталогов PHP API основанная на Slim

Рис. 2. Структура каталогов PHP API основанная на Slim

config\config.php

// Создание констант.

// Общие

define('BASE_URL', 'laplacianlab.local');
define('APPLICATION_PATH', realpath(dirname(__FILE__)) . '/../');

// Подключение к базе данных

define('DB_NAME', 'sdss');
define('DB_USER', 'laplacianlab');
define('DB_PASSWORD', 'password'); // Не забудьте изменить пароль на рабочем сервере!
define('DB_SERVER', 'localhost');

model\DBConnection.php

class DBConnection 
{ 
    private static $instance; 
    private $mysqli;
 
    private function __construct()
    { 
        $this->mysqli = new MySQLI(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME); 
    } 
 
    public static function getInstance()
    {
        if (!self::$instance instanceof self) self::$instance = new self; 
        return self::$instance;
    } 
 
    public function getHandler()
    { 
        return $this->mysqli; 
    } 
}

public\.htaccess

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

public\index.php

// Логика самозагрузки

require_once '../config/config.php';

set_include_path(get_include_path() . PATH_SEPARATOR . APPLICATION_PATH . '/vendor/');
set_include_path(get_include_path() . PATH_SEPARATOR . APPLICATION_PATH . '/model/');

require_once 'slim/slim/Slim/Slim.php';
require_once 'DBConnection.php';

use \Slim\Slim;

Slim::registerAutoloader();

$app = new Slim();
$app->response->headers->set('Content-Type', 'application/json');

// RESTful API methods

// POST signal/add

$app->post('/signal/add', function() {   
    $request =  Slim::getInstance()->request();    
    $signal = json_decode($request->getBody());
    $sql = 'INSERT INTO signals(id_ea, symbol, operation, value) VALUES (' 
            . mysql_real_escape_string($signal->ea_id) . ",'"
            . mysql_real_escape_string($signal->symbol) . "','"
            . mysql_real_escape_string($signal->operation) . "',"
            . mysql_real_escape_string($signal->value) . ')';  
    DBConnection::getInstance()->getHandler()->query($sql);
    $signal->id = DBConnection::getInstance()->getHandler()->insert_id;
    echo json_encode($signal);        
});

// Больше API методов!.., в соответствии с API спецификацией

$app->run();

composer.json

{
    "require": {
        "slim/slim": "2.*",
        "abraham/twitteroauth": "dev-master"
    }
}

Используя вышеперечисленное, мы можем протестировать веб-сервис на нашем локальном компьютере. Кстати, не забудьте (1) добавить новую запись в файл hosts для того, чтобы Windows могла преобразовать имя локального домена api.laplacianlab.local, и (2) создать виртуальный хост для Apache.

C:\Windows\System32\Drivers\etc\hosts

::1 localhost
# Copyright (c) 1993-2009 Microsoft Corp.
#
# Это пример файла HOSTS, который использует Microsoft TCP/IP для Windows.
#
# Этот файл содержит сопоставление IP адресов и имен узла. Каждая 
# запись должна занимать отдельную строчку. IP адрес должен
# быть помещен в первую колонку, за которой следует соответствующее имя узла.
# IP адрес и имя узла должны разделяться как минимум одним
# пробелом.
#
# Кроме того, комментарии (такие как этот) могут быть добавлены на отдельных
# строчках или следом за именем машины, обозначенном знаком '#'.
#
# Например:
#
#      102.54.94.97     rhino.acme.com          # сервер источник
#       38.25.63.10     x.acme.com              # x хост клиент

# Преобразование имени рабочей станции должно происходить в DNS.
#       127.0.0.1       рабочая станция
#       ::1             рабочая станция

127.0.0.1       рабочая станция
127.0.0.1       api.laplacianlab.local

httpd-vhosts.conf

# Виртуальные хосты
#
# Required modules: mod_log_config

# Если вы хотите обслуживать несколько доменов/хостов на своем
# компьютере, вы можете установить для них контейнеры VirtualHost. Большинство конфигураций
# используют виртуальный хост, с методом реализации доступа по имени, что позволяет серверу не беспокоиться об
# IP адресах. Это обозначено звездочками в директивах ниже.
#
# Перейдите по ссылке, чтобы ознакомиться с документацией 
# <URL:http://httpd.apache.org/docs/2.4/vhosts/>
# для ознакомления с полным описанием того, как установить виртуальный хост.
#
# Для того, чтобы проверить конфигурацию Вашего виртуального хоста,
# используйте параметр командной строки '-S'.

#
# Пример VirtualHost:
# Почти любые директивы Apache могут пойти в контейнер VirtualHost.
# Первая секция VirtualHost служит для всех запросов, которые
# не совпадают с ServerName или ServerAlias в любом из <VirtualHost> блоков.
#
<VirtualHost *:80>
        ServerAdmin webmaster@laplacianlab.local
        DocumentRoot "c:/wamp/www/laplacianlab/public"
        ServerName api.laplacianlab.local
        ErrorLog "logs/api.laplacianlab.local-error.log"
        CustomLog "logs/api.laplacianlab.local-access.log" common
        <directory "c:/wamp/www/laplacianlab/public">
                Options FollowSymLinks
                AllowOverride all
                Order Deny,Allow
                Deny from all
                Allow from 127.0.0.1
        </directory>    
</VirtualHost>
Сейчас мы протестируем наш первый ресурс REST при помощи RESTClient, который является дополнением к Firefox для отладки RESTful веб-сервисов. Если все пойдет хорошо, веб-сервис должен запустить логику, которую мы закодировали ранее при помощи Slim метода и прислать результат HTTP 200 в ответе JSON.


Рисунок 3. Отправим запрос POST signal/add на http://api.laplacianlab.local

Рис. 3. Отправим запрос POST signal/add на http://api.laplacianlab.local

Заголовок HTTP-ответа на запрос POST signal/add:

Status Code: 200 OK
Connection: Keep-Alive
Content-Length: 70
Content-Type: application/json
Date: Mon, 07 Apr 2014 18:12:34 GMT
Keep-Alive: timeout=5, max=100
Server: Apache/2.4.4 (Win64) PHP/5.4.12
X-Powered-By: PHP/5.4.12

А это - тело ответа HTTP:

{
        "ea_id": 1,
        "symbol": "AUDUSD",
        "operation": "BUY",
        "value": 0.9281,
        "id": 22
}

Всё получилось! Мы реализовали ту часть нашей SDSS, которая соответствует рисунку ниже. Однако помните! В реальном сценарии должна присутствовать прослойка аутентификации, чтобы обеспечить защиту таким вызовам.

Рисунок 6. MetaTrader 5 и Твиттер-приложение взаимодействуют друг с другом при помощи веб-сервиса RESTful

Рис. 4. MetaTrader 5 и Твиттер-приложение взаимодействуют друг с другом при помощи веб-сервиса RESTful


5. Интеграция веб-приложения с Твиттером

Сейчас мы займемся той частью диаграммы сети, которая публикует торговые сигналы из приложения Slim PHP Твиттер в Твиттер.

Рисунок 5. Публикация в Твиттер торговых сигналов из Твиттер-приложения

Рис. 5. Публикация в Твиттер торговых сигналов из Твиттер-приложения

Что будет дальше? И вы опять угадали! Прежде всего вам понадобится Твиттер-приложение. Для этого зайдите на страницу Twitter Developers, войдите с данными вашего аккаунта Твиттер (соответственно, вам нужен аккаунт Твиттер для того, чтобы вы могли создать Твиттер-приложение). Затем зайдите в "My Applications" и кликните на "Create New App".


Рисунок 6. Создаем новое приложение на странице Twitter Developers

Рис. 6. Создаем новое приложение на странице Twitter Developers

Вам нужно будет вписать детали своего нового приложения и принять Developer Rules of the Road. Вот пример деталей моего приложения:

Name: Laplacianlab's SDSS

Description: Social Decision Support System

Website: http://api.laplacianlab.local

Callback URL: http://api.laplacianlab.local/twitter/oauth_callback

Сейчас найдите закладку "Permissions" и обновите разрешения до "Read and Write". Ну, и наконец, после того, как создали приложение Твиттер, запишите Ваш API-key, API-secret и OAuth для того, чтобы использовать их как константы в config\config.php файле:

// Twitter OAuth

define('API_KEY', 'akMnfXR45MkoaWbZoPiu3');
define('API_SECRET', '45Mkoa54NcvQRBbf119qWerty0DnIW45MncvFgqw');
define('OAUTH_CALLBACK', 'http://api.laplacianlab.local/twitter/oauth_callback');

На данный момент мы связываем веб-приложение Slim PHP micro с Laplacianlab's SDSS (Твиттер-приложение, которое мы создали выше). Для того, чтобы это осуществить, нужны базовые знания протокола the OAuth 2.0. Основы можно найти в официальной документации. Вам должна быть знакома диаграмма OAuth.

Рисунок 7. Диаграмма OAuth

Рис. 7. Диаграмма OAuth

Таким образом, в соответствии с диаграммой, нам нужно создать таблицу MySQL, в которой мы сохраним данные источников (пользователей Твиттер, которые хотят публиковать торговые сигналы):

CREATE TABLE IF NOT EXISTS twitterers (
        id mediumint UNSIGNED NOT NULL AUTO_INCREMENT, 
        twitter_id VARCHAR(255),
        access_token TEXT,
        access_token_secret TEXT,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id)
) ENGINE=InnoDB;

В частности, мы используем TwitterOAuth, которая является библиотекой PHP для работы с OAuth API Twitter. Если вы устанавливали Slim через Composer, используя файл composer.json, который я присоединил в предыдущем разделе, вам не нужно беспокоиться об установке этой библиотеки, потому, что TwitterOAuth уже будет скопирована в папку поставщика приложения PHP.

В противном случае, вы всегда сможете скачать этот компонент PHP с GitHub. Имея OAuth flow, остаётся только написать метод для получения разрешения публикации от имени Laplacianlab's SDSS и обработку обратного вызова OAuth. Пока наша SDSS настолько проста, что мы можем написать все в index.php файле.

public\index.php

// Логика самозагрузки

require_once '../config/config.php';

set_include_path(get_include_path() . PATH_SEPARATOR . APPLICATION_PATH . '/vendor/');
set_include_path(get_include_path() . PATH_SEPARATOR . APPLICATION_PATH . '/model/');

require_once 'slim/slim/Slim/Slim.php';
require_once 'abraham/twitteroauth/twitteroauth/twitteroauth.php';
require_once 'DBConnection.php';

use \Slim\Slim;

session_start();

Slim::registerAutoloader();

$app = new Slim();
$app->response->headers->set('Content-Type', 'application/json');

// RESTful API methods

// POST signal/add

$app->post('/signal/add', function() {   
    $request =  Slim::getInstance()->request();    
    $signal = json_decode($request->getBody());
    $sql = 'INSERT INTO signals(id_ea, symbol, operation, value) VALUES (' 
            . mysql_real_escape_string($signal->ea_id) . ",'"
            . mysql_real_escape_string($signal->symbol) . "','"
            . mysql_real_escape_string($signal->operation) . "',"
            . mysql_real_escape_string($signal->value) . ')';
    DBConnection::getInstance()->getHandler()->query($sql);
    $signal->id = DBConnection::getInstance()->getHandler()->insert_id;
    echo json_encode($signal);
});

// Здесь будут другие API методы!.., в соответствии с API спецификацией

// Twitter OAuth flow

// Этот используется пользователями, для того, чтобы разрешить Laplacianlab's SDSS публиковать сигналы в Твиттере 
// от их имени.

$app->get('/tweet-signals', function() use ($app) {   
    if (empty($_SESSION['twitter']['access_token']) || empty($_SESSION['twitter']['access_token_secret']))
    {
        $connection = new TwitterOAuth(API_KEY, API_SECRET);
        $request_token = $connection->getRequestToken(OAUTH_CALLBACK);
        if ($request_token)
        {
            $_SESSION['twitter'] = array(
                'request_token' => $request_token['oauth_token'],
                'request_token_secret' => $request_token['oauth_token_secret']
            );
            switch ($connection->http_code) 
            {
                case 200:
                    $url = $connection->getAuthorizeURL($request_token['oauth_token']);                    
                    // redirect to Twitter
                    $app->redirect($url);
                    break;
                default:
                    echo '{"error":{"text":"Connection with Twitter failed"}}';
                break;
            }
        }
        else 
        {
            echo '{"error":{"text":"Error Receiving Request Token"}}';
        }
    } 
    else 
    {    
        echo '{"message":{"text":"Everything is ok! Laplacianlab\'s SDSS '
        . 'может публиковать в Твиттер торговые сигналы от вашего имени. Пожалуйста, если вы не '
        . 'хотите, чтобы SDSS публиковала сигналы в Твиттер от вашего имени, автоматизируется в вашем аккаунте Твиттер '
        . 'и запретите доступ."}}';
    }    
});

// Это OAuth callback

$app->get('/twitter/oauth_callback', function() use ($app) {   
    if(isset($_GET['oauth_token']))
    {
        $connection = new TwitterOAuth(
            API_KEY, 
            API_SECRET, 
            $_SESSION['twitter']['request_token'], 
            $_SESSION['twitter']['request_token_secret']);
        $access_token = $connection->getAccessToken($_REQUEST['oauth_verifier']);
        if($access_token)
        {       
            $connection = new TwitterOAuth(
                API_KEY, 
                API_SECRET, 
                $access_token['oauth_token'], 
                $access_token['oauth_token_secret']);
            // Установим Twitter API версию 1.1.
            $connection->host = "https://api.twitter.com/1.1/";
            $params = array('include_entities' => 'false');
            $content = $connection->get('account/verify_credentials', $params);            
            if($content && isset($content->screen_name) && isset($content->name))
            {
                $_SESSION['twitter'] = array(
                    'id' => $content->id,
                    'access_token' => $access_token['oauth_token'],
                    'access_token_secret' => $access_token['oauth_token_secret']
                );               
                // уберём токен запроса из сессии
                unset($_SESSION['twitter']['request_token']);
                unset($_SESSION['twitter']['request_token_secret']); 
                // Токены доступа OAuth в Твиттере постоянны до тех пор, пока их не аннулировали и
                // мы попытаемся их обновить, когда пользователь Твиттера пытается дать доступ
                // повторное разрешение
                $sql = "SELECT * FROM twitterers WHERE twitter_id='$content->id'";
                $result = DBConnection::getInstance()->getHandler()->query($sql);
                if($result->num_rows)
                {
                    $sql = "UPDATE twitterers SET "
                    . "access_token = '" . mysql_real_escape_string($access_token['oauth_token']) . "', "
                    . "access_token_secret = '" . mysql_real_escape_string($access_token['oauth_token_secret']) . "' "
                    . "WHERE twitter_id ='" . $content->id . "'";
                }
                else
                {
                    $sql = "INSERT INTO twitterers(twitter_id, access_token, access_token_secret) "
                    . "VALUES ('"
                    . mysql_real_escape_string($content->id) . "','"
                    . mysql_real_escape_string($access_token['oauth_token']) . "','"
                    . mysql_real_escape_string($access_token['oauth_token_secret']) . "')";
                }                
                DBConnection::getInstance()->getHandler()->query($sql);
                echo '{"message":{"text":"Everything is ok! Laplacianlab\'s SDSS '
                . 'сейчас мы можем публиковать в Твиттер торговые сигналы от вашего имени. Если вы больше не '
                . 'хотите, чтобы SDSS публиковала в Твиттер от вашего имени, авторизируйтесь в вашем Твиттер '
                . 'аккаунте и запретите доступ."}}';
            }
            else
            {
                echo '{"error":{"text":"Login error"}}';
            }
        }
    } 
    else
    { 
        echo '{"error":{"text":"Login error"}}';
    }
});

$app->run();

 

Самое важное здесь это хранение в базах данных двух фрагментов информации, которая позволит SDSS делать авторизованные вызовы в Твиттер от имени пользователей с правом доступа. Эти два фрагмента информации - токен доступа и секрет токена доступа, остаются постоянными до тех пор, пока пользователь их не аннулируют. Таким образом, SDSS никогда не хранит данные пользователя. С другой стороны, пользователи могут удалить разрешение доступа в процессе аннулирования.

Пока, основанная на PHP, SDSS имеет корректный токен доступа и секрет токена доступа, она может совершать вызовы Твиттер как показано ниже:

// Предположим, что объект по имени $user осуществил доступ к токенам...

$connection = new TwitterOAuth(
    API_KEY, 
    API_SECRET, 
    $user->getAccessToken(), 
    $user->getAccessTokenSecret());       

$message = "Hello world! Я Laplacianlab's SDSS и я публикую сигналы от имени пользователя Твиттер.";

$connection->post('statuses/update', array('status' => $message));

У нас есть все необходимое. Закончить SDSS API ресурс POST signal/add очень просто. Мы начали писать код для него в 4. Программирование PHP RESTful Web-сервисов. Вы можете поупражняться в добавлении PHP кода для тестовой публикации в Твиттере.


Заключение

В этой статье мы рассмотрели как соединить терминал MetaTrader 5 с Твиттер для того, чтобы публиковать торговые сигналы эксперта. Мы разработали систему на основе компьютера, которая совмещает в себе вычислительные возможности робота и человеческие способности к распознаванию. Мы хотим, чтобы торговые сигналы, генерируемые роботом, проходили дополнительную проверку людьми до того, как они будут отправлены на рынок виде торговых приказов. Эта идея принесла нам новую захватывающую тему, которая накапливает знания о системах автоматизированной торговли, когда пользователи публикуют чьи-то сигналы на своей странице или добавляют в избранное. Это практическое приложение на основе парадигмы Human-based computation (HBC).

Внедрение законченной Social Decision Support System займет много времени, поэтому данное упражнение может быть идеей для запуска технологического стартапа. Мы начали создавать SDSS, которая состоит из трёх главных частей:

  1. Терминал MetaTrader 5, работающий на виртуальном выделенном сервере или выделенном сервере;
  2. PHP Твиттер веб-приложение, основанное на Slim;
  3. Твиттер;

В частности, в этой части статьи мы создали архитектуру RESTful веб-сервиса, который позволяет MetaTrader 5 взаимодействовать с Slim PHP веб-приложением. Кроме того, соединили PHP веб-приложение с Твиттер через протокол OAuth. В следующей части мы напишем код к MQL5-RESTful фреймворк точно таким же образом, как описано в статье MQL5-RPC. Удаленный вызов процедур из MQL5: доступ к Web-сервисам и анализ данных Automated Trading Championship 2011.