Aufbau eines Social-Technology Startups, Teil I: Ihre MetaTrader 5 Signale twittern

laplacianlab | 2 Juni, 2016

Einleitung

Dieser Artikel versucht, mit Hilfe eines praktischen Beispiels zu veranschaulichen, wie Sie ein MetaTrader 5 Terminal zur Kommunikation mit einem externen Webdienst verknüpfen können. Wir twittern die von einem Expert Advisors erzeugten Handelssignale.

Diese Idee stammt von einem besonderen Konzept automatischen Handels, dem sog. computergestützten Handel. Kurz gesagt: die Computer des 21. Jahrhunderts besitzen keine kognitiven Fähigkeiten, doch sie können sehr gut Informationen verarbeiten und Daten ausführen. Warum bauen wir daher nicht Computersysteme, die mit Hilfe des menschlichen Gehirns sinnvolle Entscheidungen treffen? Dieser Ansatz ist inspiriert durch das Paradigma der Menschen-basierten Berechnungen (HBC-Paradigma), konzentriert sich also auf den Bau von Tools zur Unterstützung von Entscheidungen, anstatt auf Codes von Algorithmen zum Treffen von Entscheidungen.

Zuerst hatte ich mir überlegt, ein RSS-Feed mit den von meinen EAs erzeugten Handelssignalen anzulegen (unter der Annahme eines zugrunde liegenden mittel- oder langfristigen Handelssystems; diese Idee ist nicht für automatische Scalping-System gültig). Ein Mensch, der auf diesen Feed zugreifen kann, sollte meine Robotersignale, kurz bevor er sie auf den Markt setzt, gemäß den im Moment herrschenden Umständen überprüfen. Doch bald schon habe ich erkannt, dass man das alles noch viel "sozialer" machen kann und dachte: 'Warum veröffentliche ich meine Handelssignale denn nicht gleich auf Twitter?' Und das war der Beginn der Entwicklung dieses Sozialen Entscheidungsunterstützungssystems.

Abb. 1 SDSS-Architektur

Abb. 1 SDSS-Architektur

Übrigens: Sollten Sie vorhaben ein Technologie-Startup in Bezug auf FX-Trading zu erzeugen, dann finden Sie in diesem Beitrag bestimmt auch einige hilfreiche Ideen. Er kann durchaus auch als technischer Leitfaden zum Bau eines kommerziellen SaaS (Software-as-a-Service) auf Basis von SDSS angesehen werden.

Dieser Beitrag ist lang, also habe ich ihn in zwei Teile unterteilt. Im ersten Teil beschäftigen wir uns mit der Webdienst-Architektur, dem Kommunikationsprotokoll, das zwischen dem MetaTrader5 Terminal und der Twitter App verwendet wird und schließlich mit der Integration der Internet-App in Twitter. Im zweiten Teil geht es um die MQL5-Ebene des oben gezeigten Netzwerkdiagramms, das den RESTful Webdienst unseres Sozialen Entscheidungsunterstützungssystems brauchen soll. Im Besonderen codieren wir ein MQL5-RESTful-Rahmenwerk auf genau die gleiche Weise, wie es im Beitrag MQL5-RPC. Remote Procedure Calls von MQL5: Zugriff auf Web-Service und der XML-RPC ATC Analysator für Spaß und Gewinn bereits erklärt wurde.

Dieser Beitrag hier ist ebenfalls sozial, daher bitte ich dringend um Ihre Kommentare, als Unterstützung für die weitere Arbeit mit dem zweiten Teil


1. Einige Anmerkungen zur SDSS-Architektur

1.1 MetaTrader 5 auf einem Server

Dies ist ein MetaTrader 5 Terminal, das auf einer Maschine läuft, die rund um die Uhr verfügbar ist Dieser Computer kann ein Virtueller Privater Server (VPS) oder ein Dezidierter Server (DS) sein. MetaTrader 5 auf einem Server kommuniziert mit Twitter mit Hilfe des RESTful Webdienstes. Das Datenformat für einen Datenaustausch ist JSON. Im zweiten Teil dieses Beitrags werden wir die MQL5-Ebene, die den Webdienst braucht, einrichten, und zwar laut des Kommunikationsprotokolls, das wir später in diesem Beitrag festlegen werden.

