2017-10-11 4 views
0

ich eine FIX-Engine basiert auf Quickfix/N writting, die für den Handel Exekutionen (ExecutionReport) hören und sie in einer Datenbank speichern.QuickFix optionale Felder überprüfen Wert vorhanden

einen Feldwert von der API Anfordern wirft einen FieldNotFoundException, wenn der Wert nicht in der empfangenen Nachricht ist. Ein Aufruf von executionReport.Account löst beispielsweise die Ausnahme aus, wenn das Konto nicht vorhanden ist.

Da einige Felder sind optional, ich habe ausdrücklich für die Existenz des Feldwertes zu überprüfen, bevor es zu bekommen. Ich habe zwei Möglichkeiten dafür:

Möglichkeit 1: executionReport.IsSetAccount() ? executionReport.Account : null;

Möglichkeit 2:

try 
     { 
      return executionReport.Account.getValue(); 
     } 
     catch (Exception e) 
     { 
      return null; 

     } 

Die erste Option ist sauber, aber ich finde es wirklich schwer, kann der zweite in eine verallgemeinern Hilfsfunktion aber es geht gegen die API Philosophie und ich habe das Gefühl ich mache etwas falsch.

Dann meine Frage ist:

  • Gibt es eine anderen sauberen/richtigen Weg, um den Job zu tun?
  • Oder ist mein Verständnis des Protokolls/API völlig falsch? Ich habe das Gefühl, ich bekomme das Problem nicht richtig.

    Vielen Dank

+0

ich denke, das Problem bekommen - einige Felder sind optional. Nun, das ist eine Eigenschaft des FIX-Protokolls. Es ist das gleiche für fast jede FIX-Nachricht. Es gibt Transaktionen viele verschiedene Arten von ... – rupweb

Antwort

1

Sie haben nicht wirklich erklärt, warum diejenigen, unrein sind, so dass ich bin mir nicht sicher, was genau Sie suchen.

Die einzige Alternative, die ich denken kann, ist dies:

// Both these lines are functionally identical. 
executionReport.IsSetField(1) 
executionReport.IsSetField(QuickFix.Fields.Tags.Account) 

// 1 is the tag for Account. 
// The second line just uses the tag enum to get 1 
// instead of hardcoding the int. 

Ist das besser?

+0

Ja, es ist eine Alternative, gibt es den Vorteil, den validatoion zu verallgemeinern. Aber wie es in der API-Dokumentation erwähnt wird, benötigt es eine zusätzliche Boiler-Plate-Logik und wird nicht empfohlen, da es weniger typsicher ist. – Fede

+0

Ich werde nicht sagen, dass die zwei Optionen, die nicht sauber sind, sie beide den Job zu erledigen und in anycase Ich habe keine Wahl, um die ExecutionReport Einheit, die von der API zur Verfügung gestellt anzupassen. Aber das ist der Punkt, die API zwingt mich, die Felder zuvor aufwendig zu prüfen, um das zu tun. Dann läuft meine zweite Option gegen diesen Vertrag. Die erste Option ist gut und "sauber", aber es ist wirklich schwer, da es viele Felder gibt. Ist wie ein DTO mit Hunderten von Gettern und überprüfe explizit jedes Mal, wenn ich einen Getter anrufe. – Fede

+0

Nun, ich denke nicht, dass es eine sauberere Lösung gibt.Die Felder sind optional, und Sie können keinen Wert abrufen, der nicht vorhanden ist. Daher müssen Sie deren Anwesenheit überprüfen. Es gibt keinen Weg um ihn herum. –

0

Ok, zu vermeiden, dass ein Adapter-Klasse zu schreiben oder sie jedes Mal überprüfen, kann ich ein ExecutionReport Feld verwenden möchten, habe ich eine Erweiterung Klasse, die die Arbeit machen:

public static class ExecutionReportExtensions 
{ 
    public static string AccountValue(this QuickFix.FIX44.ExecutionReport executionReport) 
    { 
     if (executionReport.IsSetAccount()) 
      return executionReport.Account.getValue(); 
     return null; 
    } 

und verwenden Sie es dann wie folgt :

executexecutionReport.AccountValue()

Verwandte Themen