FYI…

Unter /lost+found plaudere ich ein wenig aus dem Nähkästchen eines Softwareentwicklers und Administrators. Manchmal sind es auch nur Memos an mich selbst, weil ich mir manche Dinge schlicht nicht merken kann 😉 Alle veröffentlichten Tipps und Programme stehen Ihnen kostenlos und uneingeschränkt zur Verfügung. Bitte beachten Sie aber, dass jegliche Nutzung auf eigene Gefahr erfolgt und ich KEINERLEI GARANTIE übernehme. Kleinere Programme und Codeschnipsel können Sie per Cut/Paste direkt übernehmen. Bei längeren Programmen schreiben Sie mir bitte eine E-Mail und ich sende ihnen den (Quell-)Code zu.

HowTo: bitcoin.de API

Ich mag die Idee eines dezentralen digitalen Zahlungssystems. Und bevor die Difficulty explodierte und die Stromkosten die Erträge auffrassen, habe ich auch selbst „geschürft“. (Einen KNC-Miner habe ich immer noch im Regal stehen – man weiss ja nie 😉 Ob nun der Bitcoin der Weissheit letzter Schluss ist weiss ich nicht, doch wenn man es so verfolgt, scheint zumindest die Blockchain eine Zukunft zu haben.

Nachdem das Mining nicht mehr profitabel war, habe ich mich auf den Handel bei bitcoin.de verlegt. Und dank der bitcoin.de API lässt sich dieser Handel mittlerweile auch automatisieren. Ich habe mir also ein kleines Tradingsystem gebaut, das den Handel automatisch für mich abwickelt. Natürlich kann ich mit den Finanzprofis nicht mithalten und ich werde auch nicht reich damit, aber meine Strategie funktioniert (für mich) und so ein Handelssystem macht einfach Spaß.

Wenn man sich in den Foren so umsieht, scheint es doch einige Verständnisschwierigkeiten zu geben, wie man so eine (REST-)API nutzt. Nachfolgend möchte ich daher kurz zeigen, wie man sie verwendet und stelle vier einfache Kommandozeilen-Tools zur Verfügung, die als Basis für Ihr eigenes System dienen können. Und selbst wenn man sich kein eigenes Tradingsystem bauen will, kann man so wenigstens das Kickback einstreichen 😉

Was man braucht…

Die bitcoin.de-API ist klar strukturiert und einfach aufgebaut. Sie stellt alle Funktionen bereit, die man für den automatisierten Handel benötigt. Alle Parameter und Rückgabewerte sind in der Dokumentation ausführlich erklärt. Auf das Wie und Warum von REST-APIs möchte ich hier nicht weiter eingehen. Wer es genau wissen will, liest sich z.B. den entsprechenden Wikipedia-Artikel durch. Um die API nutzen zu können, benötigt man zuerst einmal einen Key und ein Secret, mit denen man sich gegenüber der API authentifiziert. Sie generieren die Key/Secret-Paare in den Einstellungen unter Sonstige Einstellungen -> Trading-API. Ohne ein solches Key/Secret-Paar ist die Nutzung der API nicht möglich.

bitcoin.de stellt eine beispielhafte Implementierung der API in PHP zur Verfügung, die ich nachfolgend auch nutze. Wir Unix-Menschen neigen dazu, komplexere Systeme aus einfachen (Kommandozeilen-)Tools zusammenzubauen. PHP ist daher für mich so gut wie jede andere Sprache auch. Auf ihrem Rechner muss also zusätzlich ein PHP-Interpreter installiert sein. Unter Linux sollte er zu den Bordmitteln gehören, seit Version 10.0.0 auch unter OS X. Für ältere OS X-Versionen und unter Windows empfehle ich die Installation von XAMPP. Zusätzlich müssen Sie noch die PHP-Implementierung TradingApiSdkv1.php bei bitcoin.de herunterladen.

Die Tools…

Ich habe vier einfache Tools geschrieben, die ihnen die direkte Nutzung der bitcoin.de API erlauben:

  • addbuyoffer.php – Stellt eine Kaufanfrage ein
  • addselloffer.php – Stellt eine Verkaufsanfrage ein
  • getoffer.php – Kauft/Verkauft ein konkretes Angebot
  • canceloffer.php – löscht eine Kauf-/Verkaufsanfrage
So funktioniert’s…

Wie man die PHP-API konkret einsetzt, möchte ich beispielhaft anhand von addbuyoffer.php zeigen, das wie folgt aufgerufen wird:

$ php addbuyoffer.php <preis> <menge> <minmenge>

Im ersten Schritt müssen wir die API-Implementierung einbinden:

<?php
require_once __DIR__ . '/TradingApiSdkv1.php';

und mit dem Key/Secret-Paar ein API-Objekt erzeugen:

$btc_api = new TradingApiSdk (<key>, <secret>);

Bei einem Kaufangebot übergeben wir den Preis, die Menge sowie die minimale Menge, die wir zu kaufen wünschen. Diese übernehmen wir aus der Kommandozeile in entsprechende Variablen

$preis = $argv [1];
$menge = $argv [2];
$minmenge = $argv [3];

Bitte beachten Sie, dass ich die einzelnen Elemente nicht weiter prüfe.  Bitte beachten Sie auch, dass die API bei den übergebenen Werten etwas empfindlich ist, d.h. Sie müssen mit Dezimalpunkten arbeiten und bei kleinen Werten eine 0 vor den Dezimalpunkt stellen. Natürlich kann man das abfangen und entsprechend aufbereiten, aber das überlasse ich dem geneigten Leser als Übung. Bevor wir die Kaufanfrage einstellen, sollten wir noch mal in uns gehen, ob auch wirklich alles stimmt:

print "$menge/$minmenge Bitcoins für $preis € kaufen";
$c = readline ( "? " );
if ($c != 'ja') {
   print "Abbruch\n";
   exit ( -1 );
}

Beantworten Sie diese Rückfrage mit etwas anderem als ‚ja‘, wird das Programm abgebrochen.

Nun folgt das eigentliche Herzstück des Programms:

try {
   $buy_order = $btc_api->doRequest ( TradingApiSdk::METHOD_CREATE_ORDER, array (
     'type' => TradingApiSdk::ORDER_TYPE_BUY,
     'max_amount' => $menge,
     'price' => $preis,
     'min_amount' => $minmenge,
     'new_order_for_remaining_amount' => 1
   ) );

} catch ( Exception $e ) {
   print "Exception: " . $e->getMessage ();
   exit(-2);
 }

if ($buy_order ['status_code'] != 201) {
   print $buy_order ['errors'] [0] ['message'];
   exit(-3);
 }

else {
   print "Kaufanfrage ".$buy_order['order_id']." erfolgreich eingestellt\n";
}

exit(0);

Das Einstellen unseres Kaufangebotes erfolgt durch einen Aufruf von doRequest. Dabei müssen wir die gewünschte Methode (in diesem Fall METHOD_CREATE_ORDER) sowie ein Array mit den benötigten Parametern wie z.B. Order-Typ (ORDER_TYPE_BUY), Preis, Menge etc. angeben. Welche Parameter für die jeweiligen Aufrufe benötigt werden, können Sie in der API-Dokumentation nachlesen.

Eigentlich war es das schon, aber wir müssen natürlich überprüfen, ob unser Request erfolgreich war. Beim Aufruf des Programms kann es zu zwei Arten von Fehlern kommen. Zum einen kann es Probleme mit der Internetverbindung geben, d.h. wir können unseren Request nicht erfolgreich an bitcoin.de senden.  Mögliche Fehlerursachen sind eine fehlende Internetverbindung, DNS-Probleme und ähnliche Dinge. Diese Art von Fehlern fängt der obige try/catch-Block ab. Kommt es zu einer solchen Exception (Ausnahme), wird die entsprechende  Fehlermeldung des Systems ausgegeben und das Programm beendet.

Bei der zweiten Art von Fehler war der Request selbst zwar erfolgreich, konnte von bitcoin.de aber nicht erfüllt werden, z.B. weil ein Angebot nicht mehr zur Verfügung steht, oder weil Sie fehlerhafte Parameter übergeben haben. Diese Art von Fehler können (müssen) wir aus der Response (Antwort) auf unseren Request herausfiltern. Die REST-API liefert ein Array im JSON-Format zurück, das alle relevanten Informationen enthält. Die PHP-API liefert uns diese Informationen in Form eines PHP-Arrays zurück. Innerhalb dieses Arrays liefert uns das Feld status_code den Status unserer Aktion. Bei unterschiedlichen Operationen zeigen unterschiedliche Statuscodes den Erfolg an. In unserem Fall steht der Code 201 für eine erfolgreiche eingestellte Kaufanfrage. Wie immer können Sie die exakten Codes für die jeweiligen Operationen in der API-Dokumentation nachlesen. Wird beim Einstellen eines Kaufangebots also ein Status ungleich 201 zurückgegeben, ist ein Fehler aufgetreten, den wir ausgeben, bevor  wir das Programm beenden. Wenn Sie sich lieber die gesamte Response ansehen wollen, ersetzen Sie die print-Anweisung durch

print_r($buy_order);

War unser Aufruf hingegen erfolgreich, gibt uns das Programm die Trading-ID zurück. Und das war es auch schon.

Falls Sie die Tools nutzen wollen, schreiben Sie mir doch eine E-Mail und ich schicke sie ihnen zu. Alternativ können Sie den Code einfache aus dem Beitrag kopieren. Er ist direkt lauffähig. Wie immer erfolgt die Nutzung aber auf eigene Gefahr und unter Ausschluss jeglicher Garantie. Fragen beantworte ich innerhalb gewisser Grenzen.

Ich habe auch überlegt, ob ich die API in Python umschreibe, aktueller Bedarf besteht da bei mir aber nicht. Falls sich ein Sponsor findet, würde ich mich aber darum kümmern.

Falls dieser Beitrag hilfreich war, freue ich mich über eine Spende an
1YsWuiE58G8dVybEkWaBBFaRQgAULupEk.

Happy Trading….

Tool: xml2csv.pl

XML ist als Format für den Import und Export von Daten weit verbreitet, doch häufig ist es gar nicht so einfach, das XML-Format einer Anwendung in eine andere zu übernehmen. Hier ist CSV meisst der kleinste gemeinsame Nenner. xml2csv.pl wandelt die verschachtelt angeordneten Daten einer XML-Datei in eine Zeilen/spalten-orientierte CSV-Datei um, die dann (relativ) einfach in eine andere Anwendung import werden kann. Ich verwende es beispielsweise in Kombination mit mapcsv.pl zum Massenimport von Produktdaten in Magento. Das Tool ist in Perl geschrieben und nutzt den streambasierten XML::Parser zur XML-Verarbeitung.

Beim Aufruf übergeben Sie einfach die XML-Datei

$ xml2csv.pl <datei.xml>

Die Ausgabe erfolgt dann über stdout, kann also direkt über eine Pipe weiterverarbeitet, oder bei Bedarf in eine Datei umgeleitet werden.

Trenn- und das Quoting-Zeichen für die CSV-Felder sind fest im Code kodiert. Wer das über die Kommandozeile festlegen möchte, kann passende Optionen selbst ergänzen 😉

Ebenfalls fest kodiert ist ein (optionaler) Start-Tag, der die Konvertierung einschränkt und ausserhalb des Start-Tags liegende Daten ausspart.

Falls Sie dieses Tool nutzen wollen, schreiben Sie mir einfach eine E-Mail und ich schicke es ihnen zu. Wie immer erfolgt die Nutzung aber auf eigene Gefahr und unter Ausschluss jeglicher Garantie.

Tool: mapcsv.pl

Auch wenn sich XML und JSON großer Beliebtheit erfreuen, ist  CSV immer noch ein häufig eingesetztes Datenaustauschformat und oft der kleinste gemeinsame Nenner für den Austausch von Daten zwischen verschiedenen Anwendungen. Obwohl es so einfach aussieht, ist die Verarbeitung von CSV-Dateien überraschend komplex, wenn man sich mal intensiver damit beschäftigt. Doch das Parsing selbst soll hier nicht das Thema sein. Vielmehr möchte ich  mapcsv.pl vorstellen. Mit diesem einfachen (Kommandozeilen-)Tool können Sie eine CSV-Datei in eine andere CSV-Datei konvertieren. Ich benutze es beispielsweise für den Import von Daten aus einem Warenwirtschaftssystem in einen Magento-Shop, aber auch zur Generierung einfacher Zeitreihen für die Weiterverarbeitung in R. Das Tool ist in Perl geschrieben und nutzt Text::CSV_XS für das eigentliche CSV-Parsing.

Damit dieses Mapping funktioniert, übergeben Sie beim Aufruf des Programms neben der CSV-Quelldatei eine Mapping-Datei, die die gewünschte Abbildung beschreibt:

$ mapcsv.pl <map> <source.csv>

Die Ausgabe erfolgt über stdout, kann also direkt über eine Pipe weiterverarbeitet, oder bei Bedarf in eine Datei umgeleitet werden.

Ein einfaches Beispiel…

…sieht wie folgt aus:

$ mapcsv.pl stock.map products.csv >magento.stock.csv

products.csv enthält die im CSV-Format exportierten Produkte aus einem Warenwirtschaftssystem. Aus dieser Datei sollen drei Felder für den Import in einen Magento-Shop extrahiert werden. Die Datei stock.map beschreibt das gewünschte Mapping:

sku;Article_Color_Ean_Number
qty;Article_Color_Ean_Stock
max_sale_qty;Article_Color_Ean_Stock

Das WWS-Feld Article_Color_Ean_Number wird auf das Magento-Feld sku abgebildet. Der Lagerbestand Article_Color_Ean_Stock aus dem WWS wird für den Magento-Lagerbestand qty eingesetzt, und so weiter.

Darf’s ein bisschen mehr sein?

Neben diesem einfachen, direkten Mapping gibt es noch einige weitere Möglichkeiten. So kann man einem Zielfeld beispielsweise eine Konstante zuweisen:

tax_class_id;=2

oder ein Zielfeld einfach leer lassen:

backorders;

Auch einfache bedingte Zuweisungen sind möglich:

is_in_stock;?Article_Color_Ean_Stock > '0' '1'

schuhgroesse_damen_d;?Article_Sizerange eq 'Schuhgrößen Damen D' Article_Color_Ean_Size

Das Tool kennt eq, ne, lt, gt für alphanumerische, sowie < und > für numerische Vergleiche.

Die Möglichkeiten sind also vielfältig und das Tool selbst kann recht einfach an eigene Erfordernisse angepasst werden (so wäre etwa ein echter ternärer Operator denkbar, den ich mir mangels Zeit gespart habe).

Falls Sie dieses Tool nutzen wollen, schreiben Sie mir doch eine E-Mail und ich schicke es ihnen zu. Wie immer erfolgt die Nutzung aber auf eigene Gefahr und unter Ausschluss jeglicher Garantie.

Softwareentwicklung & Systemadministration