Interaktion zwischen MetaTrader 4 und Matlab über DDE

Dmitriy | 25 März, 2016


Einführung

Ich habe bereits einen Artikel hier veröffentlicht über Datenaustausch zwischen MetaTrader 4 und Matlab über CSV Dateien (MT 4 <-CSV->Matlab). Der in diesem Artikel beschriebene Ansatz ist jedoch, in vielen Fällen, nicht praktikabel und manchmal sogar unzumutbar.

Der in MT4 unterstützte Mechanismus von DDE (Dynamic Data Exchange) ermöglicht es uns, Daten von einer Anwendung in einer anderen direkt über den RAM des Computers zu übertragen. Matlab verfügt über die vollständige Funktionalität um das Frontend und das Backend umzusetzen, also wollen wir das Beste aus dieser Möglichkeit machen.

Der MetaTrader 4 DDE Server stellt nur die aktuellsten Tick-Daten bereit. Allerding, auch unter Berücksichtigung solcher Einschränkungen, ist DDE zu bevorzugen wenn es, zum Beispiel, um die Arbeit mit Kursen innerhalb von Balken geht.

Wie in dem Artikel über "MT 4 <-CSV->Matlab", werde ich die Reihenfolge zum Erzeugen eines den Austausch organisierenden Werkzeugs beschreiben.

Vergessen Sie nicht den DDE Server unter Extras -> Optionen -> Server Registerkarte in ihrem MetaTrader 4 Client Terminal zu aktiveren, und wir können anfangen.


Über DDE

Also, in der Organisation von Datenaustausch mit DDE gibt es zwei Enden (Frontend und Backend), zwischen denen die Verbindung hergestellt wird. Das Frontend ist eine Anwendung die Daten anfordert (Matlab in unserem Fall), das Backend ist eine Anwendung, die diese Daten zu ihrer Verfügung hat (MT4).

Die Daten können von dem Server zu dem Client über DDE auf drei Arten übertragen werden:
- durch die Anfrage des Clients,
- durch die Anfrage des Clients, und nachdem der Server benachrichtigt hat, dass die Daten für die Übertragung vorbereitet wurden, oder
- bei fertigen Daten für die Übertragung.

MetaTrader 4 DDE Server arbeitet nur in einem (dem dritten) Modus und sendet die fertigen Daten an den Client ohne auf eine Anfrage, Bestätigung oder andere solche Dinge zu warten. =) Also ist es die Aufgabe von Matlab MT4 zu benachrichtigen, dass es einen Client hat, über die benötigten Daten zu informieren und zu warten bis die Daten ankommen.

Sobald die Daten ankommen, werden wir sie im Diagramm.


Erstellen einer GUI

In der Matlab-Umgebung gibt es die Möglichkeit eine grafische Benutzeroberfläche (GUI - Graphic User Interface) zu erstellen. Ist eine GUI einmal erstellt, werden wir alle Steuerungen, Kurs-Charts und Textinformationen in ihr kombinieren, von denen wir denken, dass es notwendig diese anzuzeigen.

Das Erstellen einer GUI wird detaillierter beschrieben in den 3. Abschnitt des Artikels “MT4 <-CSV->Matlab”, so also werde ich hier nur den "guide" genannten Konsolenbefehl erwähnen, der den GUI Creation Wziard startet, und ich werde außerdem eine Liste der benötigten grafischen Objekte angeben.

Somit benötigen wir das Folgende:
- Eingabefeld "Text bearbeiten", um den Namen des Währungspaares einzugeben,
- “Achsen” zur Anzeige im Chart,
- zwei Ausgabefelder "Statischer Text", zum anzeigen des Werts des letzten Kurses, oder für etwas anders.

Unten wird gezeigt, wie ich die Objekte im meiner GUI platziert habe:


Sie sollten die grafischen Objekteigenschaften wie folgt festlegen:

Für Achsen:
Tag = axesChart (wir werden hier das Chart anzeigen),br /> Box = on – umschließt den Chart-Bereich in einem vollständigen Rechteck, off – umschließt den Chart-Bereich mit einer linken und einer Bodenlinie,
FontSize = 7 (die Standardgröße ist einfach riesig),
Units = pixels (dies benötigen wir bei der Diagrammerstellung, um den Maßstab auf 1:1 festzulegen).

