Как создать таблицу реализованных и нереализованных сделок из данных о сделках в R - PullRequest
0 голосов
/ 28 июня 2018

Итак, я видел loop решение этой проблемы из аналогичного вопроса в SQL ( Генерация всех реализованных и нереализованных сделок с использованием sql? )

Я знаю, как решить эту проблему с помощью цикла (вы в значительной степени грубой силой будете логически вычислять FIFO учет реализованных сделок). Я заинтересован в попытке найти векторизованное решение, если это возможно в R.

Допустим, мои данные в такой форме:

structure(list(Symbol = structure(c(1L, 1L, 1L, 1L, 1L), .Label = "AAPL", class = "factor"), 
    TradeDate = structure(c(1L, 1L, 1L, 1L, 1L), .Label = "2018-06-27", class = "factor"), 
    Date.Time = structure(c(2L, 3L, 3L, 4L, 4L), .Label = c("2018-06-27;103743", 
    "2018-06-27;131314", "2018-06-27;132000", "2018-06-27;153317"
    ), class = "factor"), OrderTime = structure(c(2L, 3L, 3L, 
    4L, 4L), .Label = c("2018-06-27;102850", "2018-06-27;130954", 
    "2018-06-27;132000", "2018-06-27;153018"), class = "factor"), 
    Buy.Sell = structure(c(1L, 1L, 1L, 2L, 2L), .Label = c("BUY", 
    "SELL"), class = "factor"), Quantity = c(539L, 8L, 100L, 
    -200L, -447L), Price = c(185, 184.4, 184.3969, 185.3, 185.3
    ), Proceeds = c(-99715, -1475.2, -18439.69, 37060, 82829.1
    ), Commission = c(-2.695, -1, 0, -1.50558, -3.3649713)), .Names = c("Symbol", 
"TradeDate", "Date.Time", "OrderTime", "Buy.Sell", "Quantity", 
"Price", "Proceeds", "Commission"), class = c("data.table", "data.frame"
), row.names = c(NA, -5L), .internal.selfref = <pointer: 0x03f524a0>)

   Symbol  TradeDate         Date.Time         OrderTime Buy.Sell Quantity    Price  Proceeds Commission
1:   AAPL 2018-06-27 2018-06-27;131314 2018-06-27;130954      BUY      539 185.0000 -99715.00  -2.695000
2:   AAPL 2018-06-27 2018-06-27;132000 2018-06-27;132000      BUY        8 184.4000  -1475.20  -1.000000
3:   AAPL 2018-06-27 2018-06-27;132000 2018-06-27;132000      BUY      100 184.3969 -18439.69   0.000000
4:   AAPL 2018-06-27 2018-06-27;153317 2018-06-27;153018     SELL     -200 185.3000  37060.00  -1.505580
5:   AAPL 2018-06-27 2018-06-27;153317 2018-06-27;153018     SELL     -447 185.3000  82829.10  -3.364971

Результат, который я хотел бы получить, будет выглядеть примерно так:

   Symbol Buy.Sell Quantity    Price  Proceeds Commission             BUYTIME SellPrice            SELLTIME PROFIT
1:   AAPL      BUY      539 185.0000 -99715.00     -2.695 2018-06-27 13:20:00     185.3 2018-06-27 15:33:17 161.70
2:   AAPL      BUY        8 184.4000  -1475.20     -1.000 2018-06-27 13:20:00     185.3 2018-06-27 15:33:17   7.20
3:   AAPL      BUY      100 184.3969 -18439.69      0.000 2018-06-27 10:37:43     185.3 2018-06-27 15:33:17  90.31

Где мы сопоставляем первые 539 купленных акций AAPL с первыми 200 проданными. Использование учета «первым вошел - первым вышел». Затем продолжайте продавать оставшиеся 447. На нашем первом уровне теперь осталось 539-200 = 339 акций. поэтому мы также продаем те из второго 447 ПРОДАВАТЬ. Оставив нам с 447-339 = 108. Затем мы продаем следующий заказ на покупку 8. И, наконец, мы продаем последние 100. В этом примере цена продажи была одинаковой для всех из них. Но это может быть по-другому!

Я рассматривал возможность использования cumsum сверх Quantity, чтобы найти точки, в которых кумулятивная сумма Quantity равна 0. Между этими точками происходит закрытие всех предыдущих позиций (потому что данные отфильтрованы в порядке время). Я не уверен, куда идти отсюда.

Как только будет найдено решение для одного тикера, я думаю, что будет легко использовать data.table, чтобы применить решение ко всей таблице с другими тикерами, используя аргумент by.

...