Aktienkurse mit einer KI vorhersagen - Machine Learning mit PHP

Aktuell teste und spiele ich ein bisschen mit Künstlicher Intelligenz (KI / artificial intelligence / AI). Zwar ist PHP nicht die ideale Sprache, um eine AI aufzubauen, aber es ist möglich und funktioniert auch ganz gut. In meinem Beispiel werde ich die Schlusskurse (17:30Uhr) der 30 DAX-Kurse um 16:00 Uhr vorhersagen. Dabei wird mir eine Handlungsempfehlung (Kauf/Verkauf) ausgegeben und meine erwartete Rendite angezeigt. Dann handeln wir CFDs mit einem guten Hebel und werden reich ;)

Aktienvorhersage mit PHP AI

Als Datenbasis dienen mir alle Dax30-Kurse im 5 Minuten Takt der letzten Jahre. Ich habe die Daten seit 2015 (> 2.000.000 Datensätze) allerdings dauert das Training ewig... Zum ersten Test verwenden wir daher deutlicher weniger Daten (~40-000).

DAX30 Kurse in Echtzeit crawlen

Die AI zum Laufen zu bringen ist sehr einfach und in 3 Zeilen Code sofort gemacht. Die besteht nämlich nur aus Variablen definieren, Testen und Vorhersagen. Das war es schon. Viel aufwendiger ist es, die Daten zu beschaffen und in ein entsprechendes Format zu bringen.

Wer das Geld hat, kann sich natürlich einen Zugang zu einer Schnittstelle kaufen. Da ich das nicht möchte (und noch das Geld mit dieser AI generieren will ;) ), habe ich mir ein kleines Script geschrieben, das die Kurse alle 5 Minuten von finanzen.net abruft. Die Echtzeitkurse aller Aktien gibt es hier: Dax Realtimekruse.

Die Seite lässt sich sehr gut crawlen und die Daten ziehen:

$html = file_get_contents('http://www.finanzen.net/aktien/DAX-Realtimekurse');
$table = explode('<table class="table table-vertical-center">',$html); 
$table = explode('</table>',$table[1]);
$table = explode('</thead>',$table[0]);
$rows = explode('<tr>',$table[1]);
unset($rows[0]);
$rows = array_slice($rows,0,31);
foreach($rows AS $row){
	$cols = explode('',$row);

	$name = utf8_encode(strip_tags($cols[1]));
	$vortag = toNumber(strip_tags($cols[3]));
	$bid = toNumber(strip_tags($cols[4]));
	$ask = toNumber(strip_tags($cols[5]));
	$prozent = toNumber(strip_tags($cols[6]));
	$sql = "INSERT INTO dax30(name,vortag,bid,ask,prozent,zeit)VALUES(?,?,?,?,?,NOW())";
	$stmt = $db->prepare($sql);
	$stmt->bind_param('sdddd',$name,$vortag,$bid,$ask,$prozent);
	$stmt->execute();
	$stmt->close();

	echo $name.': Vortag '.$vortag.', Bid: '.$bid.', Ask: '.$ask.', Prozent: '.$prozent."";
}
function toNumber($n){
	return trim(str_replace('%','',str_replace(',','.',str_replace('.','',$n))));
}

Das war es schon. Zwar nicht der sauberste Code, aber dafür langt er. Die Funktion toNumber interpretiert den Eingabe Wert als Zahl, egal was drinsteht. Jetzt noch einen Cronjob alle 5 Minuten aufrufen lassen und ihr bekommt sehr schnell Daten. Denkt daran, dass nur von Montag - Freitag und nur von 9 bis 17:30 gehandelt wird.

PHP-ML installieren

Als AI verwenden wir die PHP-ML Bibliothek. Hier gibts den Quellcode auf Github und Hier die Dokumentation. Installation über Composer oder über Github runterladen:

composer require php-ai/php-ml

Die Daten vorbereiten

Nachdem wir genügend Daten (es langen schon die Daten von 1-2 Wochen) gesammelt haben, rufen wir diese jetzt ab und packen sie in ein großes Mehrdimensionales Array. Uns interessiert primär nur die Spalte "Prozent", also die prozentuale Entwicklung vom Schlusskurs des Vortags. Das machen wir so:

$sql = "SELECT prozent,DATE_FORMAT(zeit,'%d.%m.%Y'),DATE(zeit),name FROM dax30 WHERE TIME(zeit) >= '09:00:00' AND TIME(zeit) < '17:36:00' ORDER BY name ASC, zeit ASC";
$stmt = $db->prepare($sql);
$stmt->execute();
$stmt->bind_result($prozent,$datum,$datum2,$name);
$stmt->store_result();
$i = 0;
$prev = '';
$prevD = '';
while($stmt->fetch()){
	if($prev != $name || $datum != $prevD){
		$i = 0;
		$prev = $name;
		$prevD = $datum;
	}

	if($i < $maxInput) // $maxInput soll die Anzahl der heutigen Einträge sein
		$aktien[$name][$datum]['kurse'][] = $prozent;
	$aktien[$name][$datum]['schlusskurs'] = $prozent;
	$i++;
}
$stmt->free_result();
$stmt->close();