1.2 Twitter-App

Wie bereits in der Einleitung angesprochen, entwickeln wir im ersten Teil dieses Beitrags die Twitter-App des SDSS. Dabei handelt es sich um eine PHP-Webanwendung, die im Grunde Signale vom MetaTrader 5 Terminal erhält, diese in einer MySQL-Datenbank speichert und sie dann twittert. Doch diese App kann noch erweitert werden, um mit vielen Problemen, für deren Lösung menschliche Fähigkeiten notwendig sind, umgehen zu können.

So möchten Sie vielleicht Know-How und Wissen erfassen und mit den vom 'MetaTrader 5 auf einem Server' empfangenen Signalen, die von Menschen gefiltert wurden, eine Web-Ontologie anlegen, um herauszufinden, wie zuverlässig Ihr EA vom Standpunkt eines echten Menschen aus wirklich ist. Wir könnten die Zuverlässigkeit eines gegebenen Signals (ein Tweet) von seinen damit zusammenhängenden Re-Tweets und Favoriten aus berechnen. Das ist nur eine Idee - sie kann natürlich in diesem Beitrag nicht eingehend behandelt werden, doch theoretisch wäre so etwas möglich. Hier geht es nur um eine praktische Anwendung auf Basis des Paradigmas der Menschen-bezogenen Berechnungen (HBC-Paradigma).

1.3 Twitter

Laut Wikipedia ist Twitter: ein Online-Dienst für soziale Netzwerke und Mikroblogging, auf dem angemeldete Nutzer telegrammartige Kurznachrichten von 140 Zeichen Länge, die sog. Tweets, senden und lesen können.



2. RESTful-Webdienst Spezifikation

2.1 REST Überblick

REST, SOAP und XML-RPC sind die drei, zum Bau eines Webdienstes am häufigsten verwendeten Architekturmuster. Da die meisten modernen Web 2.0 Anwendungen mit diesem Muster beim Bau ihrer Dienste arbeiten, codieren wir unsere SDSS auch auf REST. Ich empfehle Ihnen, sich eingehender mit diesem Thema zu befassen, indem Sie den Beitrag Die Twitter REST-API (API = Programmierschnittstelle) lesen. Kurz gesagt: REST ist ein Austausch von HTTP-Aufrufen mit JSON oder XML als Datenaustauschformat.

Anders als SOAP und XML-RPC, kann REST sehr leicht implementiert werden und ist zudem das schnellste Programmierparadigma. Es ist zudem auch das einfachste, da es keine Protokollspezifikation in dem Sinne gibt, wie das bei XML-RPC und SOAP der Fall ist. D.h.: Der Entwickler muss keine XML Pseudosprache lernen, um den Webdienst einrichten zu können. Auf der anderen Seite kann REST mit JSON als Datenaustauschformat zwischen Client und dem Server arbeiten, was den Vorteil einer schnelleren Reaktionszeit hat. Denn jedes in JSON dargestellte Objekt belegt tatsächlich weniger Bytes als ein in XML dargestelltes Objekt. Denn JSON ist semantischer, oder anders gesagt: JSON hat weniger syntaktische Elemente als XML, um Informationen abzubilden.

2.2 SDSS API-Referenz

Haben Sie den Beitrag Die Twitter REST-API schon gelesen? OK, wenn das also bekannt ist, kann die API-Spezifikation von Twitter dazu dienen, einige Ideen aufzunehmen und sie beim Bau unserer SDSS-API anzuwenden. Nicht vergessen: Wir vereinfachen die Dinge in diesem Beitrag sehr, da das Ziel dieses Beitrags hier nicht die komplette Entwicklung des SDSS ist, das von einem Technologie-Startup eingerichtet werden könnte, sondern vielmehr das Aufzeigen einer praktischen Anwendung im echten Leben, mit deren Hilfe Sie Ihr MetaTrader 5 Terminal mit einem externen Webdienst verbinden können. Deshalb konzipieren wir in diesem Abschnitt eine extrem einfache API mit einer einzigen REST-Methode, die das HTTP Verb POSTEN verwendet. Das dient zum Empfang, dem Ablegen in der Datenbank und dem Twittern jedes gegebenen Handelssignals eines EAS.