F+r EditText:
Tag = editPair (wir geben den Namen des Währungspaares in dieses Feld ein).

Für StaticText unterhalb des EditText Feld:
Tag = textBid (wir geben den genauen Wert des letzten Kurses hier ein),
HorizontalAlignment = left (dies ist nicht sehr wichtig, Sie können es auf 'center' belassen).

Für StaticText ganz unten auf der Seite:
Tag = textInfo;
HorizontalAlignment = left.

Jetzt könne wir RUN drücken.
Ich habe mein Projekt "DDEs" genannt, wenn Sie also nicht wollen, dass Ihres keine Diskrepanzen mit meinem hat, geben Sie Ihrem Projekt bitte den gleichen Namen.

Wenn die Erscheinung Ihrer GUI Ihnen gefällt und die m-Datei fertig zum Bearbeiten ist, können wir mit dem Erstellen eines DDE Client beginnen.


Verbindung Initialisieren

Zunächst sollten Sie den Kanal für die Verbindung mit dem Server organisieren, wenn Sie die GUI starten, und achten Sie auf Verbindungsabbrüche beim Schließen der Schnittstelle.
In Matlab wird die DDE Verbindung initialisiert durch die Funktion: channel = ddeinit('service','topic'),
wobei:
‘service’ – DDE Server Name (‘MT4’)
'topic’ – Name eines Datenabschnitts. In unserem Fall kann sie die Werte von 'BID', ‘ASK’, ‘QUOTE’, usw. annehmen.
Die Funktion gibt den Deskriptor des initialisierten Kanals zurück. Der Deskriptor wird für weitere Konversationen mit dem Server verwendet.

Sie müssen auch die Austauschmethode angeben. In Matlab nennt sich die von MT4 unterstützte Austauschmethode nennt sich “Advisory link” und wird initialisiert durch die Funktion: rc = ddeadv(channel,'item','callback','upmtx',format);,
wobei:
channel – Deskriptor des initialisierten Kanals,
‘item’ – Daten, an denen wir interessiert sind, das heißt, der Symbolname eines Währungspaares,
'callback' – eine Linie die ausgeführt wird bei der Ankunft von Daten von dem Server,
'upmtx' – Symbolname der Variable zum Platzieren der von Server erhaltenen Daten,
format – Array aus zwei Flags, die das Format der gesendeten Daten definieren.
Die Funktion ddeadv gibt “1” zurück, wenn erfolgreich, andernfalls gibt sie "0" zurück.

Bitte beachten Sie, dass ein Symbolausdruck als 'callback' Parameter angegeben wird, nicht ein Funktion-Deskriptor. Tatsächlich werden wir die "eval" Funktion ausführen, die die Linie ausführt, als würde sie in eine Konsole eingegeben. Diese Eigenschaft erzeugt die folgende Schwierigkeit: Bei der Ankunft eines neuen Kurses, müssen wir eine große Funktion zum Erhalt des neuen Kurses ausführen. Gleichzeitig möchten wir die Struktur des "Identifikatoren"("handles") Deskriptors an diese Funktion übergeben, die verwendet wird um Zugang zu den grafischen Objekten der GUI zu erhalten. Allerdings fand ich weder irgendwelche Methoden zum Übergeben des Identifikatoren Struktur-Deskriptor in eine ausführbare Linie, noch die Möglichkeit der in der m-Datei befindlichen Funktion, welche die GUI beschreibt.
All dies führte dazu, dass ich die neue den Kurs empfangende Funktion in eine separate m-Datei platzieren und sie als normale Matlab-Funktion aufrufen musste. Allerdings stellte sich die Unannehmlichkeit als Vorteil heraus, nachdem ich entdeckte, dass ich die Verarbeitungsfunktion ohne die Unterbrechung der DDE Client-Operationen bearbeiten konnte.

Somit, als erstes, erstellen wir eine separate Verarbeitungsfunktion, die nur die empfangenen Dateien in der Konsole darstellt.


function newTick(simbols)
% neue Tick Verarbeitung
disp(simbols); % zeigt das Argument in der Konsole
song = wavread('C:\WINDOWS\Media\Windows XP - launch.wav'); % liest den Sound
wavplay(song,40000); % spielt den Sound ab mit der Abtastfrequenz von 40 kHz