Da wir ja am Tag der Vorhersage die Kurse nur bis zum aktuellen Zeitpunkt kennen, soll die AI natürlich auch nur bis zu dieser Uhrzeit die Vortage trainieren.

Wir formatieren das Array nochmals um, damit wir es für die AI verwenden können. Die möchte nämlich 2 Arrays: Das TrainingsSet und das ResultSet. Im TrainingsSet sind alle Kurse des Tages bis 16:00 Uhr. Im ResultSet steht der jeweilige Schlusskurs um 17:30 Uhr:

foreach($aktien AS $name=>$aktie){
	$heute[$name] = array_pop($aktie); // Der heutige Tag soll natürlich nicht mitgetestet werden
	foreach($aktie AS $datum=>$aktieTag){
		$trainingsSet[] = $aktieTag["kurse"];
		$resultSet[] = $aktieTag["schlusskurs"];
	}
}

Welcher Estimator ist der richtige?

Wer in die Dokumentation von PHP-ML schaut, wird feststellen, dass dort viele verschiedene Estimator (= Schätzfunktion der KI) zur Verfügung stehen. Es gibt Classification, Regression, Clustering, usw. Neben der Vorbereitung der Daten ist die richtige Wahl des Estimators entscheidend. Entweder man probiert alle durch oder man geht gezielter vor:

Estimator Cheet Sheet PHP-AI

Quelle: http://scikit-learn.org/stable/tutorial/machine_learning_map/index.html

Classification

Classification wird verwendet um bestimmte Inputs zu klassifizieren. Hohoho. Spaß bei Seite: Man verwendet sie um die Inputs einer Gruppe zuzuweisen. Beispiel: Ihr habt als Input verschiedene Farben und wollt, dass die AI lernt, ob die Farbe hell oder dunkel ist.

Clustering

Clustering wird verwendet um seine Inputs verschiedenen Gruppen zuzuordnen. Beispielsweise könnte man verschiedene Eigenschaften von Menschen (Alter, Geschlecht, Einkommen) als Inputs verwenden und als Output hat man sowas wie Bildungsabschluss.

Regression

Eine Regression versucht Zusammenhänge auf quantitativer Basis zu beschreiben bzw. vorherzusagen. Die Inputs und Outputs sind also quantitative Werte. Beispielsweise: Aktienkurse!

Das hilft jetzt auch nicht viel weiter...

Das stimmt. Daher gibt es bei scikit-learn.org einen Flowchart zur Bestimmung des richtigen Estimators. Damit ist es relativ einfach, den am besten geeigneten Estimator zu finden.

In PHP-ML gibt es nur 2 verschiedene Möglichkeiten bei Regression: LeastSquares und SVR. Schauen wir oben auf unser CheetSheet, scheint SVR ganz gut zu passen.

PHP-ML: Die AI trainieren

Nachdem wir jetzt alles soweit haben, können wir anfangen die AI zu trainieren. Wie oben schon erwähnt, ist PHP nicht unbedingt die schnellste und beste Sprache für Machine Learning, daher übertreibt es nicht unbedingt mit der Datensatzgröße. Für 2.000.000 Daten hat er bei mir fast 4h gebraucht...

PHP-ML initialisieren

Wir definieren also die Regression mit dem Kernel "POLYNOMIAL" (LINEAR, RBF und SIGMOID haben bei uns keine guten Werte geliefert):

require_once '/var/www/vendor/autoload.php';
use Phpml\Regression\SVR;
use Phpml\SupportVectorMachine\Kernel;
use Phpml\ModelManager;

$regression = new SVR(Kernel::POLYNOMIAL, 3, 0.1, 10,0.3,0.1,3,200,true); 

Die Variablen in new SVR() haben bei mir die besten Ergebnisse geliefert. Natürlich könnt ihr damit rumspielen und testen.

Mit PHP-AI/PHP-ML trainieren

Oh yeah, jetzt gehts los. Und wir trainieren. Für das was hier passiert, ist der Code leider super unspektakulär:

$regression->train($trainingsSet, $resultSet);

Ja, das war es schon. Da wir oben die Daten so schöne vorbereitet haben, brauchen wir hier nichts weiter tun. Irgendwie hätte man sich mehr erwartet... Dass hier einiges passiert, merkt ihr an der Laufzeit de Skripts. Der Trainingsteil ist anspruchsvoll und braucht eine Weile abhängig von der Menge der Testdaten.

Training speichern für schnellere Vorhersagen