2.2.1 Allgemeines

Die API sollte auf http://api.sdss-your-startup.com gehostet sein, und Zugriff auf sie sollte per HTTP oder HTTPS erfolgen. Für Anfragen zum POSTEN werden die Parameter in den POSTEN-Korpus im JSON-Format übermittelt.

2.2.2 REST-Ressourcen

 Ressource URLBeschreibung
Signal/Hinzufügen POSTENhttp://api.sdss-your-startup.com /signal/addSendet ein EA-Signal an die Twitter-Anwendung. Dies ist die Anfrage, die vom MetaTrader 5 Terminal durchgeführt wird, damit das SDSS das Handelssignal speichern und twittern kann.

Wie in der Einleitung zu diesem Beitrag bereits angesprochen, ermutige ich Sie, hier die REST-Methoden aufzuführen, die Sie in Ihrem Sozialen Entscheidungsunterstützungssystem gerne implementieren möchten. Schreiben Sie einfach Ihre Kommentare und teilen diese mit der MQL5 Community.

2.2.3 Signal/Hinzufügen POSTEN

 ParameterBeschreibung
ea_id

Die ID des EA, der das neue Signal sendet. Beispielwert: 12345

Symbol

Das an der Transaktion beteiligte Symbol. Beispielwert: EURUSD

Operation

Die Operation, die ausgeführt werden soll. Beispielwert: KAUFEN oder VERKAUFEN

Wert

Der Wert des Symbols im Moment der Transaktion. Beispielwert: 1.3214

Beispielanfrage:

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

Vor dem Hintergrund dieses Beispiels, muss auf zwei wichtige Dinge hingewiesen werden. Nehmen wir einerseits derzeit einmal an, dass nur ein MetaTrader 5 Terminal Signale an die Twitter Anwendung sendet. Daher brauchen wir keine Terminal-ID. Doch wenn später einmal das System erweitert und unser Startup vergrößert werden soll, dann werden wir vermutlich mehrere Terminals mit Twitter verbinden wollen.

Und dann müssen wir ein Feld namens mt5_id hinzufügen, damit das entsprechende MetaTrader 5 Terminal erkannt werden kann. Andererseits sollten Sie beachten, dass der obigen Aufruf mit irgendeiner Art Authentifizierungsmechanismus (Grundlegende HTTP-Authentifizierung über SSL oder einer Token-basierten Authentifzierung oder OAuth) abgesichert werden sollte. Diesen Teil lassen wir jedoch beiseite, doch sollten Sie dieses Problem nicht aus den Augen verlieren: denn ohne einen Authentifizierungsmechanismus zwischen dem MetaTrader 5 Terminal und der Twitter Anwendung, kann jeder, der das Kommunikationsprotokoll kennt, Handelssignale an die Twitter-Anwendung aus Abb. 1 senden. SDSS-Architektur.


3. Das Datenbank-Design der Web-Anwendung

Die Spezifikation der REST-API hat uns geholfen, klar zu erkennen, wie das System arbeitet. Also ist uns jetzt das Datenbank-Design klar:

# MySQL database creation...

CREATE DATABASE IF NOT EXISTS sdss;

use sdss;

# Please, change the user's password in production

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;

# Dump some sample data...

INSERT INTO eas(name, description) VALUES
('Bollinger Bands', '<p>Robot based on Bollinger Bands. Works with H4 charts.</p>'),
('Two EMA', '<p>Robot based on the crossing of two MA. Works with H4 charts.</p>');

4. Programmierung des PHP RESTful-Webdienstes

