Учитывая следующую таблицу с ценами закрытия и указанными местами входа.
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
к получению ожидаемого результата?
Обновил свой ответ, чтобы учесть предположение, на которое любезно указал @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 Я обновил свой ответ. Я считаю, что он должен учитывать предположение, на которое вы сейчас указали.
Спасибо @Морис Лим! Я добавил дополнение к вашему ответу для больших сгруппированных данных выше. Взгляни.
@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);
Да, Морис, моя вина, все работает отлично. Проблема заключалась в том, что в исходном примере столбец закрытия имел тип long, но позже был переключен на плавающий. Мне просто нужно было изменить его на long, чтобы он плавал в вашем коде, и это работает. Однако это очень медленно, учитывая, что мой набор данных составляет около 2,3 ГБ. Я задаю еще один вопрос через несколько минут. Пожалуйста, посмотрите.
Вот продолжение: stackoverflow.com/questions/78656361/…
Мое решение не относится к пункту by
. Требуется обновленное решение для решения этой проблемы. Я ответил на ваш вопрос в сообщении выше. Пожалуйста, проверьте, удовлетворяет ли решение вашим условиям.
Это должно быть то, что вы ищете. Для каждой записи функциональный выбор находит первый индекс в таблице, который:
Получив индекс, мы обновляем исходную таблицу. Затем мы повторяем процедуру итеративно для всех точек входа.
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!
Я думаю, нет необходимости итеративно обновлять исходную таблицу. Для больших таблиц вычисления происходят намного медленнее.
Продолжение смотрите на странице stackoverflow.com/questions/78656361/…