/// <summary> /// Parse commodity prices from a textual representation /// </summary> /// <remarks> /// ported from parse_price_directive /// </remarks> public Tuple <Commodity, PricePoint> ParsePriceDirective(string line, bool doNotAddPrice = false, bool noDate = false) { string timeField = StringExtensions.NextElement(ref line); if (String.IsNullOrWhiteSpace(timeField)) { return(default(Tuple <Commodity, PricePoint>)); } string dateField = line; string symbolAndPrice = null; DateTime dateTime = default(DateTime); string symbol = null; if (!noDate && Char.IsDigit(timeField[0])) { symbolAndPrice = StringExtensions.NextElement(ref timeField); if (String.IsNullOrWhiteSpace(symbolAndPrice)) { return(default(Tuple <Commodity, PricePoint>)); } dateTime = TimesCommon.Current.ParseDateTime(dateField + " " + timeField); } else if (!noDate && Char.IsDigit(dateField[0])) { symbolAndPrice = timeField; dateTime = TimesCommon.Current.ParseDate(dateField); } else { symbol = dateField; symbolAndPrice = timeField; dateTime = TimesCommon.Current.CurrentTime; } if (String.IsNullOrEmpty(symbol)) { symbol = Commodity.ParseSymbol(ref symbolAndPrice); } PricePoint point = new PricePoint(dateTime, new Amount()); point.Price.Parse(ref symbolAndPrice, AmountParseFlagsEnum.PARSE_NO_MIGRATE); Validator.Verify(() => point.Price.Valid()); Logger.Current.Debug(DebugCommodityDownload, () => "Looking up symbol: " + symbol); Commodity commodity = FindOrCreate(symbol); if (commodity != null) { Logger.Current.Debug(DebugCommodityDownload, () => String.Format("Adding price for {0}: {1} {2}", symbol, point.When, point.Price)); if (!doNotAddPrice) { commodity.AddPrice(point.When, point.Price, true); } commodity.Flags |= CommodityFlagsEnum.COMMODITY_KNOWN; return(new Tuple <Commodity, PricePoint>(commodity, point)); } return(default(Tuple <Commodity, PricePoint>)); }
public CostBreakdown Exchange(Amount amount, Amount cost, bool isPerUnit = false, bool addPrice = true, DateTime?moment = null, string tag = null) { Logger.Current.Debug("commodity.prices.add", () => String.Format("exchange: {0} for {1}", amount, cost)); Logger.Current.Debug("commodity.prices.add", () => String.Format("exchange: is-per-unit = {0}", isPerUnit)); if (moment.HasValue) { Logger.Current.Debug("commodity.prices.add", () => String.Format("exchange: moment = {0}", moment.Value)); } if (tag != null) { Logger.Current.Debug("commodity.prices.add", () => String.Format("exchange: tag = {0}", tag)); } Commodity commodity = amount.Commodity; Annotation currentAnnotation = null; if (commodity.IsAnnotated) { currentAnnotation = ((AnnotatedCommodity)commodity).Details; } Amount perUnitCost = isPerUnit || amount.IsRealZero ? cost.Abs() : (cost / amount).Abs(); if (!cost.HasCommodity) { perUnitCost.ClearCommodity(); } if (cost.HasAnnotation) { perUnitCost = perUnitCost.StripAnnotations(new AnnotationKeepDetails()); } Logger.Current.Debug("commodity.prices.add", () => String.Format("exchange: per-unit-cost = {0}", perUnitCost)); // Do not record commodity exchanges where amount's commodity has a // fixated price, since this does not establish a market value for the // base commodity. if (addPrice && !perUnitCost.IsRealZero && (currentAnnotation == null || !(currentAnnotation.Price != null && currentAnnotation.IsPriceFixated)) && commodity.Referent != perUnitCost.Commodity.Referent) { Exchange(commodity, perUnitCost, moment ?? TimesCommon.Current.CurrentTime); } CostBreakdown breakdown = new CostBreakdown(); breakdown.FinalCost = !isPerUnit ? cost : cost *amount.Abs(); Logger.Current.Debug("commodity.prices.add", () => String.Format("exchange: final-cost = {0}", breakdown.FinalCost)); if (currentAnnotation != null && currentAnnotation.Price != null) { breakdown.BasisCost = (currentAnnotation.Price * amount).Unrounded(); } else { breakdown.BasisCost = breakdown.FinalCost; } Logger.Current.Debug("commodity.prices.add", () => String.Format("exchange: basis-cost = {0}", breakdown.BasisCost)); Annotation annotation = new Annotation(perUnitCost, moment.HasValue ? (Date)moment.Value.Date : default(Date), tag); annotation.IsPriceCalculated = true; if (currentAnnotation != null && currentAnnotation.IsPriceFixated) { annotation.IsPriceFixated = true; } if (moment.HasValue) { annotation.IsDateCalculated = true; } if (!string.IsNullOrEmpty(tag)) { annotation.IsTagCalculated = true; } breakdown.Amount = new Amount(amount, annotation); Logger.Current.Debug("commodity.prices.add", () => String.Format("exchange: amount = {0}", breakdown.Amount)); return(breakdown); }