#region License Information /* HeuristicLab * Copyright (C) 2002-2019 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections; using System.Collections.Generic; using System.Net; using System.Xml; using HeuristicLab.Problems.Instances; using System.Linq; namespace HeuristicLab.Problems.DataAnalysis.Trading { public class EcbProblemInstanceProvider : ProblemInstanceProvider { private class EcbDataDescriptor : IDataDescriptor { public string Name { get; set; } public string Description { get; set; } } public override string Name { get { return "European Central Bank FX Data Provider"; } } public override string Description { get { return "Downloads exchange rate data from the ECB"; } } public override Uri WebLink { get { return new Uri("http://www.ecb.europa.eu/stats/eurofxref/"); } } public override string ReferencePublication { get { return string.Empty; } } public override IEnumerable GetDataDescriptors() { var l = new List(); try { using (var client = new WebClient()) { var s = client.OpenRead("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml"); if (s == null) return l; using (var reader = new XmlTextReader(s)) { reader.MoveToContent(); reader.ReadToDescendant("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref"); reader.ReadToDescendant("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref"); reader.ReadToDescendant("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref"); do { l.Add(new EcbDataDescriptor() { Name = "EUR / " + reader.GetAttribute("currency"), Description = string.Empty }); } while (reader.ReadToNextSibling("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref")); } } } catch (Exception) { } return l; } public override IProblemData LoadData(IDataDescriptor descriptor) { var values = new List(); var tList = new List(); var dList = new List(); values.Add(tList); values.Add(dList); using (var client = new WebClient()) { var s = client.OpenRead("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.xml"); if (s != null) using (var reader = new XmlTextReader(s)) { reader.MoveToContent(); reader.ReadToDescendant("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref"); reader.ReadToDescendant("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref"); // foreach time do { reader.MoveToAttribute("time"); tList.Add(reader.ReadContentAsDateTime()); reader.MoveToElement(); reader.ReadToDescendant("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref"); // foreach currencys do { // find matching entry if (descriptor.Name.Contains(reader.GetAttribute("currency"))) { reader.MoveToAttribute("rate"); dList.Add(reader.ReadContentAsDouble()); reader.MoveToElement(); // skip remaining siblings while (reader.ReadToNextSibling("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref")) ; break; } } while (reader.ReadToNextSibling("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref")); } while (reader.ReadToNextSibling("Cube", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref")); } } // keep only the rows with data for this exchange rate if (tList.Count > dList.Count) tList.RemoveRange(dList.Count, tList.Count - dList.Count); else if (dList.Count > tList.Count) dList.RemoveRange(tList.Count, dList.Count - tList.Count); // entries in ECB XML are ordered most recent first => reverse lists tList.Reverse(); dList.Reverse(); // calculate exchange rate deltas var changes = new[] { 0.0 } // first element .Concat(dList.Zip(dList.Skip(1), (prev, cur) => cur - prev)).ToList(); values.Add(changes); var targetVariable = "d(" + descriptor.Name + ")"; var allowedInputVariables = new string[] { targetVariable }; var ds = new Dataset(new string[] { "Day", descriptor.Name, targetVariable }, values); return new ProblemData(ds, allowedInputVariables, targetVariable); } } }