Правильный оператор SQL возвращает правильную строку, которая представляет контракт истечения первого месяца - PullRequest
0 голосов
/ 12 сентября 2011

У меня есть база данных торговых записей SQL Server 2008 R2 для нескольких опционов на акции, каждая с интервалом в одну минуту, и каждая минута содержит записи на несколько истечений.Например,

Symbol, TradeDate, Expiry, Open, High, Low, Close
AMZN, 4/01/2009 9:31:00, 4/17/2009, 8, 10, 9, 8.5
AMZN, 4/01/2009 9:31:00, 5/17/2009, 10, 11, 10, 11
AMZN, 4/01/2009 9:31:00, 6/18/2009, 12,13,12,12
GOOG, 4/01/2009 9:31:00, 4/17/2009, 8, 9, 7, 7.5
AMZN, 4/01/2009 9:32:00, 4/17/2009, 8.2, 8.9, 8.3, 8.5
AMZN, 4/01/2009 9:32:00, 5/16/2009, 3, 4, 4, 4
...
AMZN, 4/20/2009 9:31:00, 5/16/2009, 8.5, 9, 8.75, 8.75
AMZN, 4/20/2009 9:31:00, 6/18/2009, 9, 10, 9, 9.2

В опциях всегда есть понятие контракта на первый месяц.Для этой проблемы определите контракт основного месяца следующим образом: Если есть записи TradeDate, меньшие, чем дата истечения для этого контракта, то есть первый месяц.Иначе, передний месяц - это контракт на следующие месяцы.Так, например, в приведенных выше данных, 4/01/2009, месяцем AMZN является контракт, срок действия которого истекает 17/04/2009.Однако, когда мы переходим к TradeDate от 20.04.2009, основным месяцем является контракт от 16.05.2009, поскольку в выходные дни истек срок действия контракта 17.04.2007.

Что такое оператор SQL, которыйвсегда возвращать все правильные строки, дающие «контракт на первый месяц», основанный на том, что такое TradeDate?

1 Ответ

0 голосов
/ 12 сентября 2011

Из того, что вы описали. Следующий запрос должен сделать это. Самостоятельное присоединение:

SELECT T1.Symbol, T1.TradeDate, T1.Expiry, MIN(T2.expiry) AS FrontMonrhContract, T1.Open, T1.High, T1.Low, T1.Close FROM <TABLE> T1, <TABLE> T2 WHERE T1.TradeDate <= T2.Expiry GROUP BY T1.Symbol , T1.TradeDate, T1.Expiry

Но это не будет работать, если нет записи для сделки по Контракту FrontMonth.
Что бы я чувствовал себя лучше, так это то, что вы либо вручную вводите список Expiries, либо вычисляете их, основываясь на каком-то правиле, например, в прошлую пятницу месяца или что-то в этом роде (если есть правило). Так что вы не рискуете просчитать начальный месяц, если для контракта frontMonth нет сделки.

Лучше все же сделать это в вашем приложении вместо SQL, поскольку SQL не предназначен для такой работы. В вашем приложении это будет простое сравнение со списком сроков.
Я сократил время выполнения функции построения диаграмм, которая работала с данными из базы данных sqlite более чем на 90%, выполнив такие вычисления в самом приложении вместо SQL.

Обновление:
Попробуйте следующий запрос. Предполагается, что имя таблицы будет TRADES.

SELECT 
    T1.Symbol, 
    T1.TradeDate, 
    T1.Expiry, 
    MIN(T2.expiry) AS 'FrontMonrhContract' ,
    MIN(T1.[Open]) AS 'Open',
    MIN(T1.[High]) AS 'High',
    MIN(T1.[Low]) AS 'Low',
    MIN(T1.[Close]) AS 'Close'
FROM 
    TRADES T1, TRADES T2 
WHERE T1.TradeDate <= T2.Expiry AND T1.Symbol = T2.Symbol
GROUP BY T1.Symbol , T1.TradeDate, T1.Expiry

Я только что создал пример таблицы с данными, которые вы указали в вопросе, и этот запрос работает, как и ожидалось, для этого набора данных. Для заметки у меня есть SQL Server 2005

Обновление 2:
Чтобы оптимизировать выполнение запроса, попробуйте добавить индекс с тремя столбцами GROUP BY Symbol, TradeDate, Expiry в указанном порядке.
Я создал план выполнения запроса, и более 60% времени заняло разрешение GROUP BY, и после добавления этого индекса в мой образец базы данных он полностью исчез.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...