2011-07-20 32 views
2

我有訂單的表看起來像這樣:淨頭寸計算

Ticket Open Time    Close Time    Type Size 
253199 2010-09-09 20:40:00  2010-09-09 20:41:00  sell 0.1 
255406 2010-09-13 19:30:00  2010-09-14 04:30:00  buy  0.1 
258089 2010-09-15 07:00:00  2010-09-15 09:15:00  sell 0.1 
258197 2010-09-15 09:15:00  2010-09-15 14:50:00  buy  0.1 
258203 2010-09-15 09:20:00  2010-09-15 14:50:00  buy  0.1 
259659 2010-09-16 04:35:00  2010-09-16 18:35:00  sell 0.1 
261065 2010-09-17 07:05:00  2010-09-20 00:02:00  buy  0.1 

對於每一個我想獲得一個累計被同時打開(同Type的)所有訂單的順序。換句話說,是在給定訂單之前打開並在給定訂單之後關閉的任何訂單的所有Size的總和。

這裏是我的代碼:

DROP TABLE 
IF EXISTS LongOrders; 

CREATE TABLE LongOrders SELECT 
    B.Ticket AS Ticket, 
    SUM(B.`Size`)AS `Cumulative Long` 
FROM 
    `orders`.eurusd_fx AS A 
JOIN `orders`.eurusd_fx AS B ON(
    B.`Close Time` >= A.`Open Time` 
    AND B.`Open Time` <= A.`Open Time` 
    AND A.Type = B.Type 
    AND A.Type = 'buy' 
) 
GROUP BY 
    A.`Open Time` 
ORDER BY 
    A.`Open Time`; 

DROP TABLE 
IF EXISTS ShortOrders; 

CREATE TABLE ShortOrders SELECT 
    B.Ticket AS Ticket, 
    SUM(B.`Size`)AS `Cumulative Short` 
FROM 
    `orders`.eurusd_fx AS A 
JOIN `orders`.eurusd_fx AS B ON(
    B.`Close Time` >= A.`Open Time` 
    AND B.`Open Time` <= A.`Open Time` 
    AND A.Type = B.Type 
    AND A.Type = 'sell' 
) 
GROUP BY 
    A.`Open Time` 
ORDER BY 
    A.`Open Time`; 

DROP TABLE 
IF EXISTS CumLong; 

CREATE TABLE CumLong SELECT 
    A.* 
FROM 
    LongOrders AS A 
JOIN `orders`.eurusd_fx AS B USING(Ticket); 

DROP TABLE 
IF EXISTS CumShort; 

CREATE TABLE CumShort SELECT 
    A.* 
FROM 
    ShortOrders AS A 
JOIN `orders`.eurusd_fx AS B USING(Ticket); 

SELECT DISTINCT 
    A.*, CumLong.`Cumulative Long`, 
    CumShort.`Cumulative Short` 
FROM 
    `orders`.eurusd_fx AS A 
JOIN(CumShort, CumLong)ON(
    A.Ticket = CumLong.Ticket 
    OR A.Ticket = CumShort.Ticket 
) GROUP BY A.`Open Time`; 

和輸出:

+--------+---------------------+------+------+--------+---------------------+------------+-----------------+------------------+ 
| Ticket | Open Time   | Type | Size | Item | Close Time   | Commission | Cumulative Long | Cumulative Short | 
+--------+---------------------+------+------+--------+---------------------+------------+-----------------+------------------+ 
| 253199 | 2010-09-09 20:40:00 | sell | 0.1 | eurusd | 2010-09-09 20:41:00 | -0.89  |   0.10000 |   0.10000 | 
| 255406 | 2010-09-13 19:30:00 | buy | 0.1 | eurusd | 2010-09-14 04:30:00 | -0.9  |   0.10000 |   0.10000 | 
| 258089 | 2010-09-15 07:00:00 | sell | 0.1 | eurusd | 2010-09-15 09:15:00 | -0.91  |   0.10000 |   0.10000 | 
| 258197 | 2010-09-15 09:15:00 | buy | 0.1 | eurusd | 2010-09-15 14:50:00 | -0.91  |   0.10000 |   0.10000 | 
| 259659 | 2010-09-16 04:35:00 | sell | 0.1 | eurusd | 2010-09-16 18:35:00 | -0.91  |   0.10000 |   0.10000 | 
| 261065 | 2010-09-17 07:05:00 | buy | 0.1 | eurusd | 2010-09-20 00:02:00 | -0.92  |   0.10000 |   0.10000 | 
| 262121 | 2010-09-20 03:00:00 | sell | 0.1 | eurusd | 2010-09-20 05:55:00 | -0.91  |   0.10000 |   0.10000 | 
| 262192 | 2010-09-20 05:50:00 | buy | 0.1 | eurusd | 2010-09-20 09:50:00 | -0.92  |   0.10000 |   0.10000 | 
| 262739 | 2010-09-20 16:55:00 | sell | 0.1 | eurusd | 2010-09-20 18:45:00 | -0.91  |   0.10000 |   0.90000 | 
| 262822 | 2010-09-20 18:40:00 | buy | 0.1 | eurusd | 2010-09-21 02:05:00 | -0.92  |   0.10000 |   0.10000 | 
| 263801 | 2010-09-21 13:05:00 | buy | 0.1 | eurusd | 2010-09-21 21:25:00 | -0.92  |   0.40000 |   0.10000 | 

它似乎並沒有正常工作。例如第一個sell的累積長度應爲0.

我真的很感謝一些幫助!謝謝。

編輯:1個更多的問題:我怎麼能得到的價值ABS(累計長-累計短)?我需要NET累積位置大小。

+0

