Расчет средней цены
Пример метода FIFO/LIFO, который возвращает среднюю цену открытия.
enum CalcMethod
{
FIFO,
LIFO
}
private double GetAvgEntryPrice(CalcMethod method)
{
// calculate total buy and sell volume
double sellVolume = 0;
double buyVolume = 0;
foreach (Transaction transaction in Position.Transactions)
{
if (transaction.Side == TransactionSide.Sell)
sellVolume += transaction.Qty;
else
buyVolume += transaction.Qty;
}
double x = 0;
double cumQty = 0;
double openVolume;
if (Position.Side == PositionSide.Long)
{
openVolume = buyVolume - sellVolume;
if (method == CalcMethod.LIFO)
{
for (int i = 0; i < Position.Transactions.Count; i++)
{
Transaction transaction = Position.Transactions[i];
if (transaction.Side == TransactionSide.Sell)
continue;
double qty = Math.Min(transaction.Qty, openVolume);
cumQty += qty;
x += qty * transaction.Price;
openVolume -= qty;
if (openVolume == 0)
break;
}
}
if (method == CalcMethod.FIFO)
{
for (int i = Position.Transactions.Count - 1; i >= 0 ; i--)
{
Transaction transaction = Position.Transactions[i];
if (transaction.Side == TransactionSide.Sell)
continue;
double qty = Math.Min(transaction.Qty, openVolume);
cumQty += qty;
x += qty * transaction.Price;
openVolume -= qty;
if (openVolume== 0)
break;
}
}
}
else
{
openVolume = sellVolume - buyVolume;
if (method == CalcMethod.LIFO)
{
for (int i = 0; i < Position.Transactions.Count; i++)
{
Transaction transaction = Position.Transactions[i];
if (transaction.Side == TransactionSide.Buy)
continue;
double qty = Math.Min(transaction.Qty, openVolume);
cumQty += qty;
x += qty * transaction.Price;
openVolume -= qty;
if (openVolume == 0)
break;
}
}
if (method == CalcMethod.FIFO)
{
for (int i = Position.Transactions.Count - 1; i >= 0 ; i--)
{
Transaction transaction = Position.Transactions[i];
if (transaction.Side == TransactionSide.Buy)
continue;
double qty = Math.Min(transaction.Qty, openVolume);
cumQty += qty;
x += qty * transaction.Price;
openVolume -= qty;
if (openVolume == 0)
break;
}
}
}
return x / cumQty;
}