Die obige beispielhafte Funktion gibt auch die Datei e 'C:\WINDOWS\Media\Windows XP - launch.wav' wieder, sobald ein neuer Kurs erscheint. Speichern Sie den Funktionstext als newTick.m in dem Arbeitsverzeichnis von MATLAB.

Bearbeiten wir nun die m-Datei, die das Verhalten der GUI beschreibt. Fügen Sie die Initialisierung der Verbindung der DDEs_OpeningFcn Funktion hinzu, und die De-Initialisierung wird der figure1_CloseRequestFcn Funktion hinzugefügt.
(Um die CloseRequestFcn Funktion zu der m-Datei hinzuzufügen, sollten Sie das folgende in dem GUI-Editor ausführen: View -> View Callbacks -> CloseRequestFcn).

% --- Führt aus kurz bevor DDEs sichtbar gemacht werden.
function DDEs_OpeningFcn(hObject, eventdata, handles, varargin)
% Diese Funktion hat keine Ausgabe-Argumente, siehe OutputFcn.
% hObject Identifikator zu Zahl
% Ereignisdaten reserviert - zu bestimmen in einer Zukunftsversion von MATLAB
% Identifikator Structure mit Identifikator und Benutzer-Daten (siehe GUIDATA)
% varargin Befehlszeile Argumente zu DDEs (siehe VARARGIN)

channel = ddeinit('MT4','QUOTE'); % Initialisierung
pair = get(handles.editPair,'UserData'); % liest den Symbolnamen
rc = ddeadv(channel, pair,'newTick(x)','x',[1 1]); % Verbindung herstellen
if (rc==1) % wenn die Verbindung hergestellt wurde,
disp('Connected'); % informiert die Konsole
end
handles.chann = channel; % speichert die Chanel ID in Identifikatoren

% Wählt Standard-Befehlszeilenausgabe für DDEs
handles.output = hObject,
% Aktualisiert Identifikator-Struktur
guidata(hObject, handles),
% UIWAIT lässt DDEs auf Benutzerantwort warten (siehe UIRESUME)
% uiwait(handles.figure1),

% --- Führt aus, wenn der Benutzer versucht figure1 zu schließen.
function figure1_CloseRequestFcn(hObject, eventdata, handles)
% hObject Identifikator zu figure1 (siehe GCBO)
% Ereignisdaten reserviert - zu bestimmen in einer Zukunftsversion von MATLAB
% Identifikator-Struktur mit Identifikator und Benutzerdaten (siehe GUIDATA)

channel = handles.chann; % erhält Channel ID von Identifikatoren
pair = get(handles.editPair,'UserData'); % den Symbolnamen lesen
ddeunadv(channel,pair); % Verbindungsabbruch
rc = ddeterm(channel); % De-Initialisierung
if (rc==1) % wenn alles OK ist
disp('Disconnected'); % informiert die Konsole
end

% Hinweis: delete(hObject) schließt die Figur
delete(hObject);

% --- Führt aus während der Objekterstellung, nach Einstellen aller Eigenschaften.
function editPair_CreateFcn(hObject, eventdata, handles)
% hObject Identifikator zu editPair (siehe GCBO)
% Ereignisdaten reserviert - zu bestimmen in einer Zukunftsversion von MATLAB
% Identifikatoren leer - Identifikatoren nicht erzeugt nachdem alle CreateFcns aufgerufen wurden

set(hObject, 'String', 'EURUSD'); % den Symbolnamen in das Eingabefeld eingeben
set(hObject, 'UserData', 'EURUSD'); % In den UserData des Eingabefelds - speichern

% Hinweis: Bearbeitungssteuerung hat in der Regel weißen Hintergrund in Fenstern.
% Siehe ISPC und COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end


Ich habe oben den vollen Text modifizierter Funktionen angegeben, zusammen mit dem vorbereiteten Text für leere Skelett-Funktionen von den Matlab Entwicklern.

Der letzte Block gibt den Symbolnamen in das entsprechende Feld ein, bevor die GUI gestartet wird. Der Eintrag wird zu der 'UserData' Eigenschaft kopiert. Wir werden immer die Kopie in 'UserData' verwenden, wobei wir nur den angezeigten Namen in dem Feld verwenden ('String'), wenn der Benutzer versucht die Sicherheit zu verändern. Wenn der Benutzer einen Fehler bei der Eingabe gemacht hat und ein falscher Name wurde in 'String' geschrieben, kehren wir zurück zu dem gespeicherten Namen in 'UserData'.

