public virtual void Build() { _spotDays = Parsers.ParseInteger(_strSpotDays); _sourceCurrency = Parsers.ParseCurrency(_strSourceCurrency); _targetCurrency = Parsers.ParseCurrency(_strTargetCurrency); _pointsFactor = Parsers.ParseDouble(_strPointsFactor); _advanceCalendar = _strAdvanceCalendar == "" ? new NullCalendar() : Parsers.ParseCalendar(_strAdvanceCalendar); _spotRelative = _strSpotRelative == "" ? true : Parsers.ParseBool(_strSpotRelative); }
public virtual double GetChildValueAsDouble(XmlNode node, string name, bool mandatory = false) { string s = GetChildValue(node, name, mandatory); return(s == "" ? 0.0 : Parsers.ParseDouble(s)); }
private void LoadFile(string filename, bool isMarket) { //LOG("CSVLoader loading from " << filename); Date today = Settings.evaluationDate(); using (var reader = new StreamReader(filename)) { while (!reader.EndOfStream) { string line = reader.ReadLine(); if (line.Length > 0 && line[0] != '#') { line = line.Trim(); string[] tokens = line.Split(new[] { " " }, StringSplitOptions.None).ToList().Where(i => i != "").ToArray(); //string[] tokens = Regex.Split(line, ",;\t "); //line.Split(',').ToList(); // TODO: should we try, catch and log any invalid lines? if (tokens.ToList().Count != 3) { var debug = ""; } Utils.QL_REQUIRE(tokens.ToList().Count == 3, () => "Invalid CSVLoader line, 3 tokens expected " + line); Date date = Parsers.ParseDateExact(tokens[0], "yyyyMMdd"); string key = tokens[1]; double value = Parsers.ParseDouble(tokens[2]); if (isMarket) { // process market // build market datum and add to map try { if (!_data.ContainsKey(date)) { List <MarketDatum> datum = new List <MarketDatum>(); datum.Add(MarketDatumParser.ParseMarketDatum(date, key, value)); _data.Add(date, datum); } else { _data[date].Add(MarketDatumParser.ParseMarketDatum(date, key, value)); } //TLOG("Added MarketDatum " << data_[date].back()->name()); } catch (Exception e) { //WLOG("Failed to parse MarketDatum " << key << ": " << e.ToString()); } } else { // process fixings if (date < today || (date == today && !_implyTodaysFixings)) { _fixings.Add(new Fixing(date, key, value)); } } } } // LOG("CSVLoader completed processing " << filename); } }
public static MarketDatum ParseMarketDatum(Date asof, string datumName, double value) { List <string> tokens = datumName.Split('/').ToList(); Utils.QL_REQUIRE(tokens.Count > 2, () => "more than 2 tokens expected in " + datumName); MarketDatum.InstrumentType instrumentType = ParseInstrumentType(tokens[0]); MarketDatum.QuoteType quoteType = ParseQuoteType(tokens[1]); switch (instrumentType) { case MarketDatum.InstrumentType.ZERO: { //ZERO / RATE / EUR / EUR1D / A365 / 1Y Utils.QL_REQUIRE(quoteType == MarketDatum.QuoteType.RATE || quoteType == MarketDatum.QuoteType.YIELD_SPREAD, () => "Invalid quote type for " + datumName); Utils.QL_REQUIRE(tokens.Count == 6, () => "6 tokens expected in " + datumName); string ccy = tokens[2]; DayCounter dc = Parsers.ParseDayCounter(tokens[4]); // token 5 can be a date, or tenor Date date = new Date(); Period tenor = new Period(); bool isDate = false; Parsers.ParseDateOrPeriod(tokens[5], date, tenor, out isDate); return(new ZeroQuote(value, asof, datumName, quoteType, ccy, date, dc, tenor)); } case MarketDatum.InstrumentType.DISCOUNT: { // DISCOUNT/RATE/EUR/EUR1D/1Y // DISCOUNT/RATE/EUR/EUR1D/2016-12-15 Utils.QL_REQUIRE(tokens.Count == 5, () => "5 tokens expected in " + datumName); string ccy = tokens[2]; // token 4 can be a date, or tenor Date date = new Date(); Period tenor = new Period(); bool isDate = false; Parsers.ParseDateOrPeriod(tokens[4], date, tenor, out isDate); if (!isDate) { // we can't assume any calendar here, so we do the minimal adjustment with a weekend only calendar Utils.QL_REQUIRE(tenor != null, () => "neither date nor tenor recognised"); date = new WeekendsOnly().adjust(asof + tenor); } return(new DiscountQuote(value, asof, datumName, quoteType, ccy, date)); } //case MarketDatum.InstrumentType.MM: // { // QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName); // const string&ccy = tokens[2]; // Period fwdStart = parsePeriod(tokens[3]); // Period term = parsePeriod(tokens[4]); // return boost::make_shared<MoneyMarketQuote>(value, asof, datumName, quoteType, ccy, fwdStart, term); // } //case MarketDatum.InstrumentType.MM_FUTURE: // { // QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName); // const string&ccy = tokens[2]; // const string&expiry = tokens[3]; // const string&contract = tokens[4]; // Period term = parsePeriod(tokens[5]); // return boost::make_shared<MMFutureQuote>(value, asof, datumName, quoteType, ccy, expiry, contract, term); // } case MarketDatum.InstrumentType.FRA: { Utils.QL_REQUIRE(tokens.Count == 5, () => "5 tokens expected in " + datumName); string ccy = tokens[2]; Period fwdStart = Parsers.ParsePeriod(tokens[3]); Period term = Parsers.ParsePeriod(tokens[4]); return(new FRAQuote(value, asof, datumName, quoteType, ccy, fwdStart, term)); } //case MarketDatum.InstrumentType.IMM_FRA: // { // QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName); // const string&ccy = tokens[2]; // string imm1 = tokens[3]; // string imm2 = tokens[4]; // unsigned int m1 = parseInteger(imm1); // unsigned int m2 = parseInteger(imm2); // QL_REQUIRE(m2 > m1, "Second IMM date must be after the first in " << datumName); // return boost::make_shared<ImmFraQuote>(value, asof, datumName, quoteType, ccy, m1, m2); // } case MarketDatum.InstrumentType.IR_SWAP: { Utils.QL_REQUIRE(tokens.Count == 6, () => "6 tokens expected in " + datumName); string ccy = tokens[2]; Period fwdStart = Parsers.ParsePeriod(tokens[3]); Period tenor = Parsers.ParsePeriod(tokens[4]); Period term = Parsers.ParsePeriod(tokens[5]); return(new SwapQuote(value, asof, datumName, quoteType, ccy, fwdStart, term, tenor)); } //case MarketDatum.InstrumentType.BASIS_SWAP: // { // QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName); // Period flatTerm = parsePeriod(tokens[2]); // Period term = parsePeriod(tokens[3]); // const string&ccy = tokens[4]; // Period maturity = parsePeriod(tokens[5]); // return boost::make_shared<BasisSwapQuote>(value, asof, datumName, quoteType, flatTerm, term, ccy, maturity); // } case MarketDatum.InstrumentType.CC_BASIS_SWAP: { Utils.QL_REQUIRE(tokens.Count == 7, () => "7 tokens expected in " + datumName); string flatCcy = tokens[2]; Period flatTerm = Parsers.ParsePeriod(tokens[3]); string ccy = tokens[4]; Period term = Parsers.ParsePeriod(tokens[5]); Period maturity = Parsers.ParsePeriod(tokens[6]); return(new CrossCcyBasisSwapQuote(value, asof, datumName, quoteType, flatCcy, flatTerm, ccy, term, maturity)); } //case MarketDatum.InstrumentType.CDS: // { // QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName); // const string&underlyingName = tokens[2]; // const string&seniority = tokens[3]; // const string&ccy = tokens[4]; // Period term = parsePeriod(tokens[5]); // return boost::make_shared<CdsSpreadQuote>(value, asof, datumName, underlyingName, seniority, ccy, term); // } //case MarketDatum.InstrumentType.HAZARD_RATE: // { // QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName); // const string&underlyingName = tokens[2]; // const string&seniority = tokens[3]; // const string&ccy = tokens[4]; // Period term = parsePeriod(tokens[5]); // return boost::make_shared<HazardRateQuote>(value, asof, datumName, underlyingName, seniority, ccy, term); // } //case MarketDatum.InstrumentType.RECOVERY_RATE: // { // QL_REQUIRE(tokens.size() == 3 || tokens.size() == 5, "3 or 5 tokens expected in " << datumName); // const string&underlyingName = tokens[2]; // issuer name for CDS, security ID for bond specific RRs // string seniority = ""; // string ccy = ""; // if (tokens.size() == 5) // { // // CDS // seniority = tokens[3]; // ccy = tokens[4]; // } // return boost::make_shared<RecoveryRateQuote>(value, asof, datumName, underlyingName, seniority, ccy); // } //case MarketDatum.InstrumentType.CAPFLOOR: // { // QL_REQUIRE(tokens.size() == 8 || tokens.size() == 4, "Either 4 or 8 tokens expected in " << datumName); // const string&ccy = tokens[2]; // if (tokens.size() == 8) // { // Period term = parsePeriod(tokens[3]); // Period tenor = parsePeriod(tokens[4]); // bool atm = parseBool(tokens[5].c_str()); // bool relative = parseBool(tokens[6].c_str()); // Real strike = parseReal(tokens[7]); // return boost::make_shared<CapFloorQuote>(value, asof, datumName, quoteType, ccy, term, tenor, atm, relative, // strike); // } // else // { // Period indexTenor = parsePeriod(tokens[3]); // return boost::make_shared<CapFloorShiftQuote>(value, asof, datumName, quoteType, ccy, indexTenor); // } // } case MarketDatum.InstrumentType.SWAPTION: { Utils.QL_REQUIRE(tokens.Count == 4 || tokens.Count == 6 || tokens.Count == 7, () => "4, 6 or 7 tokens expected in " + datumName); string ccy = tokens[2]; Period expiry = tokens.Count >= 6 ? Parsers.ParsePeriod(tokens[3]) : new Period(0, TimeUnit.Days); Period term = tokens.Count >= 6 ? Parsers.ParsePeriod(tokens[4]) : Parsers.ParsePeriod(tokens[3]); if (tokens.Count >= 6) { // volatility string dimension = tokens[5]; double strike = 0.0; if (dimension == "ATM") { Utils.QL_REQUIRE(tokens.Count == 6, () => "6 tokens expected in ATM quote " + datumName); } else if (dimension == "Smile") { Utils.QL_REQUIRE(tokens.Count == 7, () => "7 tokens expected in Smile quote " + datumName); strike = Parsers.ParseDouble(tokens[6]); } else { Utils.QL_FAIL("Swaption vol quote dimension " + dimension + " not recognised"); } return(new SwaptionQuote(value, asof, datumName, quoteType, ccy, expiry, term, dimension, strike)); } else { // SLN volatility shift return(null); //return new SwaptionShiftQuote(value, asof, datumName, quoteType, ccy, term); } } case MarketDatum.InstrumentType.FX_SPOT: { Utils.QL_REQUIRE(tokens.Count == 4, () => "4 tokens expected in " + datumName); string unitCcy = tokens[2]; string ccy = tokens[3]; return(new FXSpotQuote(value, asof, datumName, quoteType, unitCcy, ccy)); } case MarketDatum.InstrumentType.FX_FWD: { Utils.QL_REQUIRE(tokens.Count == 5, () => "5 tokens expected in " + datumName); string unitCcy = tokens[2]; string ccy = tokens[3]; Period term = Parsers.ParsePeriod(tokens[4]); return(new FXForwardQuote(value, asof, datumName, quoteType, unitCcy, ccy, term)); } case MarketDatum.InstrumentType.FX_OPTION: { Utils.QL_REQUIRE(tokens.Count == 6, () => "6 tokens expected in " + datumName); string unitCcy = tokens[2]; string ccy = tokens[3]; Period expiry = Parsers.ParsePeriod(tokens[4]); string strike = tokens[5]; return(new FXOptionQuote(value, asof, datumName, quoteType, unitCcy, ccy, expiry, strike)); } //case MarketDatum.InstrumentType.ZC_INFLATIONSWAP: // { // QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName); // const string&index = tokens[2]; // Period term = parsePeriod(tokens[3]); // return boost::make_shared<ZcInflationSwapQuote>(value, asof, datumName, index, term); // } //case MarketDatum.InstrumentType.YY_INFLATIONSWAP: // { // QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName); // const string&index = tokens[2]; // Period term = parsePeriod(tokens[3]); // return boost::make_shared<YoYInflationSwapQuote>(value, asof, datumName, index, term); // } //case MarketDatum.InstrumentType.ZC_INFLATIONCAPFLOOR: // { // QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName); // const string&index = tokens[2]; // Period term = parsePeriod(tokens[3]); // QL_REQUIRE(tokens[4] == "C" || tokens[4] == "F", // "excepted C or F for Cap or Floor at position 5 in " << datumName); // bool isCap = tokens[4] == "C"; // string strike = tokens[5]; // return boost::make_shared<ZcInflationCapFloorQuote>(value, asof, datumName, quoteType, index, term, isCap, // strike); // } //case MarketDatum.InstrumentType.SEASONALITY: // { // QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName); // const string&index = tokens[3]; // const string&type = tokens[2]; // const string&month = tokens[4]; // return boost::make_shared<SeasonalityQuote>(value, asof, datumName, index, type, month); // } //case MarketDatum.InstrumentType.EQUITY_SPOT: // { // QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName); // QL_REQUIRE(quoteType == MarketDatum.QuoteType.PRICE, "Invalid quote type for " << datumName); // const string&equityName = tokens[2]; // const string&ccy = tokens[3]; // return boost::make_shared<EquitySpotQuote>(value, asof, datumName, quoteType, equityName, ccy); // } //case MarketDatum.InstrumentType.EQUITY_FWD: // { // QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName); // QL_REQUIRE(quoteType == MarketDatum.QuoteType.PRICE, "Invalid quote type for " << datumName); // const string&equityName = tokens[2]; // const string&ccy = tokens[3]; // Date expiryDate = getDateFromDateOrPeriod(tokens[4], asof); // return boost::make_shared<EquityForwardQuote>(value, asof, datumName, quoteType, equityName, ccy, expiryDate); // } //case MarketDatum.InstrumentType.EQUITY_DIVIDEND: // { // QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName); // QL_REQUIRE(quoteType == MarketDatum.QuoteType.RATE, "Invalid quote type for " << datumName); // const string&equityName = tokens[2]; // const string&ccy = tokens[3]; // Date tenorDate = getDateFromDateOrPeriod(tokens[4], asof); // return boost::make_shared<EquityDividendYieldQuote>(value, asof, datumName, quoteType, equityName, ccy, // tenorDate); // } //case MarketDatum.InstrumentType.EQUITY_OPTION: // { // QL_REQUIRE(tokens.size() == 6, "6 tokens expected in " << datumName); // QL_REQUIRE(quoteType == MarketDatum.QuoteType.RATE_LNVOL, "Invalid quote type for " << datumName); // const string&equityName = tokens[2]; // const string&ccy = tokens[3]; // string expiryString = tokens[4]; // const string&strike = tokens[5]; // // note how we only store the expiry string - to ensure we can support both Periods and Dates being specified in // // the vol curve-config. // return boost::make_shared<EquityOptionQuote>(value, asof, datumName, quoteType, equityName, ccy, expiryString, // strike); // } //case MarketDatum.InstrumentType.BOND: // { // QL_REQUIRE(tokens.size() == 3, "3 tokens expected in " << datumName); // const string&securityID = tokens[2]; // return boost::make_shared<SecuritySpreadQuote>(value, asof, datumName, securityID); // } //case MarketDatum.InstrumentType.CDS_INDEX: // { // QL_REQUIRE(tokens.size() == 5, "5 tokens expected in " << datumName); // QL_REQUIRE(quoteType == MarketDatum.QuoteType.BASE_CORRELATION, "Invalid quote type for " << datumName); // const string&cdsIndexName = tokens[2]; // Period term = parsePeriod(tokens[3]); // Real detachmentPoint = parseReal(tokens[4]); // return boost::make_shared<BaseCorrelationQuote>(value, asof, datumName, quoteType, cdsIndexName, term, // detachmentPoint); // } //case MarketDatum.InstrumentType.INDEX_CDS_OPTION: // { // QL_REQUIRE(tokens.size() == 4, "4 tokens expected in " << datumName); // QL_REQUIRE(quoteType == MarketDatum.QuoteType.RATE_LNVOL, "Invalid quote type for " << datumName); // const string&indexName = tokens[2]; // const string&expiry = tokens[3]; // return boost::make_shared<IndexCDSOptionQuote>(value, asof, datumName, indexName, expiry); // } default: //Utils.QL_FAIL("Cannot convert \"" + datumName + "\" to MarketDatum"); return(null); } }