Итак, я видел 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
.