Der folgende Code realisiert die Funktion der Symbol-Namensänderung durch den Benutzer:

function editPair_Callback(hObject, eventdata, handles)
% hObject Identifikator zu editPair (siehe GCBO)
% Ereignisdaten reserviert - zu bestimmen in einer Zukunftsversion von MATLAB
% Identifikator-Struktur mit Identifikator und Benutzerdaten (siehe GUIDATA)

oldPair = get(hObject,'UserData'); % vorheriger Symbolname
newPair = get(hObject,'String'); % neuer Symbolname
channel = handles.chann; % erhält die Channel ID

disconn = ddeunadv(channel,oldPair); % Verbindung trennen
if (disconn==0) % wenn Sie scheitern beim Verbindung trennen
set(hObject,'String',oldPair); % Wiederherstellen des alten Symbolnamen im Eingabefeld
else % if diconnected
conn = ddeadv(channel, newPair,'newTick(x)','x',[1 1]); % stellt eine neue Verbindung her
if (conn==1) % wenn die Verbindung hergestellt ist
set(hObject,'UserData',newPair); % speichert welches Symbol verwendet wird
else % wenn Sie scheitern eine neue Verbindung herzustellen
ddeadv(channel, oldPair,'newTick(x)','x',[1 1]); % Wiederherstellen des Alten
set(hObject,'String',oldPair); % Wiederherstellen des alten Symbolnamen in dem Eingabefeld
end
end

% Hinwiese: get(hObject,'String') gibt die Inhalte von editPair als Text zurück
% str2double(get(hObject,'String')) gibt die Inhalte von editPair als ein double zurück


Ticks Erhalten

Berücksichtigen Sie, dass die Verbindung hergestellt ist und, bei der Ankunft eines neuen Tick, die "newTick(x)" Funktion aufgerufen wird, die das von MT4 empfangene Argument in einer Konsole "versiegelt" Zeigen wir zuerst den letzten empfangenen Kurs in der entsprechenden Zeile unserer GUI an.

Zu diesem Zweck müssen wir eine Struktur der GUI grafischen Objekte-Deskriptoren haben - Identifikatoren stehen zur Verfügung in der "newTick" Funktion. Verwenden wir die setappdata(h,name,value) Funktion, die die Daten in der Anwendungsdomäne speichert. Gebeb SIe "0" als die Anwendungs-ID an. Es ist der Deskriptor des Matlab Objekts 'root', er ist unveränderlich, also können wir ihn immer kennen.

Fügen Sie die Zeile "setappdata(0,'hndls',handles);" sofort nach der Überschrift der "DDEs_OpeningFcn" Funktion hinzu:

function DDEs_OpeningFcn(hObject, eventdata, handles, varargin)
setappdata(0,'hndls',handles); %

Jetzt, in der Funktion "newTick", können wir die Identifikatoren durch die Funktion value = getappdata(h,name) extrahieren, die wir mit "0" angegeben haben, als das Argument von "h". Dann sind wir in der Lage die GUI Objekte aus der "newTick" Funktion zu verwalten.

Dann wandeln wir das von dem DDE Server an die Funktion übergebene String Argument und zeigen den Wert von Bid in der GUI an. Außerdem erkennen wir den lokalen Zeitpunkt von dem Empfang des Kurses und ihn auch anzeigen, aber in der GUI Statusleiste. Die lokale Zeit ist notwendig, weil der DDE Server die Zeit mit einer Genauigkeit von Minuten übergibt, was ungeeignet ist für die Arbeit mit Ticks. Die 'now' Funktion gibt die lokale Zeit zurück mit einer Genauigkeit bis zu Anteilen von einer Millisekunde, also müssen wir uns keine Sorgen machen, dass verschiedene Ticks die gleiche Zeit festgelegt haben. Außerdem werden wir die Serverzeit von der von dem DDE Server erhaltenen Line extrahieren und wandeln sie in das Matlab Zeitformat.

Im Folgenden ist ein Beispiel der "newTick" Funktion:

function newTick(simbols)
% NEUE TICK VERARBEITUNG

timeLocal = now; % Detect the exact local time
handles = getappdata(0,'hndls'); % Erhält Identifikatoren von Root