Optional und lohnt sich erst bei sehr großen Datensätzen. Das schöne an der PHP-AI ist, dass sie die Trainingsergebnisse speichern lässt, so dass wir nicht für jede Vorhersage, komplett neu trainieren müssen. Wir können also einfach das Training später öffnen und anhand dessen die Vorhersage treffen. Ist auch super, um verschiedene Einstellungen zu vergleichen, etc.

$filepath = VENDOR.'php-ai/php-ml/var/model.data';
$modelManager = new ModelManager();
$modelManager->saveToFile($this->regression, $filepath);

Um die Daten später laden zu können, müssen wir lediglich die model.data-Datei laden:

$filepath = VENDOR.'php-ai/php-ml/var/model_long.data';
$modelManager = new ModelManager();
$regression = $modelManager->restoreFromFile($filepath);

Die Vorhersage mit PHP-ML

Um den neuen Kurs vorhersagen zu können, brauchen wir natürlich die Kursdaten des aktuellen Tages (haben wir oben in $heute gespeichert) und dann hoffen wir, dass wir den Kurs um 17:30Uhr so genau wie möglich erhalten:

foreach($heute AS $name=>$predict){
	$predicted = round($regression->predict($predict["kurse"]),2);
	$predictedPerformance = $predicted - $predict["kurse"][(count($predict["kurse"])-1)];
	$kurs = $predict["kurse"][count($predict["kurse"])-1];
	echo $name.": Kurs: ".$kurs.", Predicted: ".$predicted.", Performance: ".$predictedPerformance."
"; }

Die Ausgabe schaut dann in etwa so aus:

Aktienvorhersage mit PHP-AI

Das heißt, bei allen Werten mit predicted < 0 sollte man beim CFD-Handel Verkaufen und bei > 0 kaufen. Damit das übersichtlicher und schöner ist und man auch einen Verlauf sieht, lasse ich die Predictions in der Datenbank speichern. IAuf einer Seite zeigt er mir eine Übersicht, deren Werte sich alle 5 Minuten aktualisieren:

Übersicht Aktienvorhersage PHP-AI

Die Übersicht zeigt mir genau welcher Trade sich lohnt und was ich handeln sollte. Falls die vorhergesagte Performance < 0,6% ist, bekomme ich keine Empfehlung. Falls sie größer als 5% ist, erscheint "Prüfen", da das sehr unwahrscheinlich ist und sich die AI wohl vertan hat. Im realen Modus sollte man eine Performance < 2.5% oder so wählen.

Zusammenfassung

Leider wird sich damit wohl kaum Geld verdienen lassen. Ich habe das ganze primär gebaut, um mich mit AIs und Machine Learning zu beschäftigen. Die PHP-AI/PHP-ML Bibliothek ist ziemlich cool und funktioniert gut. Allerdings ist der Regression-Estimator nicht 100% geeignet, liefert aber bei über 60% der Fälle korrekte Tendenzen. Je mehr Datensätze verwendet werden, umso stärker gehen die Tendenzen und die Extreme werden größer. Statt -0.46 erhält man dann z.B. -7,8. Das ist in unserem Anwendungsfall nicht ganz so ideal.

Interessanter und deutlich besser wird das ganze mit einem Recurrent Neural Network, wie zum Beispiel ein LSTM Network (Long Short-Term Memory Network). Damit ist es dann möglich, dass die AI, wie ein Mensch auch, sinnvolle Entscheidungen trifft in Anbetracht der Vergangenheit und früherer Ereignisse. Für PHP gibt es so etwas meines Wissens keine fertige Bibliothek und wird es wohl auch nie geben. Mit TensorFlow (Googles AI) ist das ganze möglich, dann aber mit Python statt PHP ;)

Prost, da Hansi

Weitere Artikel:

2018-elasticsearch-teil-2.jpg

Elasticsearch mit PHP

Im 2ten Teil der ElastSearch-Reihe zeige ich, wie ihr mit PHP von eurer Webseite aus auf ElasticSearch zugreifen könnt. Dabei erkläre ich die Suche, wie man Tippfehler berücksichtigt und was man noch so machen könnte.

brausteuerung-arduino-teil2.jpg

Programmierung der Brausteuerung

Der 2te Teil der Brausteuerung dreht sich um die Programmierung des Arduino. Schritt für Schritt erkläre ich anhand von Codebeispielen die wichtigsten Schritte und auf was es zu achten gilt.

0 Kommentare

Kommentar verfassen
Ersten Kommentar abgeben
Name:
E-Mail
Bewertung Qualätit:
Bewertung Lesbarkeit:
Bewertung Inhalt:
Überschrift:
Kommentar:
www.godlike.de

Diese Webseite verwendet Cookies, damit wir die Inhalte und Funktionen der Webseite optimal gestalten können. Durch die weitere Nutzung der Webseite stimmen Sie der Nutzung von Cookies zu.