Die Entwickler von Slim beschreiben Slim als ein PHP-Mikroformat, mit dem man schnell einfache, jedoch leistungsfähige Web-Anwendungen und APIs schreiben kann. Genau, Sie haben recht! Auch wir schreiben unsere RESTful-API auf Slim, mit nur einigen wenigen Codezeilen. Denken Sie daran: aus Lerngründen und für verbesserte Einfachheit codieren wir hier eine HTTP POSTEN-Methode Lesen Sie sich also bitte die offizielle Slim-Dokumentation durch, um auch detailliert zu verstehen, wie Slim funktioniert.

Abb. 2 Directory-Struktur der PHP-API auf Basis von Slim

Abb. 2 Directory-Struktur der PHPAPI auf Basis von Slim

config\config.php

<?php

// Creating constants.

// General

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

// Database connection

define('DB_NAME', 'sdss');
define('DB_USER', 'laplacianlab');
define('DB_PASSWORD', 'password'); // Don't forget to change this in your production server!
define('DB_SERVER', 'localhost');

model\DBConnection.php

<?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

<?php

// Bootstrap logic

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);        
});

// More API methods here!.., according to your API spec

$app->run();

composer.json

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

Mit all dem an der Hand, können wir den Webdienst in unserer lokalen Entwicklungsmaschine testen. Ach übrigens: Bitte vergessen Sie nicht 1. in der Datei Ihres Hosts einen neuen Eintrag hinzuzufügen, damit Windows den lokalen Domainnamen api.laplacianlab.local auflösen kann, und 2. legen Sie für Ihren Apache einen virtuellen Host an.

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

::1 localhost
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
#      102.54.94.97     rhino.acme.com          # source server
#       38.25.63.10     x.acme.com              # x client host

# localhost name resolution is handled within DNS itself.
#       127.0.0.1       localhost
#       ::1             localhost

127.0.0.1       localhost
127.0.0.1       api.laplacianlab.local

httpd-vhosts.conf

# Virtual Hosts
#
# Required modules: mod_log_config

# If you want to maintain multiple domains/hostnames on your
# machine you can setup VirtualHost containers for them. Most configurations
# use only name-based virtual hosts so the server doesn't need to worry about
# IP addresses. This is indicated by the asterisks in the directives below.
#
# Please see the documentation at 
# <URL:http://httpd.apache.org/docs/2.4/vhosts/>
# for further details before you try to setup virtual hosts.
#
# You may use the command line option '-S' to verify your virtual host
# configuration.

#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any <VirtualHost> block.
#
<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>
Jetzt testen wir unsere erste REST-Ressource mit dem RESTClient, das eine Firefox-Ergänzung für Fehlersuche in RESTful-Webdiensten ist. Wenn also ordnungsgemäß verläuft, muss der Webdienst die Logik ablaufen lassen, die wir oben in der Slim-Methode codiert haben und zusammen mit einer JSON-Antwort ein HTTP 200 Ergebnis zurückschicken.


Abb. 3 Eine 'Signal/Hinzufügen POSTEN' Anfrage an http://api.laplacianlab.local senden

Abb. 3 Eine 'Signal/Hinzufügen POSTEN' Anfrage an http://api.laplacianlab.local senden

Die Kopfzeile der HTTP-Antwort für die 'Signal/Hinzufügen POSTEN' Anfrage sieht so aus:

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

Und das ist der HTTP-Antwortkorpus:

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

Prima, klappt! Wir haben soeben den Teil unseres Sozialen Entscheidungsunterstützungssystems implementiert, der der Abb. unten entspricht. Bitte nicht vergessen! Zum Schutz solcher Aufrufe in einem echten LIVE-Szenario sollze unbedingt eine Authentifizierungsebene eingerichtet sein.

Abb. 4 MetaTrader 5 und die Twitter-Anwendung kommunizieren mittels eines RESTful Webdienstes miteinander

Abb. 4 MetaTrader 5 und die Twitter-Anwendung kommunizieren mittels eines RESTful Webdienstes miteinander


5. Integration der Web-Anwendung mit Twitter

Beschäftigen wir uns jetzt mit dem Teil des Netzwerkdiagramms, das die Handelssignale von der Slim PHP Twitter-Anwendung an Twitter twittert.