% disp(simbols); % setzt das Argument in die Konsole (kommentiert)
song = wavread('C:\WINDOWS\Media\Windows XP - launch.wav'); %liest den sound
wavplay(song,40000); % spielt den Sound ab mit der Abtastrate von 40 kHz

set(handles.textInfo,'String', datestr(timeLocal)); % zeigt die lokale Zeit in der GUI

% --- Umwandern der von MT4 erhaltenen Linie ---
parts = sscanf(simbols, '%i/%i/%i %i:%i %f %f' ); % untersuchen die Linie nach
%dem Format: int/int/int int:int float float
timeServerVect = parts(1:5); % extrahiert die Zeit
timeServerVect = timeServerVect'; % Transponieren (Spalte in Linie)
timeServerVect = [timeServerVect 00]; % fügt Sekunden hinzu
timeServer = datenum(timeServerVect); % Umwandeln in Matlab Zeitformat
Bid = parts(6); % extrahiert Bid
Ask = parts(7); % extrahiert Ask
% --- Ende der Umwandlung ---

set(handles.textBid,'String',['Bid: ' num2str(Bid)]); % zeigt Bid in der GUI


Zeichnen eines Tick Chart

Hier ist die Fortsetzung der "newTick" Funktion, die oben begonnen wurde. Der Code wird mit detaillierten Kommentaren bereitgestellt, also, vermute ich, wird es keine Probleme für Sie geben Kopf oder Zahl aus ihr zu machen.
Ich werde nur das Bid-Kurs Array erklären, wie das von Identifikatoren, ist es indem 'Wurzelverzeichnis' Objekt-Bereich gespeichert
, aber gespeichert als "Daten". Die gespeicherten Daten stellen eine Struktur dar, die aus zwei Feldern besteht:
data.name - Symbolname eines Währungspaares,
data.array - Kurs-Array selbst.

In der "newTick" Funktion, gestalten diese Daten unter dem Namen von "ticks", und das Felder der Struktur haben die Namen ticks.name und ticks.array.

ticks.array stellt ein aus drei Spalten bestehendes Array dar:
- lokale Zeit in dem Matlab Zeitformat (mit von Matlab unterstützter Genauigkeit [Mikrosekunden]),
- Serverzeit
in dem Matlab Zeitformat (mit Genauigkeit bis Minute);
- Bid.

Die "newTick" Funktion leert das Kurs-Array, wenn der Symbolname in dem "editPair" Feld sich geändert hat und die Kurse für ein anderes Sybenol anfangen einzutraffen. Wenn das NICHT Geändert hat, werden Linien zu dem bestehenden Array hinzugefügt.

Der Block der Operationen mit dem Chart bestimmt die Parameter (Größe und Position) des axesChart Fensters und extrahiert die Fensterbreite in Pixel von diesem. Dies ist für das Programm notwendig um den horizontalen Maßstab der Anzeige einzustellen - ein Kurs für einen Pixel.
Gibt es weniger Kurse als Pixel in der Fensterbreite, wird das Chart als Ganzes gezeichnet. Gibt es mehr Kurse als Pixel, werden nur die neuesten Daten dargestellt, die in das Chart passen.

% --- Arbeiten mit dem Kurs-Array ---
GUIpairName = get(handles.editPair, 'UserData'); % Symbolname
if (~isappdata(0,'data')) % wenn keine Daten
ticks.name = GUIpairName; % bildet das Namensfeld
ticks.array = []; % bildet ein Feld - ein leeres Array
setappdata(0,'data',ticks); % schreibt Daten in das Wurzelverzeichnis
end
ticks = getappdata(0,'data'); % extrahiert Daten
if ~strcmp(ticks.name,GUIpairName) % wenn der Name sich geändert hat
ticks.name = GUIpairName; % bildet das Namensfeld
ticks.array = []; % bildet ein Feld - ein leeres Array
setappdata(0,'data',ticks); % schreibt die Daten in das Wurzelverzeichnis
end
ticks.array = [ticks.array; timeLocal timeServer Bid]; % fügt eine Zeile hinzu
% enthält die neuen Daten zu dem bestehenden Daten Array
setappdata(0,'data',ticks); % schreibt die Daten in das Wurzelverzeichnis
% --- Ende der Arbeit mit dem Array ---

