public void AbsReturnsPositiveMoneyFromNegativeMoney() { Money moneyPositive = new Money(1900.5m, CurrencyFixture.NewZealandDollar); Money moneyNegative = new Money(-1900.5m, CurrencyFixture.NewZealandDollar); Money.Abs(moneyNegative).Should().Be(moneyPositive); }
private void CheckNewTransaction(Wallet w, WalletTransaction newTx) { if (this.Txs == null) { return; } this.UpdateWalletData(); Money val = newTx.Balance; if (val < 0) { // SENT BITCOIN string amount = val.Abs().ToUnit(MoneyUnit.BTC).ToString(); } else { // RECEIVED BITCOIN string amount = val.ToUnit(MoneyUnit.BTC).ToString(); TimeSpan timespan = DateTimeOffset.UtcNow - newTx.AddedDate; const int TIMESPAN_TOLERANCE = 5; // in seconds if (timespan.Seconds <= TIMESPAN_TOLERANCE) { App.Current.Dispatcher.Invoke(() => Messenger.Default.Send <string>(amount, "NewReceivedTransactionFound")); } } this.GeneratePubKeys(); }
public void Abs__Produces_Correct_Result(string a, string b) { Money .Abs(Money.Parse(a)) .Should() .Be(b); }
public void Money_ArithmeticOperations() { var three = new Money(3m); var two = new Money(2m); Money five = three.Plus(two); Money oneOwed = two - three; Money one = oneOwed.Abs(); }
public void Test() { var three = new Money(3m); var two = new Money(2m); Money ten = three.Plus(three).Plus(two) + two; Money oneOwed = two - three; Money one = oneOwed.Abs(); // extended operations Money alsoTwo = two.Perform(ten, (amt1, amt2) => amt1 % amt2); three = new Money(3.9m).Perform(System.Math.Floor); }
public static void CheckMaximalRoundOffError(bool isSizeBased, InstrumentSize size, Money amount, Price price, Money accruedInterest, Side side) { if (!isSizeBased) { InstrumentSize calcAmt = size.CalculateAmount(price) * (decimal)side * -1M; //if (accruedInterest != null && accruedInterest.IsNotZero) //{ // accruedInterest = accruedInterest.Abs() * (decimal)side * -1M; // calcAmt += accruedInterest; //} InstrumentSize diff = (calcAmt.Abs() - amount.Abs()); if (diff.IsNotZero && !diff.IsWithinTolerance(0.02m)) { decimal percLeft = diff.Abs().Quantity / amount.Abs().Quantity; if (percLeft >= 0.05m) throw new ApplicationException(string.Format( "Price times Size ({0}) differs by {1}% from the provided Amount ({2}). Order cannot be filled.", calcAmt.DisplayString, Math.Round(percLeft * 100m, 1), amount.DisplayString)); } } }
public static Money TimeClip(Money time) { if (Money.IsInfinity(time) || Money.IsNaN(time)) { return(Money.NaN); } if (Money.Abs(time) > 8640000000000000) { return(Money.NaN); } return(TypeConverter.ToInteger(time)); }
public static Money TimeClip(Money time) { if (!AreFinite(time)) { return(Money.NaN); } if (Money.Abs(time) > 8640000000000000) { return(Money.NaN); } return((long)time + 0); }
private JsValue IndexOf(JsValue thisObj, JsValue[] arguments) { var o = TypeConverter.ToObject(Engine, thisObj); var lenValue = o.Get("length"); var len = TypeConverter.ToUint32(lenValue); if (len == 0) { return(-1); } var n = arguments.Length > 1 ? TypeConverter.ToInteger(arguments[1]) : 0; if (n >= len) { return(-1); } Money k; if (n >= 0) { k = n; } else { k = len - Money.Abs(n); if (k < 0) { k = 0; } } var searchElement = arguments.At(0); for (; k < len; k++) { var kString = TypeConverter.ToString(k); var kPresent = o.HasProperty(kString); if (kPresent) { var elementK = o.Get(kString); var same = ExpressionInterpreter.StrictlyEqual(elementK, searchElement); if (same) { return(k); } } } return(-1); }
public MoneyTransferOrder(IEffectenGiro stichtingDetails, Money amount, ICustomerAccount transfereeAccount, ICounterAccount transfereeCounterAccount, string transferDescription1, string transferDescription2, string transferDescription3, string transferDescription4, DateTime processDate, string narBenef1, string narBenef2, string narBenef3, string narBenef4, IndicationOfCosts costIndication) { this.CreatedBy = B4F.TotalGiro.Security.SecurityManager.CurrentUser; this.TransferorJournal = stichtingDetails.DefaultWithdrawJournal; this.NarDebet1 = stichtingDetails.StichtingName; this.NarDebet2 = stichtingDetails.ResidentialAddress.AddressLine1; this.NarDebet3 = stichtingDetails.ResidentialAddress.AddressLine2; this.NarDebet4 = stichtingDetails.ResidentialAddress.Country.CountryName; this.ProcessDate = processDate; if (amount != null) this.Amount = amount.Abs(); this.TransfereeAccount = transfereeAccount; this.TransfereeCounterAccount = transfereeCounterAccount; this.NarBenef1 = narBenef1; this.NarBenef2 = narBenef2; this.NarBenef3 = narBenef3; this.NarBenef4 = narBenef4; this.TransferDescription1 = transferDescription1; this.TransferDescription2 = transferDescription2; this.TransferDescription3 = transferDescription3; this.TransferDescription4 = transferDescription4; this.CostIndication = costIndication; }
public override PropertyDescriptor GetOwnProperty(string propertyName) { if (propertyName == "Infinity") { return(PropertyDescriptor.Undefined); } var desc = base.GetOwnProperty(propertyName); if (desc != PropertyDescriptor.Undefined) { return(desc); } if (propertyName != Money.Abs(TypeConverter.ToInteger(propertyName)).ToString()) { return(PropertyDescriptor.Undefined); } var str = PrimitiveValue; var dIndex = TypeConverter.ToInteger(propertyName); if (!IsInt(dIndex)) { return(PropertyDescriptor.Undefined); } var index = (int)dIndex; var len = str.AsString().Length; if (len <= index || index < 0) { return(PropertyDescriptor.Undefined); } var resultStr = str.AsString()[index].ToString(); return(new PropertyDescriptor(new JsValue(resultStr), false, true, false)); }
private static bool TryGetNotificationInputs(ProcessedResult result, [NotNullWhen(true)] out string?message) { message = null; try { bool isSpent = result.NewlySpentCoins.Any(); bool isReceived = result.NewlyReceivedCoins.Any(); bool isConfirmedReceive = result.NewlyConfirmedReceivedCoins.Any(); bool isConfirmedSpent = result.NewlyConfirmedReceivedCoins.Any(); Money miningFee = result.Transaction.Transaction.GetFee(result.SpentCoins.Select(x => x.Coin).ToArray()); if (isReceived || isSpent) { Money receivedSum = result.NewlyReceivedCoins.Sum(x => x.Amount); Money spentSum = result.NewlySpentCoins.Sum(x => x.Amount); Money incoming = receivedSum - spentSum; Money receiveSpentDiff = incoming.Abs(); string amountString = receiveSpentDiff.ToFormattedString(); if (result.Transaction.Transaction.IsCoinBase) { message = $"{amountString} BTC received as Coinbase reward"; } else if (isSpent && receiveSpentDiff == miningFee) { message = $"Self transfer. Fee: {amountString} BTC"; } else if (incoming > Money.Zero) { message = $"{amountString} BTC received"; } else if (incoming < Money.Zero) { var sentAmount = receiveSpentDiff - miningFee; message = $"{sentAmount.ToFormattedString()} BTC sent"; } } else if (isConfirmedReceive || isConfirmedSpent) { Money receivedSum = result.ReceivedCoins.Sum(x => x.Amount); Money spentSum = result.SpentCoins.Sum(x => x.Amount); Money incoming = receivedSum - spentSum; Money receiveSpentDiff = incoming.Abs(); string amountString = receiveSpentDiff.ToFormattedString(); if (isConfirmedSpent && receiveSpentDiff == miningFee) { message = $"Self transfer confirmed. Fee: {amountString} BTC"; } else if (incoming > Money.Zero) { message = $"Receiving {amountString} BTC has been confirmed"; } else if (incoming < Money.Zero) { var sentAmount = receiveSpentDiff - miningFee; message = $"{sentAmount.ToFormattedString()} BTC sent got confirmed"; } } } catch (Exception ex) { Logger.LogWarning(ex); } return(message is { });
private static void InsertEndTermValue(IDalSession session, IPortfolioHistorical portfolio, IList<IJournalEntryLine> dividends, IPeriodicReporting reportingPeriod) { IAccountTypeInternal account = portfolio.ParentAccount; IEndTermValue etv = new EndTermValue(account, reportingPeriod); Money InternalDividend = new Money(0m, account.BaseCurrency); Money InternalDividendTax = new Money(0m, account.BaseCurrency); Money ExternalDividend = new Money(0m, account.BaseCurrency); Money ExternalDividendTax = new Money(0m, account.BaseCurrency); if (dividends != null) { List<IJournalEntryLine> divs = dividends.ToList(); if (divs.Exists(d => d.GiroAccount.Key == account.Key)) { if (divs.Exists(d => d.GLAccount.IsGrossDividendInternal)) InternalDividend = divs.Where(d => (d.GLAccount.IsGrossDividendInternal && (d.GiroAccount.Key == account.Key))).Select(m => m.Balance.BaseAmount).Sum(); if (divs.Exists(d => d.GLAccount.IsDividendTaxInternal)) InternalDividendTax = divs.Where(d => (d.GLAccount.IsDividendTaxInternal && (d.GiroAccount.Key == account.Key))).Select(m => m.Balance.BaseAmount).Sum(); if (divs.Exists(d => d.GLAccount.IsGrossDividendExternal)) ExternalDividend = divs.Where(d => (d.GLAccount.IsGrossDividendExternal && (d.GiroAccount.Key == account.Key))).Select(m => m.Balance.BaseAmount).Sum(); if (divs.Exists(d => d.GLAccount.IsDividendTaxExternal)) ExternalDividendTax = divs.Where(d => (d.GLAccount.IsDividendTaxExternal && (d.GiroAccount.Key == account.Key))).Select(m => m.Balance.BaseAmount).Sum(); } } etv.CashValue = portfolio.CashPortfolio.TotalPortfolioValue; etv.FundValue = portfolio.FundPortfolio.TotalPortfolioValue; etv.ClosingValue = etv.FundValue + etv.CashValue; etv.CultureFundValue = portfolio.FundPortfolio.CultureFundValue.Abs(); etv.GreenFundValue = portfolio.FundPortfolio.GreenFundValue.Abs(); etv.InternalDividend = InternalDividend.Abs(); etv.InternalDividendTax = InternalDividendTax.Abs(); etv.ExternalDividend = ExternalDividend.Abs(); etv.ExternalDividendTax = ExternalDividendTax.Abs(); session.InsertOrUpdate(etv); }
private void setSignServiceCharge(ref Money serviceCharge, ref decimal serviceChargePercentage) { // Set the sign of the ServiceCharge if (serviceCharge != null && serviceCharge.IsNotZero) serviceCharge = serviceCharge.Abs() * -1; serviceChargePercentage = Math.Abs(serviceChargePercentage); }
private InstrumentSize getTradeDifferenceOpenValue(InstrumentSize size, Money amount, Money serviceCharge, Money accruedInterest) { InstrumentSize diff; if (IsSizeBased) diff = (this.OpenValue.Abs() - size.Abs()); else diff = (this.OpenValue.Abs() - amount.Abs() + serviceCharge + accruedInterest); return diff; }
public IOrderExecution Fill(InstrumentSize size, Price price, Money amount, decimal exRate, IAccount counterParty, DateTime transactionDate, DateTime transactionDateTime, IExchange exchange, bool isCompleteFill, Money serviceCharge, decimal serviceChargePercentage, Money accruedInterest, ITradingJournalEntry tradingJournalEntry, IGLLookupRecords lookups) { IOrderExecution returnValue = null; if (size == null || price == null || amount == null) throw new Exception("Size, Price and Amount are mandatory when filling the order."); if (IsFillable != OrderFillability.True) throw new ApplicationException("This Order is not fillable."); setSignServiceCharge(ref serviceCharge, ref serviceChargePercentage); if (accruedInterest != null && accruedInterest.IsNotZero) accruedInterest = accruedInterest.Abs() * (decimal)this.Side * -1M; CheckMaximalRoundOffError(IsSizeBased, size, amount, price, accruedInterest, this.Side); if (isCompleteFill) { // Check whether the order has not been filled before if (Transactions.Count > 0) throw new ApplicationException("The order has already been filled and so it can not be a complete fill."); if (this.OpenValue.IsZero) throw new ApplicationException("The open value of this order is zero."); InstrumentSize diff = getTradeDifferenceOpenValue(size, amount, serviceCharge, accruedInterest); if (diff.IsNotZero) { const decimal maxAllowed = 0.05m; // TickSize && NominalValue decimal tickSize = 0M; if (this.OrderType == OrderTypes.SizeBased) { IInstrumentExchange ie = getInstrumentExchange(exchange); if (ie != null) tickSize = ie.TickSize; } if (this.RequestedInstrument.SecCategory.Key == SecCategories.Bond) tickSize = ((IBond)this.RequestedInstrument).NominalValue.Quantity; if (!(tickSize > 0M && Math.Abs(diff.Quantity / tickSize) < 1M)) { decimal fillRatio = diff.Abs().Quantity / this.OpenValue.Abs().Quantity; if (fillRatio > maxAllowed) throw new ApplicationException( string.Format("The size of this transaction is different from the order size by more than {0:0.##}%.", maxAllowed * 100)); } } amount.XRate = exRate; } else { orderInitialCheck(ref amount, size, exRate, serviceCharge, accruedInterest); } this.IsCompleteFilled = isCompleteFill; orderCheckSide(this.Side, ref amount, ref size); checkServiceChargePercentage(serviceCharge, serviceChargePercentage, amount); ListOfTransactionComponents[] components = packageComponents(amount, serviceCharge, accruedInterest); returnValue = new OrderExecution(this, counterParty, size, price, exRate, transactionDate, transactionDateTime, serviceChargePercentage, tradingJournalEntry, lookups, components); fillOrder(returnValue, size, price, amount, serviceCharge, accruedInterest); return returnValue; }
protected bool orderCheckSide(Side side, ref Money amount, ref InstrumentSize size) { if (side == Side.Buy) { size = size.Abs(); amount = amount.Abs() * -1; } else { size = size.Abs() * -1; amount = amount.Abs(); } return true; }
/// <summary> /// Checks the value against the tolerance parameters (but only wheb they are set) /// </summary> /// <param name="orderValue">The value to check</param> /// <param name="totalPortfolioValue">The total portfolio value</param> /// <returns></returns> public bool IsOrderValueWithinTolerance(Money orderValue, Money totalPortfolioValue) { bool retVal = false; Money orderVal; if (IsToleranceParameterSet) { switch (PricingType) { case PricingTypes.Direct: orderVal = orderValue.Abs(); if (!orderVal.Underlying.Equals(MinimumRebalanceAmount.Underlying)) orderVal = orderVal.Convert((ICurrency)MinimumRebalanceAmount.Underlying); if (orderVal >= MinimumRebalanceAmount) retVal = true; break; case PricingTypes.Percentage: orderVal = orderValue.Abs(); if (!orderVal.Underlying.Equals(totalPortfolioValue.Underlying)) orderVal = orderVal.Convert((ICurrency)totalPortfolioValue.Underlying); decimal perc = orderVal.Quantity / totalPortfolioValue.Abs().Quantity; if (perc >= MinimumRebalancePercentage) retVal = true; break; } } else retVal = true; return retVal; }
/// <summary> /// We need to calculate the serviceCharge for Netting. /// On the netted order, take the nett amount (minus service charge) and then add the service charge /// </summary> protected bool calculateServiceChargeForAmountBasedOrder( IExchange exchange, ref Money tradeAmount, out Money serviceCharge, out decimal serviceChargePercentageforOrder) { bool retVal = false; serviceCharge = null; serviceChargePercentageforOrder = 0m; serviceChargePercentageforOrder = getServiceChargePercentageforOrder(exchange); // deduct ServiceCharge if (serviceChargePercentageforOrder > 0) { Money newAmount = tradeAmount * (decimal)(1M / (1M + serviceChargePercentageforOrder)); serviceCharge = (tradeAmount.Abs() - newAmount.Abs()) * -1M; tradeAmount = newAmount; retVal = true; } return retVal; }
protected Money getCommAmount(Money amount) { Money result = new Money(0m, CommCurrency); Money comAmount = amount.Abs(); if (!comAmount.Underlying.Equals(this.CommCurrency)) comAmount = comAmount.Convert(this.CommCurrency); return comAmount; }
private static JsValue Pow(JsValue thisObject, JsValue[] arguments) { var x = TypeConverter.ToNumber(arguments.At(0)); var y = TypeConverter.ToNumber(arguments.At(1)); if (Money.IsNaN(y)) { return(Money.NaN); } if (y.Equals(0)) { return(1); } if (Money.IsNaN(x) && !y.Equals(0)) { return(Money.NaN); } if (Money.Abs(x) > 1) { if (Money.IsPositiveInfinity(y)) { return(Money.PositiveInfinity); } if (Money.IsNegativeInfinity(y)) { return(+0); } } if (Money.Abs(x).Equals(1)) { if (Money.IsInfinity(y)) { return(Money.NaN); } } if (Money.Abs(x) < 1) { if (Money.IsPositiveInfinity(y)) { return(0); } if (Money.IsNegativeInfinity(y)) { return(Money.PositiveInfinity); } } if (Money.IsPositiveInfinity(x)) { if (y > 0) { return(Money.PositiveInfinity); } if (y < 0) { return(+0); } } if (Money.IsNegativeInfinity(x)) { if (y > 0) { if (Money.Abs(y % 2).Equals(1)) { return(Money.NegativeInfinity); } return(Money.PositiveInfinity); } if (y < 0) { if (Money.Abs(y % 2).Equals(1)) { return(-0); } return(+0); } } if (NumberInstance.IsPositiveZero(x)) { // If x is +0 and y>0, the result is +0. if (y > 0) { return(0); } // If x is +0 and y<0, the result is +∞. if (y < 0) { return(Money.PositiveInfinity); } } if (NumberInstance.IsNegativeZero(x)) { if (y > 0) { // If x is −0 and y>0 and y is an odd integer, the result is −0. if (Money.Abs(y % 2).Equals(1)) { return(-0); } // If x is −0 and y>0 and y is not an odd integer, the result is +0. return(+0); } if (y < 0) { // If x is −0 and y<0 and y is an odd integer, the result is −∞. if (Money.Abs(y % 2).Equals(1)) { return(Money.NegativeInfinity); } // If x is −0 and y<0 and y is not an odd integer, the result is +∞. return(Money.PositiveInfinity); } } // If x<0 and x is finite and y is finite and y is not an integer, the result is NaN. if (x < 0 && !Money.IsInfinity(x) && !Money.IsInfinity(y) && !y.Equals((int)y)) { return(Money.NaN); } return((Money)(decimal)System.Math.Pow(x.ToDouble(), y.ToDouble())); }
protected virtual TransactionFillDetails getTransactionFillDetailsAmountBasedOrderByGoalSeek( Money grossAmount, Side side, bool isCommissionRelevant, bool isValueInclComm, DateTime settlementDate, Price price, IExchange exchange, ICommRule rule, ICommClient client, decimal servChargePerc, int precision) { decimal realAmount; decimal guess = grossAmount.Abs().CalculateSize(price).Quantity; FinancialMath.MaxCycles = 200; // Check -> use Commission bool useComm = true; bool useAddComm = false; if (!isCommissionRelevant || rule == null) useComm = false; if (useComm) useAddComm = (rule.AdditionalCalculation != null); realAmount = FinancialMath.GoalSeek(x => new InstrumentSize(x, this).CalculateAmount(price).Quantity + (useComm ? rule.CommCalculation.Calculate(client.GetNewInstance(new InstrumentSize(x, this), price, (useAddComm ? rule.AdditionalCalculation.Calculate(client.GetNewInstance(new InstrumentSize(x, this), price)) : null))).Quantity : 0M) + (useAddComm ? rule.AdditionalCalculation.Calculate(client.GetNewInstance(new InstrumentSize(x, this), price)).Quantity : 0M) + (new InstrumentSize(x, this).CalculateAmount(price).Abs().Quantity * servChargePerc), grossAmount.Abs().Quantity, guess, precision); InstrumentSize size = new InstrumentSize(realAmount, this); Money amount = size.CalculateAmount(price); InstrumentSize cleanSize = amount.CalculateSize(price); Money servCh = (amount.Abs() * servChargePerc); Money comm = amount.ZeroedAmount(); Money addComm = amount.ZeroedAmount(); if (useComm) { if (rule.AdditionalCalculation != null) addComm = rule.AdditionalCalculation.Calculate(client.GetNewInstance(cleanSize, price)); comm = rule.CommCalculation.Calculate(client.GetNewInstance(cleanSize, price, addComm)); // if sell -> comm is already in the amount if (side == Side.Sell && (comm + addComm) != null && (comm + addComm).IsNotZero) { amount += (comm + addComm); cleanSize = amount.CalculateSize(price); if (!isValueInclComm) { if (rule.AdditionalCalculation != null) addComm = rule.AdditionalCalculation.Calculate(client.GetNewInstance(cleanSize, price)); comm = rule.CommCalculation.Calculate(client.GetNewInstance(cleanSize, price, addComm)); } } } return new TransactionFillDetails(cleanSize, amount, null, servCh, servChargePerc, comm + addComm, grossAmount.Abs(), side); }
public bool AddTransferFee(Money transferFee, IGLLookupRecords lookups, string description) { bool success = false; if (transferFee == null || lookups == null) throw new ApplicationException("It is not possible to add transfer fee since not all parameters are valid."); IGeneralOperationsComponent comp = Components.Where(u => u.BookingComponentType == BookingComponentTypes.CashTransfer).FirstOrDefault(); if (!(comp != null && comp.MainLine != null && comp.MainLine.IsAllowedToAddTransferFee)) throw new ApplicationException("It is not possible to add transfer fee to this transfer."); if (TransferFee != null && TransferFee.IsNotZero) throw new ApplicationException("It is not possible to add transfer fee more than once."); if (transferFee.Sign || transferFee.Abs().Quantity > TransferAmount.Abs().Quantity) throw new ApplicationException("The transfer fee can not be higher than the transfer amount."); if (transferFee != null && transferFee.IsNotZero) { ICashTransferComponent newComponent = new CashTransferComponent(this, BookingComponentTypes.CashTransferFee, this.CreationDate); newComponent.AddLinesToComponent(transferFee, BookingComponentTypes.CashTransferFee, true, false, false, lookups, Account); newComponent.Component.SetDescription(description); this.Components.Add(newComponent); success = true; } return success; }
private static JsValue Abs(JsValue thisObject, JsValue[] arguments) { var x = TypeConverter.ToNumber(arguments.At(0)); return(Money.Abs(x)); }
private Money addFixMinMax(Money fee) { // Add Fixed setup if (FixedSetup != null && FixedSetup.IsNotZero) { fee += FixedSetupMonthly; } // Check Minimum Value if (MinValue != null && MinValue.IsNotZero && fee.Abs() < MinValueMonthly.Abs()) fee = MinValueMonthly; // Check Maximum Value if (MaxValue != null && MaxValue.IsNotZero && fee.Abs() > MaxValueMonthly.Abs()) fee = MaxValueMonthly; return fee; }
private void WalletManager_WalletRelevantTransactionProcessed(object sender, ProcessedResult e) { try { // If there are no news, then don't bother. if (!e.IsNews || (sender as Wallet).State != WalletState.Started) { return; } // ToDo // Double spent. // Anonymity set gained? // Received dust bool isSpent = e.NewlySpentCoins.Any(); bool isReceived = e.NewlyReceivedCoins.Any(); bool isConfirmedReceive = e.NewlyConfirmedReceivedCoins.Any(); bool isConfirmedSpent = e.NewlyConfirmedReceivedCoins.Any(); Money miningFee = e.Transaction.Transaction.GetFee(e.SpentCoins.Select(x => x.GetCoin()).ToArray()); if (isReceived || isSpent) { Money receivedSum = e.NewlyReceivedCoins.Sum(x => x.Amount); Money spentSum = e.NewlySpentCoins.Sum(x => x.Amount); Money incoming = receivedSum - spentSum; Money receiveSpentDiff = incoming.Abs(); string amountString = receiveSpentDiff.ToString(false, true); if (e.Transaction.Transaction.IsCoinBase) { _notificationManager.NotifyAndLog($"{amountString} BTC", "Mined", NotificationType.Success, e); } else if (isSpent && receiveSpentDiff == miningFee) { _notificationManager.NotifyAndLog($"Mining Fee: {amountString} BTC", "Self Spend", NotificationType.Information, e); } else if (isSpent && receiveSpentDiff.Almost(Money.Zero, Money.Coins(0.01m)) && e.IsLikelyOwnCoinJoin) { _notificationManager.NotifyAndLog($"CoinJoin Completed!", "", NotificationType.Success, e); } else if (incoming > Money.Zero) { if (e.Transaction.IsRBF && e.Transaction.IsReplacement) { _notificationManager.NotifyAndLog($"{amountString} BTC", "Received Replaceable Replacement Transaction", NotificationType.Information, e); } else if (e.Transaction.IsRBF) { _notificationManager.NotifyAndLog($"{amountString} BTC", "Received Replaceable Transaction", NotificationType.Success, e); } else if (e.Transaction.IsReplacement) { _notificationManager.NotifyAndLog($"{amountString} BTC", "Received Replacement Transaction", NotificationType.Information, e); } else { _notificationManager.NotifyAndLog($"{amountString} BTC", "Received", NotificationType.Success, e); } } else if (incoming < Money.Zero) { _notificationManager.NotifyAndLog($"{amountString} BTC", "Sent", NotificationType.Information, e); } } else if (isConfirmedReceive || isConfirmedSpent) { Money receivedSum = e.ReceivedCoins.Sum(x => x.Amount); Money spentSum = e.SpentCoins.Sum(x => x.Amount); Money incoming = receivedSum - spentSum; Money receiveSpentDiff = incoming.Abs(); string amountString = receiveSpentDiff.ToString(false, true); if (isConfirmedSpent && receiveSpentDiff == miningFee) { _notificationManager.NotifyAndLog($"Mining Fee: {amountString} BTC", "Self Spend Confirmed", NotificationType.Information, e); } else if (isConfirmedSpent && e.IsLikelyOwnCoinJoin) { _notificationManager.NotifyAndLog($"CoinJoin Confirmed!", "", NotificationType.Information, e); } else if (incoming > Money.Zero) { _notificationManager.NotifyAndLog($"{amountString} BTC", "Receive Confirmed", NotificationType.Information, e); } else if (incoming < Money.Zero) { _notificationManager.NotifyAndLog($"{amountString} BTC", "Send Confirmed", NotificationType.Information, e); } } } catch (Exception ex) { Logger.LogWarning(ex); } }
/// <summary> /// Calculates a fee so that the fee plus the net amount (of the order) equals the gross amount. /// </summary> /// <param name="grossAmount">The gross amount.</param> /// <param name="side">The side of the order/transaction.</param> /// <param name="price">The price of the order/transaction.</param> /// <param name="fee">The calculated fee (<b>out</b> parameter).</param> /// <returns><b>true</b> if fee could be calculated (net amount fell on this line), <b>false</b> if not.</returns> public virtual bool CalculateBackwards(Money grossAmount, Price price, Side side, out Tuple<InstrumentSize, Money> result) { bool success = false; if (price == null) throw new ApplicationException("It is not possible to calculate the commission when there is no current price."); decimal sideFactor = (side == Side.Buy ? 1M : -1M); Money fixedSetup = Parent.FixedSetup + StaticChargeAmount; Money nettAmount = (grossAmount.Abs() - (fixedSetup * sideFactor)) / ((Tariff.CalculateSize(price).Quantity + sideFactor)); Money fee = grossAmount.Abs() - (nettAmount * sideFactor); InstrumentSize size = nettAmount.CalculateSize(price); result = new Tuple<InstrumentSize, Money>(size, fee); // Check if within range if (Envelops(size.Abs())) success = true; return success; }