Abb. 5 Handelssignale werden von der Twitter-Anwendung an Twitter getwittert.

Abb. 5 Handelssignale werden von der Twitter-Anwendung an Twitter getwittert.

Und was kommt jetzt? Genau, schon wieder richtig geraten! Klar brauchen wir zunächst eine Twitter-Anwendung. Also gehen Sie zu 'Twitter-Entwickler', melden sich in Ihrem Twitter-Konto an (Sie brauchen natürlich zuerst ein Twitter-Konto, um eine Twitter-Anwendung anlegen zu können), gehen dort zu "Meine Anwendungen" und klicken auf "Neue Anwendung anlegen".


Abb. 6 Eine neue Anwendung in 'Twitter-Entwickler' anlegen

Abb. 6 Eine neue Anwendung in 'Twitter-Entwickler' anlegen

Sie müssen die Detailangaben Ihrer neuen Anwendung ausfüllen und die 'Verkehrsregeln' der Entwickler akzeptieren. Die Detailangaben meiner neuen Anwendung lauten z.B. folgendermaßen:

Bezeichnung: Laplacianlabs SDSS

Beschreibung: Soziales Entscheidungsunterstützungssystem

Website: http://api.laplacianlab.local

Rückruf-URL: http://api.laplacianlab.local/twitter/oauth_callback

Gehen Sie anschließend auf die Registerkarte "Berechtigungen" und aktualisieren dort die Rechte für "Lesen und Schreiben". Und nachdem Sie Ihre Twitter-Anwendung angelegt haben, notieren Sie sich abschließend Ihren API-Schlüssel, Ihr API-Geheimnis und Ihren Oauth-Rückruf, um diese als Konstanten in Ihrer config\config.php Datei einsetzen zu können:

// Twitter OAuth

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

Was jetzt gerade geschieht ist die Kommunikation der Slim PHP-Mikro-Webanwendung mit Laplacianlabs SDSS (der oben angelegten Twitter-Anwendung). Dazu müssen Sie die Grundlagen des OAuth 2.0 Protokolls kennen, also bitte versäumen Sie nicht, sich die offizielle Dokumentation durchzulesen. Sie sollten mit dem OAuth-Flussdiagramm vertraut sein.

Abb. 7 OAuth-Flussdiagramm

Abb. 7 OAuth-Flussdiagramm

Gemäß dieses Diagramms müssen wir nun konsequenterweise die folgende MySQL-Tabelle zur Speicherung der Ressourcen-Besitzer anlegen (die Personen, die ihre Handelssignale twittern möchten):

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;

Dazu verwenden wir gezielt TwitterOAuth, eine PHP-Library zur Arbeit mit der OAuth-API von Twitter. Wenn Sie Slim via dem Composer mit Hilfe der composer.json-Datei installiert haben, die ich im vorangegangenen Abschnitt angehängt habe, brauchen Sie sich um die Installierung dieser Libary keine Gedanken machen, denn TwitterOAuth wird bereits in den Anbieter-Ordner Ihrer PHP-Anwendung kopiert

Andernfalls können Sie diese PHP-Komponente immer von GitHub herunterladen. In Anbetracht des OAuth-Flusses müssen wir nur noch die Methode für die Personen, die twittern, so programmieren, dass sie die Berechtigungen auf die SDSS von Laplacianlab und den Oauth-Rückruf anwendet. Derzeit ist unser SDSS so einfach, dass wir alles in die index.php-Datei schreiben können.

public\index.php

<?php

// Bootstrap logic

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);
});

// More API methods here!.., according to your API spec

// Twitter OAuth flow

// This method is for users to give permissions to Laplacianlab's SDSS to tweet 
// on their behalf.

$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 '
        . 'can now tweet trading signals on your behalf. Please, if you no '
        . 'longer want the SDSS to tweet on your behalf, log in your Twitter '
        . 'account and revoke access."}}';
    }    
});