% --- Arbeiten mit dem Chart ---
chartSize = get(handles.axesChart,'Position');% erhält die Chart Fenstergröße
chartSize = chartSize(3); % extrahiert die Chart-Fensterbreite
lenArray = size(ticks.array); % erhält die Größe des Daten Array
lenArray = lenArray(1); % extrahiert die Anzahl an Linien in dem Daten Array

set(handles.axesChart, 'NextPlot','replace'); % Zeichenmodus - ersetzt
% das alte Chart mit einem neuen

if (chartSize >= lenArray)
stairs(handles.axesChart,ticks.array(:,3)); % zeichnet das ganze Chart
else
stairs(handles.axesChart,ticks.array(lenArray-chartSize+1:lenArray,3));
% anzeigen der neuesten in das Chart passenden Daten
end
set(handles.axesChart,'XLim',[1 chartSize]); % den Maßstab einstellen - ein Zählimpuls
% in one width pixel
set(handles.axesChart, 'NextPlot','add'); % Zeichenmodus - hinzufügen
plot(handles.axesChart,[1 chartSize], [Bid Bid],'m');% den Bid horizontal zeichnen


Daten in einer Datei speichern

Die letzte zu beschreibende Funktion ist das Speichern von Tick-Daten in einer Datei durch eine Benutzeranfrage.
Wir werden durch das Drücken einer Schaltfläche speichern, also fügen wir das "Push Button" dem GUI Formular mit dem Editor hinzu.

Stellen Sie die folgenden Objekt-Eigenschaften ein: Tag = pushSave, String = Save.

Durch Drücken der "M-file Editor" Schaltfläche, wird die Vorlage der pushSave_Callback Funktion zu dem Ende der "DDEs.m" automatisch hinzugefügt.

Im Folgenden ist der volle Text der Funktion, die die Daten speichert:

% --- Führt aus durch Drücken der Schaltfläche pushSave.
function pushSave_Callback(hObject, eventdata, handles)
% hObject Identifikafor zu pushSave (see GCBO)
% eventdata reserved - zu bestimmen in einer Zukunftsversion von MATLAB
% Identifikatoren Struktur mit Identifikator und Benutzerdaten (siehe GUIDATA)
date = datestr(now,'yyyy-mm-dd'); % das Datum erhalten (string)
time = datestr(now,'HH-MM-SS') % die Zeit erhalten (string)
name = get(handles.editPair,'UserData');% den Symbolnamen (string)
template = [name '@' date '@' time]; % bilden des Dateinamen
[userName, userPath] = uiputfile([template '.txt']); % den Namen und den Pfad von dem Benutzer erhalten
if userName~=0 % if "Cancel" ist nicht betätigt
ticks = getappdata(0,'data'); % Daten aus dem Wurzelverzeichnis erhalten

timesStr = datestr(ticks.array(:,1)); % ein String Array bilden
% von Zeit und Datum
bidStr = num2str(ticks.array(:,3)); % ein BID benanntes String Array bilden
delimStr(1:length(bidStr)) =' ' ; % bilden eines "Spalten" Unterteilers
% genauer, bilden einer Linie, die in eine Spalte umgesetzt wird
matrix=[timesStr delimStr' bidStr]; % sammeln schreiben aller Str in eine Matrix
dlmwrite([userPath userName], matrix, '');% die MAtrix in eine Datei speichern
end


Die Funktion bereitet den Dateinamen vor, der aus dem Datum, der Zeit und dem Namen des Finanzinstruments besteht.
Beim Speichern werden die Symbol-Matrizen vorausgehend vorbereitet:
- timesStr -- lokale Zeit und Datum entsprechend der Kurse,
- delimStr -- Trennzeichen,
- bidStr -- BID Spalte.
Sie sind alle in einer Matrix vereint.

delimStr stellt eine Linie bestehend aus Leerzeichen dar. Die Länge der Linie ist gleich der Länge der BID Spalte. Bei der Zusammenführung wird die delimStr Linie in eine Spalte umgesetzt und trennt die Kurs-Spalte von der Zeit.


Fazit

Ich hoffe, das oben beschriebene Verfahren ermöglicht es Ihnen, die ganze Fülle der mathematischen Funktionen in Matlab für Entwicklung und Testen Ihrer automatisierten Handelsstrategien zu nutzen.