Соответствие входов и выходов в kdb

Учитывая следующую таблицу с ценами закрытия и указанными местами входа.

t: ([] close: 18 2 4 8 5 7 3 10 17; entry: 0 1 0 0 0 1 0 0 0);

Я хотел бы выяснить правильные места выхода. Условием является то, что разница между ценами закрытия >= 3 и, конечно же, сделка может быть закрыта только один раз за вход, причем после входа.

Моя неправильная попытка:

t: update exits: (close - close[first where entry=1])>=3 from t;
show t;

урожайность:

close entry exits
-----------------
18    0     1    
2     1     0    
4     0     0    
8     0     1    
5     0     1    
7     1     1    
3     0     0    
10    0     1    
17    0     1 

Ожидается следующее:

close entry exits
-----------------
18    0     0    
2     1     0    
4     0     0    
8     0     1    / exit
5     0     0    
7     1     0    
3     0     0    
10    0     1    / exit
17    0     0 

Каков правильный векторизованный подход в идиоматическом kdb+/q к получению ожидаемого результата?

Продолжение смотрите на странице stackoverflow.com/questions/78656361/…

marital_weeping 22.06.2024 16:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
92
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Обновил свой ответ, чтобы учесть предположение, на которое любезно указал @cillianreilly. Обновленный ответ отслеживает портфель записей, и любые сделанные выходы будут обновлять список портфеля.

q)t:([] close:18 2 4 8 5 7 3 10 17; entry:0 1 0 0 0 1 0 0 0);
q)/ x[0]:portfolio remaining
q)/ x[1]:exits
q)f2:{{x[0],:$[y`entry;y`close;()];if[x[1]:any exits:2<y[`close]-x 0;x[0] _:first where exits];x}\[(`long$();0b);x][;1]};
q)update exits:f2 t from t
close entry exits
-----------------
18    0     0
2     1     0
4     0     0
8     0     1
5     0     0
7     1     0
3     0     0
10    0     1
17    0     0
q)t:([]close:2 6 10;entry:1 1 0);
q)update exits:f2 t from t
close entry exits
-----------------
2     1     0
6     1     1
10    0     1

Я считаю, что нет необходимости итеративно обновлять исходную таблицу. Для больших таблиц вычисления происходят намного медленнее.

q)data:([] close:10000?100; entry:10000?01b);
q)t:update exits:0b from data;
q)o:select close,index:i from t where entry;
q)f:{index:?[x;((>;`close;2+y`close);(>;`i;y`index);(not;`exits));();(first;`i)];update exits:1b from x where i=index};
q)\t c:f/[t;o]
1233
q)f2:{{x[0],:$[y`entry;y`close;()];if[x[1]:any exits:2<y[`close]-x 0;x[0] _:first where exits];x}\[(`long$();0b);x][;1]};
q)t:data;
q)\t m:update exits:f2 t from t
61
q)all c=m
close| 1
entry| 1
exits| 1

Это решение предполагает, что каждая запись выйдет до следующей точки входа, например. это не сработает для: t:([]close:2 6 10;entry:1 1 0)

cillianreilly 22.06.2024 09:13

Вы абсолютно правы. Я написал решение исходя из предположения вышеизложенного. Мне придется придумать обновленное решение, чтобы справиться с этим🙂

Maurice Lim 22.06.2024 09:22

@cillianreilly Я обновил свой ответ. Я считаю, что он должен учитывать предположение, на которое вы сейчас указали.

Maurice Lim 22.06.2024 10:22

Спасибо @Морис Лим! Я добавил дополнение к вашему ответу для больших сгруппированных данных выше. Взгляни.

marital_weeping 22.06.2024 13:11

@marital_weeping какой у тебя meta ohlcv? Не могли бы вы предоставить образец, так как я не могу воспроизвести ошибку. Я попробовал следующее, и это работает: N:1000; ohlcv:([] ticker:N?`NOK`YHOO`CSCO`ORCL`AAPL`DELL`IBM`MSFT`GOOG; date:asc N?.z.d; close:N?100; entry:N?01b);

Maurice Lim 22.06.2024 16:24

Да, Морис, моя вина, все работает отлично. Проблема заключалась в том, что в исходном примере столбец закрытия имел тип long, но позже был переключен на плавающий. Мне просто нужно было изменить его на long, чтобы он плавал в вашем коде, и это работает. Однако это очень медленно, учитывая, что мой набор данных составляет около 2,3 ГБ. Я задаю еще один вопрос через несколько минут. Пожалуйста, посмотрите.

marital_weeping 22.06.2024 16:32

Вот продолжение: stackoverflow.com/questions/78656361/…

marital_weeping 22.06.2024 16:42

Мое решение не относится к пункту by. Требуется обновленное решение для решения этой проблемы. Я ответил на ваш вопрос в сообщении выше. Пожалуйста, проверьте, удовлетворяет ли решение вашим условиям.

Maurice Lim 22.06.2024 17:37

Это должно быть то, что вы ищете. Для каждой записи функциональный выбор находит первый индекс в таблице, который:

  1. Строго больше цены закрытия плюс 2.
  2. Появляется после этой цены закрытия
  3. Это еще не выход

Получив индекс, мы обновляем исходную таблицу. Затем мы повторяем процедуру итеративно для всех точек входа.

t:update 1h$entry,exits:0b from t
o:select close,index:i from t where entry
f:{
        index:?[x;((>;`close;2+y`close);(>;`i;y`index);(not;`exits));();(first;`i)];
        update exits:1b from x where i=index
        }

q)f/[t;o]
close entry exits
-----------------
18    0     0
2     1     0
4     0     0
8     0     1
5     0     0
7     1     0
3     0     0
10    0     1
17    0     0

Спасибо за отличный ответ @cillianreilly!

marital_weeping 22.06.2024 09:49

Я думаю, нет необходимости итеративно обновлять исходную таблицу. Для больших таблиц вычисления происходят намного медленнее.

Maurice Lim 22.06.2024 10:31

Другие вопросы по теме