Azure Stream Analytics SQL 언어, JavaScript UDF(사용자 정의 함수) 및 UUDA(사용자 정의 집계)의 조합을 통해 고급 분석을 지원합니다. 고급 분석에는 온라인 기계 학습 학습 및 점수 매기기, 상태 저장 프로세스 시뮬레이션이 포함됩니다. 이 문서에서는 고주파 거래 시나리오에서 연속 학습 및 채점을 수행하는 Azure Stream Analytics 작업에서 선형 회귀를 수행하는 방법을 설명합니다.
사전 요구 사항
- Azure 구독입니다. 계정이 없는 경우, 무료 계정을만드세요.
- Azure Stream Analytics 작업.
- Azure Event Hubs 네임스페이스 및 이벤트 허브.
- Stream Analytics 쿼리 언어에 대해 잘 알고 있습니다.
- (선택 사항) 출력을 시각화하려는 경우 Power BI 계정입니다.
고주파 거래 워크플로
고주파 거래의 논리적 흐름은 다음과 같습니다.
- 증권거래소에서 실시간 시세 가져오기
- 가격 변동을 예상하기 위해 견적을 중심으로 예측 모델을 빌드합니다.
- 가격 움직임의 성공적인 예측에서 돈을 벌기 위해 구매 또는 판매 주문을 배치.
이 시나리오에는 다음이 필요합니다.
- 실시간 견적 피드입니다.
- 실시간 시세를 기반으로 작동할 수 있는 예측 모델
- 거래 알고리즘의 손익을 보여 주는 거래 시뮬레이션입니다.
실시간 견적 피드
Important
이 섹션에서 참조하는 IEX 거래 WebSocket API(iextrading.com)가 사용 중지되었습니다. 이제 IEX Cloud는 다양한 인증 및 엔드포인트를 사용하여 IEX Cloud 를 통해 시장 데이터를 제공합니다. 그에 따라 구현에서 URL 및 인증을 업데이트합니다.
Important
SocketIoClientDotNet 이 샘플에서 사용되는 NuGet 패키지와 WindowsAzure.ServiceBus NuGet 패키지는 더 이상 사용되지 않습니다. 새 프로젝트의 경우, 레거시 EventHubClient 대신 EventHubProducerClient와 함께 현재 Socket.IO 클라이언트 라이브러리와 Azure.Messaging.EventHubs 패키지를 사용하세요.
Investors Exchange(IEX)는 이전에 socket.io를 사용해 무료 실시간 매수호가 및 매도호가를 제공했습니다. 간단한 콘솔 프로그램을 작성하여 실시간 시세를 받아 데이터 원본으로 사용하기 위해 Azure Event Hubs로 전송할 수 있습니다. 다음 코드는 프로그램의 기본입니다. 이 코드는 간결하게 오류 처리를 생략합니다. 또한 프로젝트에 SocketIoClientDotNet 및 WindowsAzure.ServiceBus NuGet 패키지도 포함해야 합니다.
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);
});
Caution
이 코드 샘플은 설명 전용입니다. 여기에 사용된 IEX WebSocket API 엔드포인트 및 NuGet 패키지는 더 이상 사용할 수 없습니다. 프로덕션 환경에서는 이 코드를 사용하지 마세요. 현재 대안은 이 섹션의 앞부분에 있는 중요 참고 사항을 참조하세요.
생성된 몇 가지 샘플 이벤트는 다음과 같습니다.
{"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"}
메모
이벤트의 타임스탬프는 에포크 시간의 lastUpdated입니다.
고주파 거래를 위한 예측 모델
이 데모에서는 고빈도 알고리즘 트레이딩의 주문 불균형 기반 전략에서 설명된 선형 모델을 사용합니다.
VOI(거래량 주문 불균형)는 현재 매수/매도 호가와 거래량, 그리고 직전 틱의 매수/매도 호가와 거래량에 의해 결정됩니다. 이 논문은 VOI와 향후 가격 이동 간의 상관 관계를 식별합니다. 지난 5개의 VOI 값과 다음 10틱의 가격 변경 간에 선형 모델을 빌드합니다. 모델은 선형 회귀를 사용하여 전날의 데이터를 학습합니다.
그런 다음 학습된 모델은 현재 거래일의 견적에 대한 가격 변경 예측을 실시간으로 수행합니다. 모델이 충분히 큰 가격 변동을 예측하면 거래를 실행합니다. 임계값 설정에 따라 단일 주식은 거래일 동안 수천 개의 거래를 생성할 수 있습니다.
다음 섹션에서는 Azure Stream Analytics 작업에서 학습 및 예측 작업을 표현하는 방법을 보여 줍니다. 전체 쿼리는 파이프라인을 구성하는 CTE(공통 테이블 식)로 구성된 단일 WITH 문입니다.
| CTE 단계 | Purpose |
|---|---|
typeconvertedquotes |
원시 입력 필드를 적절한 SQL 형식으로 변환 |
timefilteredquotes |
시세를 거래 시간대로 필터링하고 잘못된 데이터를 제거합니다. |
shiftedquotes |
LAG를 사용하여 이전 틱의 매수호가/매도호가 값을 가져옵니다 |
currentPriceAndVOI |
현재 및 이전 틱에서 VOI(볼륨 순서 불균형) 계산 |
shiftedPriceAndShiftedVOI |
연속된 중간 가격 10개와 연속된 VOI 값 2개로 시퀀스를 구성합니다. |
modelInput |
데이터를 기능 벡터로 재구성(VOI를 x로, 가격 델타를 y로) |
modelagg / modelparambs / model |
SUM 및 AVG 집계를 사용하여 2개 변수 선형 회귀 모델 학습 |
shiftedVOI / VOIAndModel / VOIANDModelJoined |
전날 학습된 모델을 사용하여 현재 VOI 값 조인 |
prediction |
모델에서 예상되는 향후 가격 변동(efpc) 계산 |
tradeSignal |
efpc가 ±0.02 임계값을 초과하면 구매/판매 신호 생성 |
메모
이 쿼리에는 필드 이름의 대/소문자를 유지하여 UDA 사용 시 예측 가능한 동작을 보장하는 Azure Stream Analytics 호환성 수준 1.1 이상이 필요합니다.
따옴표 입력 필드 정리 및 변환
Azure Stream Analytics 쿼리의 첫 번째 CTE는 Event Hubs의 원시 견적 데이터를 올바르게 형식화된 SQL 열로 변환합니다. DATEADD 는 Epoch 시간(Unix 밀리초)을 datetime으로 변환합니다. TRY_CAST 쿼리에 실패하지 않고 데이터 형식을 강제 변환합니다. 필드 조작 또는 비교에서 예기치 않은 동작을 방지하기 위해 입력 필드를 예상 데이터 형식으로 캐스팅합니다.
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
),
LAG를 사용하여 이전 틱 값 가져오기
Azure Stream Analytics 쿼리의 다음 CTE는 LAG 함수를 사용하여 각 주식 기호에 대한 이전 틱의 입찰가/요청 가격과 크기를 가져옵니다. LIMIT DURATION 값의 1시간은 임의로 선택됩니다. 견적 빈도를 고려하면 한 시간 전까지 거슬러 올라가 이전 틱 데이터를 찾을 수 있습니다.
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
),
VOI(볼륨 순서 불균형) 계산
다음 CTE는 현재 및 이전 틱의 입찰/요청 데이터에서 VOI 값을 계산합니다. 쿼리는 이전 틱이 없는 경우 null 값을 필터링합니다.
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
),
모델 학습을 위한 기능 시퀀스 빌드
다음 CTE는 LAG 를 다시 사용하여 2개의 연속 VOI 값과 10개의 연속 중간 가격 값이 있는 시퀀스를 만듭니다. 이러한 시퀀스는 선형 회귀 모델에 대한 학습 데이터를 형성합니다.
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
),
기능 벡터로 데이터 재구성
다음 CTE는 가격 및 VOI 시퀀스를 2개 변수 선형 모델의 기능 벡터로 재구성합니다. 여기서 VOI 값은 독립 변수(x1, x2)이고 평균 미래 가격 변경은 종속 변수(y)입니다. 불완전한 데이터가 있는 이벤트는 필터링됩니다.
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
),
SUM 및 AVG를 사용하여 선형 회귀 모델 학습
Azure Stream Analytics 기본 제공 선형 회귀 함수가 없으므로 쿼리는 SUM 및 AVG 집계를 사용하여 2 변수 선형 회귀 모델에 대한 계수(a, b1, b2)를 계산합니다. 모델은 24시간 텀블링 윈도우를 사용하여 매일 재학습합니다.
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
),
전날의 모델을 사용하여 현재 따옴표 채점
쿼리는 전날 학습된 선형 회귀 모델을 사용하여 현재 이벤트의 점수를 매기기 위해 따옴표를 모델 계수와 조인합니다. 쿼리는 JOIN을 사용하는 대신 UNION을 사용하여 모델 이벤트와 견적 이벤트를 단일 스트림으로 결합합니다. 그런 다음 LAG 를 사용하여 이전 날의 모델과 이벤트를 페어링하므로 정확히 하나의 일치 항목을 얻을 수 있습니다. 주말 때문에 쿼리는 3일(72시간)을 되돌아봅니다. 간단한 JOIN 을 사용하는 경우 모든 견적 이벤트에 대해 세 가지 모델을 얻게 됩니다.
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'
),
예측에서 무역 신호 생성
최종 CTE는 선형 회귀 수식()을 적용하여 예상 미래 가격 변동(a + b1 * x1 + b2 * x2efpc)을 계산한 다음 ±0.02 임계값에 따라 구매/판매 신호를 생성합니다. 거래 값이 10이면 매수입니다. 거래 값이 -10이면 매도입니다.
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
),
시뮬레이션을 사용하여 거래 전략 테스트
거래 신호를 생성한 후 실제 거래 없이 거래 전략이 얼마나 효과적인지 테스트합니다.
이 테스트는 1분마다 이동하는 홉핑 윈도우가 있는 UDA를 사용합니다. 날짜 및 HAVING 절의 그룹화는 창이 같은 날에 속한 이벤트만 고려하도록 합니다. 2일에 걸친 홉핑 윈도우의 경우 GROUP BY 날짜에 따라 그룹화가 전날과 당일로 나뉩니다. HAVING 절은 현재 날짜에 종료되지만 이전 날에 그룹화되는 창을 필터링합니다.
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
)
JavaScript UDA는 함수의 모든 누적기를 초기화하고, 창에 init 추가된 모든 이벤트를 사용하여 상태 전환을 계산하고, 창 끝에 시뮬레이션 결과를 반환합니다. 시뮬레이션은 거래당 주식 10주를 보유하거나 단락합니다. 트랜잭션 비용은 평평합니다 $8. 다음 표에서는 UDA가 수행하는 네 가지 거래 작업을 보여 줍니다.
| Condition | 신호 | 조치 | 다음 위치 |
|---|---|---|---|
| 현재 보유 없음 | 구매 (10) | 구매하여 열기 | Long |
| 현재 보유 없음 | 판매(-10) | 매도 개시(숏) | Short |
| 롱 포지션 | 판매(-10) | 매도 청산 후, 매도 개시(숏) | Short |
| 숏 포지션 | 구매 (10) | 매도 청산 후, 매수 개시 | 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;
}
}
메모
Azure Stream Analytics 대한 Power BI 출력 커넥터는 사용 중지 예정입니다. Azure Data Explorer, Azure Synapse Analytics 또는 Power BI DirectQuery를 통해 연결하거나 가져올 수 있는 데이터 저장소와 같은 대체 출력 대상을 사용하는 것이 좋습니다. 자세한 내용은 Power BI에 대한 Azure Stream Analytics 출력을(를) 참조하세요.
마지막으로 시각화를 위해 Power BI 대시보드에 출력합니다.
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 */
요약
이 문서에서는 Azure Stream Analytics 적당히 복잡한 쿼리를 사용하여 현실적인 고주파 거래 모델을 구현하는 방법을 보여 줍니다. Azure Stream Analytics 기본 제공 선형 회귀 함수를 포함하지 않기 때문에 모델은 5개 대신 두 개의 입력 변수를 사용합니다. 그러나 더 높은 차원의 더 정교한 알고리즘을 JavaScript UDA로 구현할 수도 있습니다.
쿼리 개발, 테스트 및 디버깅을 위해 Visual Studio Code