您需要某種解析函數:它們在MySQL中不可用,但可以模擬:請參閱http://onlamp.com/pub/a/mysql/2007/03/29/emulating-analytic-aka-ranking-functions-with-mysql.html或http://explainextended.com/2009/03/12/ analytic-functions-optimizing-lag-lead-first_value-last_value/ – davek

回答

1
SELECT 
    A.* 
    , SUM(CASE WHEN B.Type = 'buy' THEN B.Size ELSE 0 END) 
    AS `Cumulative Long` 
    , SUM(CASE WHEN B.Type = 'sell' THEN B.Size ELSE 0 END) 
    AS `Cumulative Short` 
FROM 
    orders.eurusd_fx AS A 
    JOIN 
    orders.eurusd_fx AS B 
     ON B.`Open Time` <= A.`Open Time` 
     AND A.`Open Time` <= B.`Close Time` 
GROUP BY 
    A.Ticket 
ORDER BY 
    A.`Open Time` 
    , A.Ticket ; 

SELECT 
    A.* 
    , (SELECT COALESCE(SUM(B.Size),0) 
     FROM orders.eurusd_fx AS B 
     WHERE B.`Open Time` <= A.`Open Time` 
     AND A.`Open Time` <= B.`Close Time` 
     AND B.Type = 'buy' 
    ) AS `Cumulative Long` 
    , (SELECT COALESCE(SUM(C.Size),0) 
     FROM orders.eurusd_fx AS C 
     WHERE C.`Open Time` <= A.`Open Time` 
     AND A.`Open Time` <= C.`Close Time` 
     AND C.Type = 'sell' 
    ) AS `Cumulative Short` 
FROM 
    orders.eurusd_fx AS A 
ORDER BY 
    A.`Open Time` 
    , A.Ticket ; 

爲了獲得額外的計算,你要麼添加其他計算方法爲列或添加一個額外層(推ORDER BY到外層):

SELECT tmp.* 
    , ABS(`Cumulative Long` - `Cumulative Short`) AS NetCumulativeSize 
FROM 
    (SELECT 
     A.* 
     , SUM(CASE WHEN B.Type = 'buy' THEN B.Size ELSE 0 END) 
     AS `Cumulative Long` 
     , SUM(CASE WHEN B.Type = 'sell' THEN B.Size ELSE 0 END) 
     AS `Cumulative Short` 
    FROM 
     orders.eurusd_fx AS A 
     JOIN 
     orders.eurusd_fx AS B 
      ON B.`Open Time` <= A.`Open Time` 
      AND A.`Open Time` <= B.`Close Time` 
    GROUP BY 
     A.Ticket 
) AS tmp 
ORDER BY 
    tmp.`Open Time` 
    , tmp.Ticket ; 
+0

非常好,謝謝!還有1個問題:我怎樣才能得到'ABS('累積長' - '累積短')的值?我需要NET累積位置大小。 –

+0

我的直覺告訴我ON子句應該是:b.opentime <= a。結束時間,以重疊時間。假設A從2運行到7. B順序有4種不同的重疊可能性:1到8,1到3,4,5到6到8.在ON中3打開和1關閉時,選擇2(1到8和1至3),其中2打開,2關閉你選擇所有4.從要求,我不清楚哪個是正確的。 – Martin

+0

@Martin:我認爲他不希望覆蓋所有'(A.OpenTime,A.CloseTime)'期間,而是查找在訂單(A)打開時打開的其他訂單(B)。 –

1

這就是我理解你的要求的方式。如果錯了,請澄清。

SELECT 
    A.Ticket AS Ticket, 
    SUM(B.`Size`) AS `Cumulative Long` 
FROM 
    `orders`.eurusd_fx AS A 
JOIN `orders`.eurusd_fx AS B ON (
    B.`Close Time` >= A.`Open Time` 
    AND B.`Open Time` <= A.`Open Time` 
    AND A.Type = B.Type 
    AND A.Type = 'buy' 
) 
GROUP BY 
    A.`Ticket` 
ORDER BY 
    A.`Ticket`; 
+0

是的,這是正確的......但是當我使用它時,即使第一個訂單是賣出,我的最終結果對於第一個訂單的累積長期顯示爲0.01。 –

+0

它應該是B.Type而不是A.Type:'AND B.Type ='buy'' –

0

我插入了我的測試不同票號的數據,因此不會改變程序。

SELECT DISTINCT A.*, CumLong.`Cumulative Long`, CumShort.`Cumulative Short` 

FROM `orders`.eurusd_fx AS A 

LEFT JOIN Cumlong ON A.Ticket = CumLong.Ticket 

LEFT JOIN cumshort ON A.Ticket = Cumshort.Ticket 

GROUP BY A.`Open Time` 

結果:

ticket open time close time    type size Cumulative Long Cumulative Short 

1 2010-09-09 20:40:00 2010-09-09 20:41:00 sell 0.1 NULL    0.100000001490116 

2 2010-09-13 19:30:00 2010-09-14 04:30:00 buy 0.1 0.100000001490116 NULL 

3 2010-09-15 07:00:00 2010-09-15 09:15:00 sell 0.1 NULL    0.100000001490116 

4 2010-09-15 09:15:00 2010-09-15 14:50:00 buy 0.1 0.100000001490116 NULL 

5 2010-09-15 09:20:00 2010-09-15 14:50:00 buy 0.1 NULL    NULL 

6 2010-09-16 04:35:00 2010-09-16 18:35:00 sell 0.1 NULL    0.100000001490116 

7 2010-09-17 07:05:00 2010-09-20 00:02:00 buy 0.1 0.100000001490116 NULL 

這就是你想要什麼?我不這麼認爲,因爲只有另一個開放的訂單是258203.NN 258197與258203同時結算,但之前開放(我明白,如果時間有重疊,你希望先前開始的訂單)

所以我想結果應該是一行258203與短缺0,2。