Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Azure Stream Analytics unterstützt erweiterte Analysen durch die Kombination aus SQL-Sprache, JavaScript benutzerdefinierten Funktionen (UDFs) und benutzerdefinierten Aggregaten (UDAs). Zu den erweiterten Analysen gehören Online-Schulungen zum maschinellen Lernen und Bewertung sowie zustandsbehaftete Prozesssimulationen. In diesem Artikel wird beschrieben, wie Sie eine lineare Regression in einem Azure Stream Analytics Auftrag durchführen, der kontinuierliche Schulungen und Bewertungen in einem Hochfrequenzhandelsszenario durchführt.
Voraussetzungen
- Ein Azure-Abonnement. Wenn Sie kein Konto haben, erstellen Sie ein kostenloses Konto.
- Ein Azure Stream Analytics Auftrag.
- Ein Azure Event Hubs-Namespace und ein Event Hub.
- Vertrautheit mit der Stream Analytics-Abfragesprache.
- (Optional) Ein Power BI Konto, wenn Sie die Ausgabe visualisieren möchten.
Workflow für den Hochfrequenzhandel
Der logische Fluss des Hochfrequenzhandels lautet:
- Abrufen von Echtzeitkursen von einer Wertpapierbörse.
- Erstellung eines Prognosemodells auf Basis der Kursnotierungen, um die Kursbewegung vorherzusagen.
- Kauf- oder Verkaufsaufträge erteilen, um von der korrekten Vorhersage von Kursbewegungen zu profitieren.
Für dieses Szenario ist Folgendes erforderlich:
- Ein Kursdatenfeed in Echtzeit.
- Ein Vorhersagemodell, das auf Echtzeit-Kursnotierungen angewendet werden kann.
- Eine Handelssimulation, die den Gewinn oder Verlust des Handelsalgorithmus veranschaulicht.
Feed mit Echtzeit-Kursnotierungen
Important
Die in diesem Abschnitt referenzierte IEX Trading WebSocket-API (iextrading.com) wurde eingestellt. IEX Cloud bietet jetzt Marktdaten über IEX Cloud mit unterschiedlichen Authentifizierungs- und Endpunkten. Aktualisieren Sie die URL und Authentifizierung in Ihrer Implementierung entsprechend.
Important
Die NuGet-Pakete SocketIoClientDotNet und WindowsAzure.ServiceBus, die in diesem Beispiel verwendet werden, sind veraltet. Verwenden Sie für neue Projekte eine aktuelle Socket.IO Clientbibliothek und das Azure.Messaging.EventHubs-Paket mit EventHubProducerClient anstelle der älteren EventHubClient.
Investors Exchange (IEX) bot früher kostenlose Gebots- und Nachfragekurse in Echtzeit über socket.io an. Sie können ein einfaches Konsolenprogramm schreiben, um Echtzeit-Kurse zu empfangen und sie an Azure Event Hubs als Datenquelle zu pushen. Der folgende Code ist ein Skelett des Programms. Der Code lässt der Kürze halber die Fehlerbehandlung weg. Sie müssen auch die SocketIoClientDotNet Und WindowsAzure.ServiceBus NuGet-Pakete in Ihr Projekt einschließen.
using Quobject.SocketIoClientDotNet.Client;
using Microsoft.ServiceBus.Messaging;
var symbols = "msft,fb,amzn,goog";
var eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, eventHubName);
var socket = IO.Socket("https://ws-api.iextrading.com/1.0/tops");
socket.On(Socket.EVENT_MESSAGE, (message) =>
{
eventHubClient.Send(new EventData(Encoding.UTF8.GetBytes((string)message)));
});
socket.On(Socket.EVENT_CONNECT, () =>
{
socket.Emit("subscribe", symbols);
});
Vorsicht
Dieses Codebeispiel dient nur zur Veranschaulichung. Der IEX WebSocket-API-Endpunkt und die hier verwendeten NuGet-Pakete sind nicht mehr verfügbar. Verwenden Sie diesen Code nicht in der Produktion. Aktuelle Alternativen finden Sie weiter oben in den WICHTIGen Hinweisen in diesem Abschnitt.
Hier sind einige generierte Beispielereignisse:
{"symbol":"MSFT","marketPercent":0.03246,"bidSize":100,"bidPrice":74.8,"askSize":300,"askPrice":74.83,"volume":70572,"lastSalePrice":74.825,"lastSaleSize":100,"lastSaleTime":1506953355123,"lastUpdated":1506953357170,"sector":"softwareservices","securityType":"commonstock"}
{"symbol":"GOOG","marketPercent":0.04825,"bidSize":114,"bidPrice":870,"askSize":0,"askPrice":0,"volume":11240,"lastSalePrice":959.47,"lastSaleSize":60,"lastSaleTime":1506953317571,"lastUpdated":1506953357633,"sector":"softwareservices","securityType":"commonstock"}
{"symbol":"MSFT","marketPercent":0.03244,"bidSize":100,"bidPrice":74.8,"askSize":100,"askPrice":74.83,"volume":70572,"lastSalePrice":74.825,"lastSaleSize":100,"lastSaleTime":1506953355123,"lastUpdated":1506953359118,"sector":"softwareservices","securityType":"commonstock"}
{"symbol":"FB","marketPercent":0.01211,"bidSize":100,"bidPrice":169.9,"askSize":100,"askPrice":170.67,"volume":39042,"lastSalePrice":170.67,"lastSaleSize":100,"lastSaleTime":1506953351912,"lastUpdated":1506953359641,"sector":"softwareservices","securityType":"commonstock"}
{"symbol":"GOOG","marketPercent":0.04795,"bidSize":100,"bidPrice":959.19,"askSize":0,"askPrice":0,"volume":11240,"lastSalePrice":959.47,"lastSaleSize":60,"lastSaleTime":1506953317571,"lastUpdated":1506953360949,"sector":"softwareservices","securityType":"commonstock"}
{"symbol":"FB","marketPercent":0.0121,"bidSize":100,"bidPrice":169.9,"askSize":100,"askPrice":170.7,"volume":39042,"lastSalePrice":170.67,"lastSaleSize":100,"lastSaleTime":1506953351912,"lastUpdated":1506953362205,"sector":"softwareservices","securityType":"commonstock"}
{"symbol":"GOOG","marketPercent":0.04795,"bidSize":114,"bidPrice":870,"askSize":0,"askPrice":0,"volume":11240,"lastSalePrice":959.47,"lastSaleSize":60,"lastSaleTime":1506953317571,"lastUpdated":1506953362629,"sector":"softwareservices","securityType":"commonstock"}
Note
Der Zeitstempel des Ereignisses lautet lastUpdated (in Epochenzeit).
Prädiktives Modell für den Hochfrequenzhandel
Für diese Demonstration verwendet das Beispiel ein lineares Modell, das in Order Imbalance Based Strategy in High Frequency Algorithmic Trading beschrieben ist.
„Volume Order Imbalance“ (VOI) ist eine Funktion des Geld-/Briefkurses (aktuell und letzter Tick-Vorgang). Das Papier identifiziert die Korrelation zwischen VOI und zukünftiger Preisbewegung. Damit wird ein lineares Modell zwischen den letzten fünf VOI-Werten und der Preisänderung der nächsten zehn Takten erstellt. Das Modell wird mit den Daten des Vortags per linearer Regression trainiert.
Das trainierte Modell macht dann Kursänderungsvorhersagen auf Kursen am aktuellen Handelstag in Echtzeit. Wenn das Modell eine große Preisänderung vorhersagt, führt es einen Trade aus. Je nach Schwellenwerteinstellung kann ein einzelner Kurs Tausende von Trades während eines Handelstages generieren.
In den folgenden Abschnitten wird gezeigt, wie Sie die Schulungs- und Vorhersagevorgänge in einem Azure Stream Analytics Auftrag ausdrücken. Die vollständige Abfrage ist eine einzelne WITH Anweisung, die aus allgemeinen Tabellenausdrücken (CTEs) besteht, die eine Pipeline bilden:
| CTE-Stufe | Purpose |
|---|---|
typeconvertedquotes |
Konvertieren von unformatierten Eingabefeldern in richtige SQL-Typen |
timefilteredquotes |
Kursnotierungen auf die Handelszeiten filtern und ungültige Daten entfernen |
shiftedquotes |
Verwenden Sie LAG, um die Bid-/Ask-Werte des vorherigen Ticks abzurufen. |
currentPriceAndVOI |
Berechnen des Volume Order Imbalance (VOI) aus aktuellem und vorherigem Tick |
shiftedPriceAndShiftedVOI |
Erstellen Sie Sequenzen von 10 aufeinanderfolgenden Mittelpreisen und 2 aufeinanderfolgenden VOI-Werten |
modelInput |
Daten in Merkmalsvektoren umformen (VOI als x, Preisdifferenz als y) |
modelagg / modelparambs / model |
Trainieren eines zweivariablen linearen Regressionsmodells mithilfe von SUMME- und AVG-Aggregaten |
shiftedVOI / VOIAndModel / VOIANDModelJoined |
Verknüpfen aktueller VOI-Werte mit dem trainierten Modell des vorigen Tages |
prediction |
Berechnen der erwarteten zukünftigen Preisänderung (efpc) aus dem Modell |
tradeSignal |
Kauf-/Verkaufssignale generieren, wenn efpc den Schwellenwert von ±0,02 überschreitet |
Note
Für diese Abfrage ist Azure Stream Analytics-Kompatibilitätsstufe 1.1 oder höher erforderlich, bei der die Groß-/Kleinschreibung der Feldnamen beibehalten wird, um ein vorhersehbares Verhalten mit UDAs zu gewährleisten.
Eingabefelder für Anführungszeichen bereinigen und konvertieren
Die erste CTE in der Azure Stream Analytics-Abfrage konvertiert die Kursrohdaten aus Event Hubs in korrekt typisierte SQL-Spalten. DATEADD wandelt epochenzeit (Unix Millisekunden) in Datetime um. TRY_CAST erzwingt die Datentypen, ohne dass die Abfrage fehlschlägt. Wandeln Sie Eingabefelder in die erwarteten Datentypen um, um unerwartetes Verhalten bei Manipulation oder Vergleich der Felder zu vermeiden.
WITH
typeconvertedquotes AS (
/* convert all input fields to proper types */
SELECT
System.Timestamp AS lastUpdated,
symbol,
DATEADD(millisecond, CAST(lastSaleTime as bigint), '1970-01-01T00:00:00Z') AS lastSaleTime,
TRY_CAST(bidSize as bigint) AS bidSize,
TRY_CAST(bidPrice as float) AS bidPrice,
TRY_CAST(askSize as bigint) AS askSize,
TRY_CAST(askPrice as float) AS askPrice,
TRY_CAST(volume as bigint) AS volume,
TRY_CAST(lastSaleSize as bigint) AS lastSaleSize,
TRY_CAST(lastSalePrice as float) AS lastSalePrice
FROM quotes TIMESTAMP BY DATEADD(millisecond, CAST(lastUpdated as bigint), '1970-01-01T00:00:00Z')
),
timefilteredquotes AS (
/* filter between 7am and 1pm PST, 14:00 to 20:00 UTC */
/* clean up invalid data points */
SELECT * FROM typeconvertedquotes
WHERE DATEPART(hour, lastUpdated) >= 14 AND DATEPART(hour, lastUpdated) < 20 AND bidSize > 0 AND askSize > 0 AND bidPrice > 0 AND askPrice > 0
),
Vorherige Tick-Werte mit LAG abrufen
Die nächste CTE in der Azure Stream Analytics-Abfrage verwendet die LAG-Funktion, um den Geld-/Briefkurs und die Größe des vorherigen Ticks für jedes Wertpapiersymbol abzurufen. Ein Wert von einer Stunde für LIMIT DURATION wird willkürlich gewählt. Anhand der Kursfrequenz können Sie den vorherigen Tick ermitteln, indem Sie eine Stunde zurückblicken.
shiftedquotes AS (
/* get previous bid/ask price and size in order to calculate VOI */
SELECT
symbol,
(bidPrice + askPrice)/2 AS midPrice,
bidPrice,
bidSize,
askPrice,
askSize,
LAG(bidPrice) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS bidPricePrev,
LAG(bidSize) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS bidSizePrev,
LAG(askPrice) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS askPricePrev,
LAG(askSize) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS askSizePrev
FROM timefilteredquotes
),
Berechnen des Volumenreihenfolgeungleichgewichts (VOI)
Die nächste CTE berechnet den VOI-Wert aus den Daten für den Geld-/Briefkurs des aktuellen und des vorherigen Ticks. Die Abfrage filtert Nullwerte für Fälle heraus, in denen kein vorheriger Tick existiert.
currentPriceAndVOI AS (
/* calculate VOI */
SELECT
symbol,
midPrice,
(CASE WHEN (bidPrice < bidPricePrev) THEN 0
ELSE (CASE WHEN (bidPrice = bidPricePrev) THEN (bidSize - bidSizePrev) ELSE bidSize END)
END) -
(CASE WHEN (askPrice < askPricePrev) THEN askSize
ELSE (CASE WHEN (askPrice = askPricePrev) THEN (askSize - askSizePrev) ELSE 0 END)
END) AS VOI
FROM shiftedquotes
WHERE
bidPrice IS NOT NULL AND
bidSize IS NOT NULL AND
askPrice IS NOT NULL AND
askSize IS NOT NULL AND
bidPricePrev IS NOT NULL AND
bidSizePrev IS NOT NULL AND
askPricePrev IS NOT NULL AND
askSizePrev IS NOT NULL
),
Erstellen von Featuresequenzen für Modellschulungen
Die nächste CTE verwendet LAG erneut, um eine Sequenz mit zwei aufeinander folgenden VOI-Werten zu erstellen, gefolgt von 10 aufeinander folgenden Mid-Price-Werten. Diese Sequenzen bilden die Schulungsdaten für das lineare Regressionsmodell.
shiftedPriceAndShiftedVOI AS (
/* get 10 future prices and 2 previous VOIs */
SELECT
symbol,
midPrice AS midPrice10,
LAG(midPrice, 1) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice9,
LAG(midPrice, 2) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice8,
LAG(midPrice, 3) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice7,
LAG(midPrice, 4) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice6,
LAG(midPrice, 5) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice5,
LAG(midPrice, 6) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice4,
LAG(midPrice, 7) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice3,
LAG(midPrice, 8) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice2,
LAG(midPrice, 9) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice1,
LAG(midPrice, 10) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS midPrice,
LAG(VOI, 10) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS VOI1,
LAG(VOI, 11) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS VOI2
FROM currentPriceAndVOI
),
Daten in Featurevektoren umformen
Im nächsten CTE werden die Preis- und VOI-Sequenzen in Featurevektoren für ein zweivariables lineares Modell umgestaltet, wobei VOI-Werte die unabhängigen Variablen (x1, x2) und die durchschnittliche zukünftige Preisänderung die abhängige Variable (y) sind. Ereignisse mit unvollständigen Daten werden herausgefiltert.
modelInput AS (
/* create feature vector, x being VOI, y being delta price */
SELECT
symbol,
(midPrice1 + midPrice2 + midPrice3 + midPrice4 + midPrice5 + midPrice6 + midPrice7 + midPrice8 + midPrice9 + midPrice10)/10.0 - midPrice AS y,
VOI1 AS x1,
VOI2 AS x2
FROM shiftedPriceAndShiftedVOI
WHERE
midPrice1 IS NOT NULL AND
midPrice2 IS NOT NULL AND
midPrice3 IS NOT NULL AND
midPrice4 IS NOT NULL AND
midPrice5 IS NOT NULL AND
midPrice6 IS NOT NULL AND
midPrice7 IS NOT NULL AND
midPrice8 IS NOT NULL AND
midPrice9 IS NOT NULL AND
midPrice10 IS NOT NULL AND
midPrice IS NOT NULL AND
VOI1 IS NOT NULL AND
VOI2 IS NOT NULL
),
Trainieren des linearen Regressionsmodells mit SUMME und AVG
Da Azure Stream Analytics keine integrierte lineare Regressionsfunktion hat, verwendet die Abfrage SUM und AVG Aggregate, um die Koeffizienten (a, b1, b2) für das lineare Regressionsmodell mit zwei Variablen zu berechnen. Das Modell wird täglich neu trainiert, wobei ein 24-stündiges Tumbling-Window verwendet wird.
modelagg AS (
/* get aggregates for linear regression calculation,
http://faculty.cas.usf.edu/mbrannick/regression/Reg2IV.html */
SELECT
symbol,
SUM(x1 * x1) AS x1x1,
SUM(x2 * x2) AS x2x2,
SUM(x1 * y) AS x1y,
SUM(x2 * y) AS x2y,
SUM(x1 * x2) AS x1x2,
AVG(y) AS avgy,
AVG(x1) AS avgx1,
AVG(x2) AS avgx2
FROM modelInput
GROUP BY symbol, TumblingWindow(hour, 24, -4)
),
modelparambs AS (
/* calculate b1 and b2 for the linear model */
SELECT
symbol,
(x2x2 * x1y - x1x2 * x2y)/(x1x1 * x2x2 - x1x2 * x1x2) AS b1,
(x1x1 * x2y - x1x2 * x1y)/(x1x1 * x2x2 - x1x2 * x1x2) AS b2,
avgy,
avgx1,
avgx2
FROM modelagg
),
model AS (
/* calculate a for the linear model */
SELECT
symbol,
avgy - b1 * avgx1 - b2 * avgx2 AS a,
b1,
b2
FROM modelparambs
),
Bewertung aktueller Kurse mit dem Modell des Vortags
Um das trainierte lineare Regressionsmodell des vorherigen Tages zum Bewerten des aktuellen Ereignisses zu verwenden, verknüpft die Abfrage die Anführungszeichen mit den Modellkoeffizienten. Anstatt JOIN zu verwenden, verwendet die Abfrage UNION , um Modellereignisse und Anführungszeichenereignisse in einem einzigen Datenstrom zu kombinieren. Anschließend wird lag verwendet, um die Ereignisse mit dem Modell des vorigen Tages zu koppeln, sodass Sie genau eine Übereinstimmung erhalten. Aufgrund des Wochenendes sieht die Abfrage drei Tage (72 Stunden) zurück. Wenn eine einfache JOIN verwendet würde, würden Sie für jedes Quote-Ereignis drei Modelle erhalten.
shiftedVOI AS (
/* get two consecutive VOIs */
SELECT
symbol,
midPrice,
VOI AS VOI1,
LAG(VOI, 1) OVER (PARTITION BY symbol LIMIT DURATION(hour, 1)) AS VOI2
FROM currentPriceAndVOI
),
VOIAndModel AS (
/* combine VOIs and models */
SELECT
'voi' AS type,
symbol,
midPrice,
VOI1,
VOI2,
0.0 AS a,
0.0 AS b1,
0.0 AS b2
FROM shiftedVOI
UNION
SELECT
'model' AS type,
symbol,
0.0 AS midPrice,
0 AS VOI1,
0 AS VOI2,
a,
b1,
b2
FROM model
),
VOIANDModelJoined AS (
/* match VOIs with the latest model within 3 days (72 hours, to take the weekend into account) */
SELECT
symbol,
midPrice,
VOI1 as x1,
VOI2 as x2,
LAG(a, 1) OVER (PARTITION BY symbol LIMIT DURATION(hour, 72) WHEN type = 'model') AS a,
LAG(b1, 1) OVER (PARTITION BY symbol LIMIT DURATION(hour, 72) WHEN type = 'model') AS b1,
LAG(b2, 1) OVER (PARTITION BY symbol LIMIT DURATION(hour, 72) WHEN type = 'model') AS b2
FROM VOIAndModel
WHERE type = 'voi'
),
Generieren von Handelssignalen aus Vorhersagen
Die endgültigen CTEs berechnen die erwartete zukünftige Preisänderung (efpc), indem die lineare Regressionsformel (a + b1 * x1 + b2 * x2) angewendet und dann Kauf-/Verkaufssignale basierend auf einem ±0,02-Schwellenwert generiert werden. Ein Handelswert von 10 bedeutet Kauf. Ein Handelswert von -10 bedeutet „Verkaufen“.
prediction AS (
/* make prediction if there is a model */
SELECT
symbol,
midPrice,
a + b1 * x1 + b2 * x2 AS efpc
FROM VOIANDModelJoined
WHERE
a IS NOT NULL AND
b1 IS NOT NULL AND
b2 IS NOT NULL AND
x1 IS NOT NULL AND
x2 IS NOT NULL
),
tradeSignal AS (
/* generate buy/sell signals */
SELECT
DateAdd(hour, -7, System.Timestamp) AS time,
symbol,
midPrice,
efpc,
CASE WHEN (efpc > 0.02) THEN 10 ELSE (CASE WHEN (efpc < -0.02) THEN -10 ELSE 0 END) END AS trade,
DATETIMEFROMPARTS(DATEPART(year, System.Timestamp), DATEPART(month, System.Timestamp), DATEPART(day, System.Timestamp), 0, 0, 0, 0) as date
FROM prediction
),
Testen der Handelsstrategie mit einer Simulation
Testen Sie nach dem Generieren der Handelssignale, wie effektiv die Handelsstrategie ist, ohne real zu handeln.
Dieser Test verwendet einen UDA mit einem Hopping-Fenster, das minütlich einen Hop durchführt. Die Gruppierung am Datum und die HAVING-Klausel stellen sicher, dass das Fenster nur Ereignisse enthält, die zum selben Tag gehören. Bei einem Hopping-Fenster über zwei Tage hinweg teilt das Datum in GROUP BY die Gruppierung in den vorherigen und den aktuellen Tag auf. Die HAVING-Klausel filtert die Fenster heraus, die am aktuellen Tag enden, aber zum Vortag gruppiert sind.
simulation AS
(
/* perform trade simulation for the past 7 hours to cover an entire trading day, and generate output every minute */
SELECT
DateAdd(hour, -7, System.Timestamp) AS time,
symbol,
date,
uda.TradeSimulation(tradeSignal) AS s
FROM tradeSignal
GROUP BY HoppingWindow(minute, 420, 1), symbol, date
Having DateDiff(day, date, time) < 1 AND DATEPART(hour, time) < 13
)
Die JavaScript UDA initialisiert alle Akkumulatoren in der init Funktion, berechnet den Zustandsübergang mit jedem Ereignis, das dem Fenster hinzugefügt wird, und gibt die Simulationsergebnisse am Ende des Fensters zurück. Bei der Simulation werden pro Handel 10 Aktien einer Aktie gehalten oder geshortet. Die Transaktionskosten betragen pauschal $8. In der folgenden Tabelle sind die vier Handelsaktionen aufgeführt, die von der UDA ausgeführt werden:
| Zustand | Signal | Action | Position danach |
|---|---|---|---|
| Keine aktuelle Holding | Kaufen (10) | Kaufen, um zu öffnen | Long |
| Keine aktuelle Holding | Verkaufen (-10) | Sell to open (short) | Short |
| Long-Position | Verkaufen (-10) | Sell to close, dann Sell to open (short) | Short |
| Short-Position | Kaufen (10) | Buy to close, dann Buy to open | Long |
function main() {
var TRADE_COST = 8.0;
var SHARES = 10;
this.init = function () {
this.own = false;
this.pos = 0;
this.pnl = 0.0;
this.tradeCosts = 0.0;
this.buyPrice = 0.0;
this.sellPrice = 0.0;
this.buySize = 0;
this.sellSize = 0;
this.buyTotal = 0.0;
this.sellTotal = 0.0;
}
this.accumulate = function (tradeSignal, timestamp) {
if(!this.own && tradeSignal.trade == 10) {
// Buy to open
this.own = true;
this.pos = 1;
this.buyPrice = tradeSignal.midprice;
this.tradeCosts += TRADE_COST;
this.buySize += SHARES;
this.buyTotal += SHARES * tradeSignal.midprice;
} else if(!this.own && tradeSignal.trade == -10) {
// Sell to open
this.own = true;
this.pos = -1
this.sellPrice = tradeSignal.midprice;
this.tradeCosts += TRADE_COST;
this.sellSize += SHARES;
this.sellTotal += SHARES * tradeSignal.midprice;
} else if(this.own && this.pos == 1 && tradeSignal.trade == -10) {
// Sell to close
this.own = false;
this.pos = 0;
this.sellPrice = tradeSignal.midprice;
this.tradeCosts += TRADE_COST;
this.pnl += (this.sellPrice - this.buyPrice)*SHARES - 2*TRADE_COST;
this.sellSize += SHARES;
this.sellTotal += SHARES * tradeSignal.midprice;
// Sell to open
this.own = true;
this.pos = -1;
this.sellPrice = tradeSignal.midprice;
this.tradeCosts += TRADE_COST;
this.sellSize += SHARES;
this.sellTotal += SHARES * tradeSignal.midprice;
} else if(this.own && this.pos == -1 && tradeSignal.trade == 10) {
// Buy to close
this.own = false;
this.pos = 0;
this.buyPrice = tradeSignal.midprice;
this.tradeCosts += TRADE_COST;
this.pnl += (this.sellPrice - this.buyPrice)*SHARES - 2*TRADE_COST;
this.buySize += SHARES;
this.buyTotal += SHARES * tradeSignal.midprice;
// Buy to open
this.own = true;
this.pos = 1;
this.buyPrice = tradeSignal.midprice;
this.tradeCosts += TRADE_COST;
this.buySize += SHARES;
this.buyTotal += SHARES * tradeSignal.midprice;
}
}
this.computeResult = function () {
var result = {
"pnl": this.pnl,
"buySize": this.buySize,
"sellSize": this.sellSize,
"buyTotal": this.buyTotal,
"sellTotal": this.sellTotal,
"tradeCost": this.tradeCost
};
return result;
}
}
Note
Der Power BI-Ausgabekonnektor für Azure Stream Analytics wird eingestellt. Erwägen Sie die Verwendung alternativer Ausgabeziele wie Azure Data Explorer, Azure Synapse Analytics oder eines Datenspeichers, mit dem Power BI über DirectQuery eine Verbindung herstellen oder importieren können. Weitere Informationen finden Sie unter Azure Stream Analytics-Ausgabe an Power BI.
Abschließend geben Sie die Daten zur Visualisierung an das Power BI-Dashboard aus.
SELECT * INTO tradeSignalDashboard FROM tradeSignal /* output tradeSignal to PBI */
SELECT
symbol,
time,
date,
TRY_CAST(s.pnl as float) AS pnl,
TRY_CAST(s.buySize as bigint) AS buySize,
TRY_CAST(s.sellSize as bigint) AS sellSize,
TRY_CAST(s.buyTotal as float) AS buyTotal,
TRY_CAST(s.sellTotal as float) AS sellTotal
INTO pnlDashboard
FROM simulation /* output trade simulation to PBI */
Zusammenfassung
In diesem Artikel wird gezeigt, wie Sie ein realistisches Hochfrequenzhandelsmodell mit einer moderat komplexen Abfrage in Azure Stream Analytics implementieren. Das Modell verwendet zwei Eingabevariablen anstelle von fünf, da Azure Stream Analytics keine integrierte lineare Regressionsfunktion enthält. Sie können jedoch auch komplexere Algorithmen mit höheren Dimensionen als JavaScript UDAs implementieren.
Mit Azure Stream Analytics Tools für Visual Studio Code für die Abfrageentwicklung, Tests und Debugging können Sie die meisten Abfragen testen und debuggen, außer javaScript UDA.