// This is the 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']);
            // Set Twitter API version to 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']
                );               
                // remove the request token from session
                unset($_SESSION['twitter']['request_token']);
                unset($_SESSION['twitter']['request_token_secret']); 
                // Twitter's OAuth access tokens are permanent until revoked so
                // we try to update them when a tweeterer tries to give access
                // permissions again
                $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 '
                . 'can now tweet trading signals on your behalf. Please, if you no '
                . 'longer want the SDSS to tweet on your behalf, log in your Twitter '
                . 'account and revoke access."}}';
            }
            else
            {
                echo '{"error":{"text":"Login error"}}';
            }
        }
    } 
    else
    { 
        echo '{"error":{"text":"Login error"}}';
    }
});

$app->run();

 

Das Wichtigste hier ist das Speichern der zwei Datenstücke in die Datenbank, die der SDSS gestatten, authentifizierte Aufrufe an Twitter im Auftrag der Nutzer durchzuführen, die ihre Zugriffsrechte angegeben haben. Diese zwei Datenstücke sind der Zugriffs-Token und das Geheimnis des Zugriffs-Tokens, die beide solange permanent sind, bis sie vom Nutzer widerrufen werden. Das bedeutet, dass das soziale Entscheidungsunterstützungssystem niemals Nutzerangaben speichert und, andererseits, Nutzer stets ihre Zugriffsrechte entfernen können - jederzeit, indem sie sie einfach widerrufen.

Solange das PHP-basierte SDSS den korrekten Zugriffs-Token und das Geheimnis des Zugriffs-Tokens hat, kann es Twitter-Aufrufe wie den folgenden ausführen:

// Let's assume there's an object named $user to access the tokens...

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

$message = "Hello world! I am Laplacianlab's SDSS and I am tweeting on behalf of a tweeterer.";

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

Jetzt haben wir alles zusammen, was wir brauchen. Also gehen die Abschlussarbeiten für die SDDS-API-Ressource 'Signal/Hinzufügen POSTEN', die wir in Punkt 4 bereits zu codieren begonnen haben, kinderleicht. Der PHP RESTful-Webdienst wird programmiert, d.h. Sie müssen als Hausaufgabe noch den zum Twittern einiger Stichprobendaten erforderlichen PHP-Code hinzufügen.


Fazit

Dieser Beitrag hat beschrieben, wie man das MetaTrader 5 Terminal mit Twitter verknüpft, damit Sie die Handelssignale Ihres EAs twittern können. Wir haben ein computergestütztes System entwickelt, das die Rechnerleistung von Robotern mit den kognitiven Fähigen von Menschen verbindet. Denn wir wollen, dass Menschen die Handelssignale überprüfen, die sonst von Expert Advisors automatisch auf dem Markt platziert werden würden. Und daher haben wir die Tür zu einem neuen und aufregenden Thema aufgestoßen´- nämlich das Erfassen von Wissen über automatische Handelssysteme, wenn Menschen Handelssignale re-twittern oder ihren Favoriten hinzufügen. Dies ist eine ganz praktische Anwendung auf Grundlage des Paradigmas Menschen-basierter Berechnungen (HBC-Paradigma).

Die Einrichtung eines Sozialen Entscheidungsunterstützungssystems ist zeitaufwendig, daher kann man diese Übung hier als eine Idee zum Bau eines Technologie-Startups sehen. Wir haben ein SDSS entwickelt, das aus drei Hauptteilen besteht:

  1. MetaTrader 5 Terminal, der auf einem VPS oder DS läuft;
  2. PHP-Twitter Web-Anwendung auf Grundlage von Slim;
  3. Twitter;

Vor allem in diesem ersten Teil haben wir die Architektur des RESTful-Webdienstes implementiert, der MetaTrader 5 mit der Slim PHP Web-Anwendung kommunizieren lässt, und wir haben zudem auch die PHP Web-Anwendung mit Twitter mittels des OAuth-Protokolls verknüpft. Im zweiten Teil dieses Beitrags codieren wir ein MQL5-RESTful-Rahmenwerk, genauso wie im Beitrag MQL5-RPC. Remote Procedure Calls from MQL5: Zugriff auf Web-Service und der XML-RPC ATC Analysator für Spaß und Gewinn erklärt.