Как установить трейлинг-стоп-лосс для тестирования на истории в Google Bigquery, если это возможно - PullRequest
1 голос
/ 02 июля 2019

, поэтому я проводил тестирование некоторых торговых стратегий на фондовом рынке в Google Bigquery и хотел бы установить трейлинг-стоп на 1% от введенной цены. Если цена акций выросла, скажем, на 5%, трейлинг-стоп также увеличится на 5%. Если цена акций упала, трейлинг-стоп не изменится. (https://www.investopedia.com/terms/t/trailingstop.asp)

У меня есть эта таблица, в которой показан мой сигнал на вход, а в столбце выхода будет показано значение 1, если цена опустится ниже цены трейлинг-стопа, что означает, что сделка закрыта.

Это таблица, которая у меня пока есть:

date           price      entry_signal      
30/06/2018     95              0                
01/07/2018     100             1                
02/07/2018     103             0                
03/07/2018     105             0                
04/07/2018     104.50          0                
05/07/2018     101             0                

Я хотел бы иметь столбец, показывающий, что такое трейлинг-стоп на каждую дату. Сначала трейлинг-стоп устанавливается как 99% от цены на 01/07/2018, когда enter_signal = 1, когда торговля совершается в эту дату.

Когда цена повышается на y%, трейлинг-стоп также будет расти на y%. Однако, если цена падает, трейлинг-стоп не изменится со своего последнего значения.

Когда цена <= трейлинг-стоп, сделка закрывается, и сигнал_входа будет равен 1 ... </p>

В настоящее время я застрял в отсутствии трейлинг-стопа, чтобы двигаться вниз на y%, если цена также снизится на y% ....

Желаемый результат таблицы:

date           price      trailing stop loss      entry_signal      exit_signal
30/06/2018     95              NULL                     0                0
01/07/2018     100             99                       1                0
02/07/2018     103             101.97                   0                0
03/07/2018     105             103.95                   0                0
04/07/2018     104.50          103.95                   0                0
05/07/2018     101             103.95                   0                1

Это был мой оригинальный код:

SELECT 
date, price, entry_signal,
GREATEST(trailing_stop_loss, 0.99 * price) AS trailing_stop_loss
FROM (
SELECT
date, price, entry_signal,
LAST_VALUE(trailing_stop_loss IGNORE NULLS) OVER (ORDER BY DATE) AS trailing_stop_loss
FROM (
SELECT
 date, price, entry_signal,
IF(entry_signal * 0.99 * price > 0, 0.99 * price, NULL) AS trailing_stop_loss
FROM table
)
)

Таблица, которую я получил:

date           price      trailing stop loss      entry_signal      
30/06/2018     95              NULL                     0                
01/07/2018     100             99                       1                
02/07/2018     103             101.97                   0                
03/07/2018     105             103.95                   0                
04/07/2018     104.50          103.455                  0                
05/07/2018     101             99.99                    0                

1 Ответ

2 голосов
/ 04 июля 2019

Ниже для BigQuery Standard SQL

В настоящее время я застрял на , у которого нет трейлинг-стопа, чтобы двигаться вниз на y%, если цена также снизится на y% ....

#standardSQL
WITH temp1 AS (
  SELECT day, price, entry_signal,
    UNIX_DATE(PARSE_DATE('%d/%m/%Y', day)) day_as_days,
    COUNTIF(entry_signal = 1) OVER(ORDER BY UNIX_DATE(PARSE_DATE('%d/%m/%Y', day))) grp
  FROM `project.dataset.table`
), temp2 AS (
  SELECT day, price,
    0.99 * price AS trailing_stop_loss,
    IFNULL(price > LAG(price) OVER(PARTITION BY grp ORDER BY day_as_days), TRUE) AS up,
    entry_signal, grp, day_as_days
  FROM temp1
)
SELECT day, price, trailing_stop_loss, entry_signal, 
  IF(price > trailing_stop_loss, 0, 1) AS exit_signal
FROM (
  SELECT day_as_days, day, price, entry_signal,
    IF(up, trailing_stop_loss, arr[OFFSET(0)]) trailing_stop_loss
  FROM (
    SELECT day_as_days, day, price, up, trailing_stop_loss, entry_signal,
      ARRAY_AGG(trailing_stop_loss) OVER(PARTITION BY grp ORDER BY IF(up, day_as_days, 0) DESC) arr
    FROM temp2
  )
)
-- ORDER BY day_as_days   

с результатом

Row day         price   trailing_stop_loss  entry_signal    exit_signal  
1   30/06/2018  95.0    94.05               0               0    
2   01/07/2018  100.0   99.0                1               0    
3   02/07/2018  103.0   101.97              0               0    
4   03/07/2018  105.0   103.95              0               0    
5   04/07/2018  104.5   103.95              0               0    
6   05/07/2018  101.0   103.95              0               1    

Желаемый результат таблицы: ...

Как вы можете видеть, приведенный выше запрос, по крайней мере, частично обращается к вашей точке stuck at - хотя я не уверен, какова вся картина и что еще необходимо решить - даже если ваша общая проблема все еще не решена полностью - я чувствую, что на ваш конкретный вопрос дан ответ.

Итак, я надеюсь, что вышеизложенное разблокирует вас, и вы сможете выполнить свой вызов самостоятельно: o)

Кстати, я использовал ниже фиктивные данные (из вашего вопроса)

WITH `project.dataset.table` AS (
  SELECT '30/06/2018' day, 95 price, 0 entry_signal UNION ALL
  SELECT '01/07/2018', 100, 1 UNION ALL
  SELECT '02/07/2018', 103, 0 UNION ALL
  SELECT '03/07/2018', 105, 0 UNION ALL
  SELECT '04/07/2018', 104.50, 0 UNION ALL
  SELECT '05/07/2018', 101, 0 
)
...