internal static void CalculatePreCheckNecessary(Transaction tran, ref CalculateUnfillMarginParameters unfillParams, decimal?effectiveLot = null) { Price buy = null; Price sell = null; Account account = tran.Owner; Settings.Instrument settingInstrument = tran.SettingInstrument; AccountClass.Instrument accountInstrument = account.GetOrCreateInstrument(settingInstrument.Id); if (tran.OrderType == OrderType.Market || tran.OrderType == OrderType.MarketOnOpen || tran.OrderType == OrderType.MarketOnClose || settingInstrument.MarginFormula == MarginFormula.CSiMarketPrice || settingInstrument.MarginFormula == MarginFormula.CSxMarketPrice) { Quotation quotation = QuotationProvider.GetLatestQuotation(tran.InstrumentId, account); buy = quotation.BuyOnCustomerSide; sell = quotation.SellOnCustomerSide; } foreach (Order order in tran.Orders) { if (order.Phase == OrderPhase.Placed || order.Phase == OrderPhase.Placing) { decimal contractSize = tran.ContractSize == 0 ? accountInstrument.TradePolicyDetail.ContractSize : tran.ContractSize; var price = order.IsBuy ? sell : buy; order.CalculatePreCheckNecessary(settingInstrument.MarginFormula, tran.CurrencyRate, contractSize, price, effectiveLot); } } foreach (Order order in tran.Orders) { if (tran.Type == TransactionType.OneCancelOther && tran.OrderType == OrderType.Limit && order.TradeOption == TradeOption.Better) { continue; } Collect(order, tran.ContractSize, effectiveLot, ref unfillParams); } }
private static decimal CalculateUnfilledAutoCloseLot(AccountClass.Instrument instrument, Transaction tran, bool isBuy, bool isAutoClose, Dictionary <Guid, decimal> remainFilledLotPerOrderDict) { decimal result = 0m; foreach (Transaction eachTran in instrument.GetTransactions()) { if (!eachTran.ShouldSumPlaceMargin()) { continue; } bool isHandledOCOTran = false; foreach (Order eachOrder in eachTran.Orders) { if (isHandledOCOTran) { continue; } isHandledOCOTran = eachTran.Type == TransactionType.OneCancelOther; if (eachOrder.IsBuy != isBuy) { continue; } if (!eachOrder.IsOpen) { CalculateRemainFilledLotPerOpenOrder(eachOrder, remainFilledLotPerOrderDict); } else if (isAutoClose) { result += eachOrder.Lot; } } } return(result); }
internal static decimal CalculateTotalAutoCloseLot(AccountClass.Instrument instrument, bool isBuy, decimal unfilledLot, Dictionary <Guid, decimal> remainLotsDict) { decimal result = 0m; decimal remainUnfilledLot = unfilledLot; foreach (Transaction eachTran in instrument.GetTransactions()) { if (remainUnfilledLot <= 0) { break; } foreach (Order eachOrder in eachTran.Orders) { if (eachOrder.IsBuy != isBuy && eachOrder.IsOpen && eachOrder.Phase == OrderPhase.Executed) { var items = FilledCalculator.CalculateOrderCanCloseLot(eachOrder, unfilledLot, remainLotsDict); decimal canClosedLot = items.Item1; decimal remainLot = items.Item2; remainLotsDict[eachOrder.Id] = remainLot - canClosedLot; remainUnfilledLot -= canClosedLot; result += canClosedLot; if (remainUnfilledLot <= 0) { break; } } } } return(result); }
internal void Add(AccountClass.Instrument instrument) { if (!_instruments.ContainsKey(instrument.Id)) { _instruments.AddItem(instrument, OperationType.AsNewRecord); } }
public bool HasEnoughMoneyToPlace(Transaction tran) { if (tran.IsFreeOfPlaceMarginCheck()) { return(true); } Account account = tran.Owner; AccountClass.Instrument instrument = account.GetOrCreateInstrument(tran.InstrumentId); decimal placeCheckNecessary = account.CalculatePreCheckNecessary(tran); decimal placeCheckBalance = account.CalculatePreCheckBalance(); decimal credit = account.CalculateCredit(instrument); decimal unclearBalance = account.CaculateUnclearBalance(); TradePolicy tradePolicy = account.Setting.TradePolicy; MarginCheckOption marginCheckOption = tradePolicy.OpenNecessaryPolicy.MarginCheckOption; bool isMarginEnough = true; if (marginCheckOption == MarginCheckOption.Balance || marginCheckOption == MarginCheckOption.All) { decimal necessary = account.SumFund.Balance - unclearBalance - placeCheckBalance + account.Setting.ShortMargin + credit + account.SumFund.InterestNotValued + account.SumFund.StorageNotValued + account.SumFund.TradePLNotValued; isMarginEnough &= placeCheckNecessary <= necessary; } if (marginCheckOption == MarginCheckOption.Equity || marginCheckOption == MarginCheckOption.All) { decimal equity = account.SumFund.Equity - unclearBalance - placeCheckBalance + account.Setting.ShortMargin + credit; isMarginEnough &= placeCheckNecessary <= equity; } return(isMarginEnough); }
private void DoResetPerTradeDay(AccountClass.Instrument instrument, TradeDayInfo eachResetHistorySetting, InstrumentCloseQuotation closeQuotation) { var settingInstrument = Settings.Setting.Default.GetInstrument(instrument.Id, eachResetHistorySetting.TradeDay); var calculator = TradeDayCalculatorFactory.CreateForReset(eachResetHistorySetting, closeQuotation, Settings.Setting.Default); calculator.Calculate(); _account.AddBalance(settingInstrument.CurrencyId, calculator.Balance, calculator.ResetTime); OrderDayHistorySaver.Save(_account, instrument, calculator, eachResetHistorySetting, settingInstrument); }
private void DoResetCore(AccountClass.Instrument instrument, Dictionary <DateTime, TradeDayInfo> resetHistorySettingDict) { foreach (var eachResetHistorySetting in resetHistorySettingDict.Values) { var settingInstrument = Settings.Setting.Default.GetInstrument(instrument.Id, eachResetHistorySetting.TradeDay); var closeQuotation = _instrumentDayClosePriceFactory.GetQuotation(settingInstrument, eachResetHistorySetting.TradeDay); this.DoResetPerTradeDay(instrument, eachResetHistorySetting, closeQuotation); } }
internal static void Save(Account account, AccountClass.Instrument instrument, TradeDayCalculator calculator, TradeDayInfo tradeDayInfo, Settings.Instrument settingInstrument) { InstrumentResetItem resetItem = CreateInstrumentResetItem(tradeDayInfo.TradeDay, instrument, calculator.ResetResults, tradeDayInfo.Settings.BuyPrice, tradeDayInfo.Settings.SellPrice); resetItem.ResetBalance = calculator.Balance; instrument.AddResetItem(tradeDayInfo.TradeDay, resetItem); AddOrderResetToAccount(account, calculator.ResetResults); AddResetResultToOrderDayHistory(account, calculator.ResetResults); }
internal static bool ExistsOrdersForCalculateNormal(this AccountClass.Instrument instrument, DateTime tradeDay) { foreach (var eachOrder in instrument.GetOrders(tradeDay)) { if (eachOrder.IsForexOrderOrPayoffShortSellOrder()) { return(true); } } return(false); }
internal static decimal CalculatePreCheckNecessary(this AccountClass.Instrument instrument, Transaction tran) { Account account = tran.Owner; Settings.TradePolicyDetail tradePolicyDetail = instrument.TradePolicyDetail(); if (tran.AccountInstrument == instrument) { return(InnerCalculatePreCheckNecessary(instrument, tran, tran.FirstOrder.IsBuy)); } decimal buyPreCheckNecessary = InnerCalculatePreCheckNecessary(instrument, tran, true); decimal sellPreCheckNecessary = InnerCalculatePreCheckNecessary(instrument, tran, false); return(Math.Max(buyPreCheckNecessary, sellPreCheckNecessary)); }
internal static IEnumerable <ResetOrder> GetOrders(this AccountClass.Instrument instrument, DateTime tradeDay) { foreach (var eachTran in instrument.GetTransactions()) { foreach (var eachOrder in eachTran.Orders) { var orderDayHistory = ResetManager.Default.GetOrderDayHistory(eachOrder.Id, tradeDay); if (eachOrder.IsOpen && eachOrder.LotBalance > 0 && eachOrder.Phase == OrderPhase.Executed && orderDayHistory != null && orderDayHistory.LotBalance > 0) { yield return(new ResetOrder(eachOrder)); } } } }
internal bool HasEnoughMoneyToFill(AccountClass.Instrument instrument, bool existsCloseOrder, decimal fee, bool isNecessaryFreeOrder, decimal lastEquity, bool isForPayoff, out string errorInfo) { decimal riskCredit = this.CalculateCredit(instrument.Id); decimal unclearBalance = _owner.UnclearDepositManager.Sum(); TradePolicy tradePolicy = _owner.Setting().TradePolicy(null); MarginCheckOption marginCheckOption = this.GetMarginCheckOption(existsCloseOrder, tradePolicy); decimal fillCheckNecessary = existsCloseOrder ? _fund.RiskRawData.NecessaryFillingCloseOrder : _fund.RiskRawData.NecessaryFillingOpenOrder; errorInfo = string.Empty; bool isBalanceEnough = this.CheckBalanceIsEnough(instrument.IsPhysical, marginCheckOption, unclearBalance, fillCheckNecessary, out errorInfo); bool isEquityEnough = this.CheckEquityIsEnough(instrument.IsPhysical, marginCheckOption, unclearBalance, fillCheckNecessary, fee, isForPayoff, riskCredit, isNecessaryFreeOrder, lastEquity, out errorInfo); Logger.Warn(this.BuildLoggerInfo(existsCloseOrder, riskCredit, unclearBalance, marginCheckOption, instrument.Id, instrument.Owner, lastEquity)); return(isBalanceEnough && isEquityEnough); }
private void PrintErrorInfo(AccountClass.Instrument instrument, DateTime tradeDay, List <TradingDailyQuotation> closeQuotations) { StringBuilder sb = new StringBuilder(500); sb.AppendLine(string.Format("DoResetByClosePrice instrumentId = {0}, tradeDay = {1}", instrument.Id, tradeDay)); IQuotePolicyProvider provider = this._account; sb.AppendLine(string.Format("account privateQuotePolicyId = {0}, publicQuotePolicyId = {1} ", provider.PrivateQuotePolicyId, provider.PublicQuotePolicyId)); sb.Append("Close quotations:"); foreach (var quotation in closeQuotations) { sb.AppendLine(quotation.ToString()); } Logger.Warn(sb.ToString()); }
internal static MarginAndQuantityResult CalculateFillMarginAndQuantity(AccountClass.Instrument instrument, bool isBuy, Dictionary <Guid, decimal> remainFilledLotPerOrderDict) { var result = new MarginAndQuantityResult(); foreach (Transaction eachTran in instrument.GetTransactions()) { foreach (Order eachOrder in eachTran.Orders) { if (eachOrder.ShouldCalculateFilledMarginAndQuantity(isBuy)) { result += eachOrder.CalculateFilledMarginAndQuantity(isBuy, remainFilledLotPerOrderDict); } } } return(result); }
private static decimal InnerCalculatePreCheckNecessary(AccountClass.Instrument instrument, Transaction tran, bool isBuy) { MarginAndQuantityResult unfilledArgs = new MarginAndQuantityResult(); Dictionary <Guid, decimal> remainFilledLotPerOrderDict = new Dictionary <Guid, decimal>(); if (tran.IsPending) { unfilledArgs = UnfilledCalculator.CalculateUnfilledMarginArgsForPlacePendingOrder(instrument, tran, isBuy, remainFilledLotPerOrderDict); } MarginAndQuantityResult filledArgs = new MarginAndQuantityResult(); MarginAndQuantityResult marginArgs = new MarginAndQuantityResult(); instrument.InitializeFilledAndMarginArgs(isBuy, unfilledArgs, filledArgs, marginArgs); filledArgs += FilledCalculator.CalculateFillMarginAndQuantity(instrument, isBuy, remainFilledLotPerOrderDict); return(CalculateNecessary(instrument, isBuy, marginArgs, filledArgs)); }
private static MarginAndQuantityResult CalculateUnfilledMarginAndQuantity(AccountClass.Instrument instrument, bool isBuy, Dictionary <Guid, decimal> unfilledLotsPerTran) { MarginAndQuantityResult result = new MarginAndQuantityResult(); foreach (Transaction eachTran in instrument.GetTransactions()) { if (eachTran.OrderCount == 0) { continue; } decimal?unfilledLot; if (eachTran.ShouldCalculatePreCheckNecessary(instrument, isBuy, unfilledLotsPerTran, out unfilledLot)) { result += eachTran.CalculateUnfilledMarginAndQuantity(unfilledLot); } } return(result); }
internal bool ShouldCalculatePreCheckNecessary(AccountClass.Instrument instrument, bool isBuy, Dictionary <Guid, decimal> unfilledLotsPerTran, out decimal?unfilledLot) { unfilledLot = null; if (!this.ShouldSumPlaceMargin()) { return(false); } Order order = _tran.FirstOrder; if (unfilledLotsPerTran != null && unfilledLotsPerTran.ContainsKey(_tran.Id)) { unfilledLot = unfilledLotsPerTran[_tran.Id]; } bool hasUnfilledLot = unfilledLot == null || unfilledLot > 0; return(order.IsBuy == isBuy && order.IsOpen && hasUnfilledLot && (!instrument.IsPhysical || (instrument.IsPhysical && (!isBuy || ((PhysicalOrder)order).IsInstalment)))); }
private void DoResetByClosePrice(AccountClass.Instrument instrument, DateTime tradeDay, List <TradingDailyQuotation> closeQuotations, TradeDayInfo tradeDayInfo) { var settingInstrument = Settings.Setting.Default.GetInstrument(instrument.Id, tradeDay); var resetItem = instrument.GetResetItem(tradeDay); if (resetItem != null) { Logger.InfoFormat("DoResetByClosePrice modifyClosePrice lastResetItem instrumentId = {0}, tradeDay = {1}, resetBalance = {2}", instrument.Id, tradeDay, resetItem.ResetBalance); _account.AddBalance(settingInstrument.CurrencyId, -resetItem.ResetBalance, tradeDayInfo.Settings.ResetTime); } var quotation = _instrumentDayClosePriceFactory.GetQuotation(settingInstrument, closeQuotations); if (quotation == null) { this.PrintErrorInfo(instrument, tradeDay, closeQuotations); } this.DoResetPerTradeDay(instrument, tradeDayInfo, quotation); }
internal static TradePolicyDetail Get(AccountClass.Instrument instrument) { var result = instrument.TradePolicyDetail(); if (result != null) { return(result); } var trans = instrument.GetTransactions(); if (trans.Count == 0) { throw new NullReferenceException(string.Format("tradePolicyDetail not found, because instrument's tranCount = 0, instrumentId = {0}, accountId = {1}", instrument.Id, instrument.Owner.Id)); } var order = trans[0].FirstOrder; return(GetCommon(order.Id, instrument.Owner)); }
private decimal GetInstrumentResetBalanceGreateThanTradeDay(AccountClass.Instrument instrument, DateTime tradeDay) { var resetItems = instrument.ResetItems; if (resetItems == null || resetItems.Count() == 0) { return(0m); } decimal result = 0m; foreach (var eachResetItem in resetItems) { if (eachResetItem.TradeDay > tradeDay) { result += eachResetItem.ResetBalance; } } return(result); }
internal static bool HasEnoughMoneyToPlace(this Account account, Transaction tran) { if (tran.IsFreeOfPlaceMarginCheck()) { return(true); } AccountClass.Instrument instrument = account.GetOrCreateInstrument(tran.InstrumentId); decimal preCheckNecessaryForBalanceCheckOption = 0; decimal placeCheckNecessary = account.CalculatePreCheckNecessary(tran, out preCheckNecessaryForBalanceCheckOption); decimal placeCheckBalance = account.CalculatePreCheckBalance(); decimal credit = account.CalculateCredit(instrument); decimal unclearBalance = account.CaculateUnclearBalance(); TradePolicy tradePolicy = account.Setting().TradePolicy(null); MarginCheckOption marginCheckOption = tradePolicy.OpenNecessaryPolicy.MarginCheckOption; bool isMarginEnough = true; decimal balanceRemainAmount = account.Balance - unclearBalance - placeCheckBalance + account.Setting().ShortMargin + credit; Logger.InfoFormat("precheck placeCheckNecessary = {0}, placeCheckBalance = {1}, credit = {2}, unclearBalance = {3}, balanceRemainAmount = {4}, ShortMargin = {5} , accountId = {6}, marginCheckOption = {7}, tranId = {8}, isPhysical = {9}, equity = {10}", placeCheckNecessary, placeCheckBalance, credit, unclearBalance, balanceRemainAmount, account.Setting().ShortMargin, account.Id, marginCheckOption, tran.Id, tran.IsPhysical, account.Equity); if (marginCheckOption == MarginCheckOption.Balance || marginCheckOption == MarginCheckOption.All) { if (tran.IsPhysical) { isMarginEnough &= balanceRemainAmount >= 0; } else { isMarginEnough &= preCheckNecessaryForBalanceCheckOption <= balanceRemainAmount; } } if (marginCheckOption == MarginCheckOption.Equity || marginCheckOption == MarginCheckOption.All) { decimal equity = account.Equity - unclearBalance - placeCheckBalance + account.Setting().ShortMargin + credit; isMarginEnough &= placeCheckNecessary <= equity; } return(isMarginEnough); }
private static void InitializeFilledAndMarginArgs(this AccountClass.Instrument instrument, bool isBuy, MarginAndQuantityResult unfilledArgs, MarginAndQuantityResult filledArgs, MarginAndQuantityResult marginArgs) { var physicalInstrument = instrument as Physical.PhysicalInstrument; BuySellPair margin, quantity, partialMargin, partialQuantity; margin = new BuySellPair(instrument.TotalBuyMargin, instrument.TotalSellMargin); quantity = new BuySellPair(instrument.TotalBuyQuantity, instrument.TotalSellQuantity); if (physicalInstrument != null) { partialMargin = new BuySellPair(physicalInstrument.TotalBuyMarginForPartialPaymentPhysicalOrder, physicalInstrument.TotalSellMarginForPartialPaymentPhysicalOrder); partialQuantity = new BuySellPair(physicalInstrument.TotalBuyLotBalanceForPartialPaymentPhysicalOrder, physicalInstrument.TotalSellLotBalanceForPartialPaymentPhysicalOrder); } else { partialMargin = BuySellPair.Empty; partialQuantity = BuySellPair.Empty; } filledArgs.Add(isBuy, margin, quantity, partialMargin, partialQuantity); marginArgs.Add(isBuy, unfilledArgs); marginArgs.Add(isBuy, margin, quantity, partialMargin, partialQuantity); }
private void DoResetCommon(AccountClass.Instrument instrument, DateTime tradeDay) { try { Logger.InfoFormat("doInstrumentReset accountId = {0}, instrumentId = {1}, tradeDay = {2}, lastResetDay = {3}", _account.Id, instrument.Id, tradeDay, instrument.LastResetDay); var resetHistorySettingDict = _account.LoadHistorySetting(instrument.Id, tradeDay); this.DoResetCore(instrument, resetHistorySettingDict); var settingInstrument = Settings.Setting.Default.GetInstrument(instrument.Id, tradeDay); if (settingInstrument.IsPhysical) { _instalmentResetter.Value.PayoffInstalment(_account, instrument.Id, tradeDay, resetHistorySettingDict); } _instrumentManager.UpdateLastResetDay(instrument.Id, tradeDay); Logger.InfoFormat("doInstrumentReset completed accountId = {0}, instrumentId = {1}, tradeDay = {2}", _account.Id, instrument.Id, tradeDay); } catch (OrderConvertException orderConvertException) { Logger.ErrorFormat("msg = {0}, accountId={1}, instrumentId={2}, orderId={3}", orderConvertException.Message, orderConvertException.AccountId, orderConvertException.InstrumentId, orderConvertException.OrderId); throw; } }
private static decimal CalculateNecessary(AccountClass.Instrument instrument, bool isBuy, MarginAndQuantityResult marginArgs, MarginAndQuantityResult filledArgs) { MarginAndQuantityResult necessaryParams = new MarginAndQuantityResult(); necessaryParams.Add(isBuy, marginArgs, filledArgs); decimal netNecessary = 0m; decimal hedgeNecessary = 0m; decimal partialPaymentPhysicalNecessary = 0m; if (necessaryParams.PartialQuantity.Sell > 0) { partialPaymentPhysicalNecessary = necessaryParams.PartialMargin.Sell; } else if (necessaryParams.PartialQuantity.Buy > 0) { partialPaymentPhysicalNecessary = necessaryParams.PartialMargin.Buy; } instrument.CalculateNetAndHedgeNecessary(necessaryParams.Margin.Buy, necessaryParams.Margin.Sell, necessaryParams.Quantity.Buy, necessaryParams.Quantity.Sell, partialPaymentPhysicalNecessary, out netNecessary, out hedgeNecessary); return(netNecessary + hedgeNecessary); }
internal GeneralLotCalculator(AccountClass.Instrument owner) : base(owner) { }
protected LotCalculator(AccountClass.Instrument owner) { _owner = owner; }
internal Verifier(Transaction tran) { _tran = tran; _instrument = _tran.TradingInstrument; _isBuy = _tran.FirstOrder.IsBuy; }
internal static MarginAndQuantityResult CalculateUnfilledMarginArgsForPlacePendingOrder(AccountClass.Instrument instrument, Transaction tran, bool isBuy, Dictionary <Guid, decimal> remainFilledLotPerOrderDict) { MarginAndQuantityResult result = new MarginAndQuantityResult(); bool isAutoClose = tran.Owner.IsAutoClose || instrument.IsPhysical; decimal canAutoCloseLot = CalculateUnfilledAutoCloseLot(instrument, tran, isBuy, isAutoClose, remainFilledLotPerOrderDict); Dictionary <Guid, decimal> unfilledLotPerTran = null; if (isAutoClose && canAutoCloseLot > 0) { decimal totalAutoCloseLot = FilledCalculator.CalculateTotalAutoCloseLot(instrument, isBuy, canAutoCloseLot, remainFilledLotPerOrderDict); unfilledLotPerTran = CalculateRemainUnfilledLotPerTransactionInSameDirection(instrument, isBuy, totalAutoCloseLot); } result = CalculateUnfilledMarginAndQuantity(instrument, isBuy, unfilledLotPerTran); return(result); }
private static Dictionary <Guid, decimal> CalculateRemainUnfilledLotPerTransactionInSameDirection(AccountClass.Instrument instrument, bool isBuy, decimal totalAutoCloseLot) { Dictionary <Guid, decimal> result = null; foreach (Transaction eachTran in instrument.GetTransactions()) { if (totalAutoCloseLot <= 0) { break; } if (!eachTran.ShouldSumPlaceMargin()) { continue; } bool isHandledOCOTran = false; foreach (Order eachOrder in eachTran.Orders) { if (isHandledOCOTran) { continue; } isHandledOCOTran = eachTran.Type == TransactionType.OneCancelOther; if (eachOrder.IsBuy == isBuy && eachOrder.IsOpen) { decimal canFilledLot = Math.Min(totalAutoCloseLot, eachOrder.Lot); decimal unfilledLot = eachOrder.Lot - canFilledLot; if (result == null) { result = new Dictionary <Guid, decimal>(); } result[eachTran.Id] = unfilledLot; totalAutoCloseLot -= canFilledLot; if (totalAutoCloseLot <= 0) { break; } } } } return(result); }
protected PreCheckVerifierBase(Transaction tran) { _tran = tran; _instrument = _tran.AccountInstrument; _isBuy = _tran.FirstOrder.IsBuy; }