17 using System.Collections.Generic;
71 return security.QuoteCurrency.ConversionRate
72 * security.SymbolProperties.ContractMultiplier
85 if (baseCurrency ==
null)
90 decimal totalQuantity;
91 decimal orderQuantity;
101 totalQuantity = baseCurrency.BaseCurrency.Amount;
106 var openOrdersReservedQuantity = GetOpenOrdersReservedQuantity(parameters.
Portfolio, parameters.
Security, parameters.
Order);
111 if (orderQuantity <= totalQuantity - openOrdersReservedQuantity)
117 openOrdersReservedQuantity, orderQuantity, baseCurrency));
120 var maximumQuantity = 0m;
140 if (orderQuantity <= Math.Abs(maximumQuantity))
146 maximumQuantity, openOrdersReservedQuantity, orderQuantity, baseCurrency, parameters.
Security, parameters.
Order));
162 maximumQuantity = totalQuantity - openOrdersReservedQuantity - orderFee;
163 if (orderQuantity <= maximumQuantity)
169 maximumQuantity, openOrdersReservedQuantity, orderQuantity, baseCurrency, parameters.
Security, parameters.
Order));
195 if (targetPortfolioValue < 0)
201 if (baseCurrency ==
null)
207 if (targetPortfolioValue == 0)
214 baseCurrency.BaseCurrency.Amount,
215 baseCurrency.BaseCurrency.Symbol);
218 var targetOrderValue = Math.Abs(targetPortfolioValue - baseCurrencyPosition);
243 decimal orderFees = 0;
244 decimal currentOrderValue = 0;
246 var orderQuantity = targetOrderValue / unitPrice;
250 if (orderQuantity == 0)
252 string reason =
null;
261 var lastOrderQuantity = 0m;
267 if (currentOrderValue > targetOrderValue)
269 var currentOrderValuePerUnit = currentOrderValue / orderQuantity;
270 var amountOfOrdersToRemove = (currentOrderValue - targetOrderValue) / currentOrderValuePerUnit;
276 orderQuantity -= amountOfOrdersToRemove;
281 if (orderQuantity <= 0)
289 if (lastOrderQuantity == orderQuantity)
292 orderQuantity, orderFees, parameters.
Security));
294 lastOrderQuantity = orderQuantity;
298 var orderValue = orderQuantity * unitPrice;
305 currentOrderValue = orderValue + orderFees;
306 }
while (currentOrderValue > targetOrderValue);
335 if (baseCurrency ==
null)
340 var baseCurrencyPosition = baseCurrency.BaseCurrency.Amount;
341 var quoteCurrencyPosition = portfolio.CashBook[security.QuoteCurrency.Symbol].Amount;
345 var unitPrice =
new MarketOrder(security.Symbol, 1, utcTime).
GetValue(security) / security.QuoteCurrency.ConversionRate;
356 return parameters.
Result(quoteCurrencyPosition / unitPrice, baseCurrency.BaseCurrency.Symbol);
361 return parameters.
Result(baseCurrencyPosition, baseCurrency.BaseCurrency.Symbol);
367 private static decimal GetOrderPrice(
Security security,
Order order)
373 orderPrice = security.
Price;
400 private static decimal GetOpenOrdersReservedQuantity(SecurityPortfolioManager portfolio, Security security,
Order order)
402 var baseCurrency = security as IBaseCurrencySymbol;
403 if (baseCurrency ==
null)
return 0;
407 ? security.QuoteCurrency.Symbol
408 : baseCurrency.BaseCurrency.Symbol;
410 var symbolDirectionPairs =
new Dictionary<Symbol, OrderDirection>();
411 foreach (var portfolioSecurity
in portfolio.Securities.Values)
413 var basePortfolioSecurity = portfolioSecurity as IBaseCurrencySymbol;
414 if (basePortfolioSecurity ==
null)
continue;
416 if (basePortfolioSecurity.BaseCurrency.Symbol == targetCurrency)
418 symbolDirectionPairs.Add(portfolioSecurity.Symbol,
OrderDirection.Sell);
420 else if (portfolioSecurity.QuoteCurrency.Symbol == targetCurrency)
422 symbolDirectionPairs.Add(portfolioSecurity.Symbol,
OrderDirection.Buy);
427 var openOrders = portfolio.Transactions.GetOpenOrders(x =>
430 return symbolDirectionPairs.TryGetValue(x.Symbol, out dir) &&
432 dir == x.Direction &&
441 var openOrdersReservedQuantity = 0m;
442 foreach (var openOrder
in openOrders)
444 var orderSecurity = portfolio.Securities[openOrder.Symbol];
445 var orderBaseCurrency = orderSecurity as IBaseCurrencySymbol;
447 if (orderBaseCurrency !=
null)
450 var quantityInTargetCurrency = openOrder.AbsoluteQuantity;
451 if (orderSecurity.QuoteCurrency.Symbol == targetCurrency)
453 quantityInTargetCurrency *= GetOrderPrice(security, openOrder);
456 openOrdersReservedQuantity += quantityInTargetCurrency;
460 return openOrdersReservedQuantity;