Changeset 9744 for branches/HeuristicLab.Problems.DataAnalysis.Trading
- Timestamp:
- 07/24/13 12:51:02 (11 years ago)
- Location:
- branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4
- Files:
-
- 1 added
- 2 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/Calculators/OnlineProfitCalculator.cs
r9743 r9744 22 22 using System; 23 23 using System.Collections.Generic; 24 using System.Linq; 24 25 using HeuristicLab.Common; 25 26 … … 28 29 29 30 private int p; 30 private double transactionCost;31 private readonly double transactionCost; 31 32 private int c; 32 33 private double sum; … … 63 64 } else if (p == 0 && signal.IsAlmost(1)) { 64 65 p = 1; 66 iterationReturn = -transactionCost; 65 67 } else if (p == 0 && signal.IsAlmost(-1)) { 66 68 p = -1; 69 iterationReturn = -transactionCost; 67 70 } else if (p == 1 && signal.IsAlmost(1)) { 68 71 iterationReturn = actualReturn; … … 89 92 90 93 public static double Calculate(IEnumerable<double> returns, IEnumerable<double> signals, double transactionCost, out OnlineCalculatorError errorState) { 94 errorState = OnlineCalculatorError.None; 95 return GetProfits(returns, signals, transactionCost).Sum(); 96 } 97 98 public static IEnumerable<double> GetProfits(IEnumerable<double> returns, IEnumerable<double> signals, double transactionCost) { 99 var calc = new OnlineProfitCalculator(transactionCost); 100 91 101 IEnumerator<double> returnsEnumerator = returns.GetEnumerator(); 92 102 IEnumerator<double> signalsEnumerator = signals.GetEnumerator(); 93 OnlineProfitCalculator calculator = new OnlineProfitCalculator(transactionCost);94 103 95 104 // always move forward both enumerators (do not use short-circuit evaluation!) … … 97 106 double signal = signalsEnumerator.Current; 98 107 double @return = returnsEnumerator.Current; 99 calculator.Add(@return, signal); 108 109 double prevTotalProfit = calc.Profit; 110 calc.Add(@return, signal); 111 double curTotalProfit = calc.Profit; 112 113 yield return curTotalProfit - prevTotalProfit; 100 114 } 101 115 … … 103 117 if (returnsEnumerator.MoveNext() || signalsEnumerator.MoveNext()) { 104 118 throw new ArgumentException("Number of elements in first and second enumeration doesn't match."); 105 } else {106 errorState = calculator.ErrorState;107 return calculator.Profit;108 119 } 109 120 } -
branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/Calculators/OnlineSharpeRatioCalculator.cs
r9743 r9744 22 22 using System; 23 23 using System.Collections.Generic; 24 using HeuristicLab.Common;25 24 26 25 namespace HeuristicLab.Problems.DataAnalysis.Trading { 27 26 public class OnlineSharpeRatioCalculator : IOnlineCalculator { 28 27 29 private int p;30 private double transactionCost;31 private int c;32 28 private OnlineMeanAndVarianceCalculator meanAndVarianceCalculator; 29 private OnlineProfitCalculator profitCalculator; 30 33 31 public double SharpeRatio { 34 32 get { … … 40 38 41 39 public OnlineSharpeRatioCalculator(double transactionCost) { 42 this.transactionCost = transactionCost;43 40 this.meanAndVarianceCalculator = new OnlineMeanAndVarianceCalculator(); 41 this.profitCalculator = new OnlineProfitCalculator(transactionCost); 44 42 Reset(); 45 43 } … … 48 46 public OnlineCalculatorError ErrorState { 49 47 get { 50 return meanAndVarianceCalculator.MeanErrorState | meanAndVarianceCalculator.VarianceErrorState ;48 return meanAndVarianceCalculator.MeanErrorState | meanAndVarianceCalculator.VarianceErrorState | profitCalculator.ErrorState; 51 49 } 52 50 } … … 55 53 } 56 54 public void Reset() { 57 p = 0; 58 c = 0; 55 profitCalculator.Reset(); 59 56 meanAndVarianceCalculator.Reset(); 60 57 } 61 58 62 59 public void Add(double actualReturn, double signal) { 63 double iterationReturn = 0.0; 64 if (c == 0) { 65 p = (int)signal; 66 iterationReturn = 0; 67 c++; 68 } else { 69 if (p == 0 && signal.IsAlmost(0)) { 70 } else if (p == 0 && signal.IsAlmost(1)) { 71 p = 1; 72 } else if (p == 0 && signal.IsAlmost(-1)) { 73 p = -1; 74 } else if (p == 1 && signal.IsAlmost(1)) { 75 iterationReturn = actualReturn; 76 } else if (p == 1 && signal.IsAlmost(0)) { 77 iterationReturn = actualReturn - transactionCost; 78 p = 0; 79 } else if (p == 1 && signal.IsAlmost(-1)) { 80 iterationReturn = actualReturn - transactionCost; 81 p = -1; 82 } else if (p == -1 && signal.IsAlmost(-1)) { 83 iterationReturn = -actualReturn; 84 } else if (p == -1 && signal.IsAlmost(0)) { 85 iterationReturn = -actualReturn - transactionCost; 86 p = 0; 87 } else if (p == -1 && signal.IsAlmost(1)) { 88 iterationReturn = -actualReturn - transactionCost; 89 p = 1; 90 } 91 c++; 92 } 93 meanAndVarianceCalculator.Add(iterationReturn); 60 double prevTotalProfit = profitCalculator.Profit; 61 profitCalculator.Add(actualReturn, signal); 62 double curTotalProfit = profitCalculator.Profit; 63 64 meanAndVarianceCalculator.Add(curTotalProfit - prevTotalProfit); 94 65 } 95 66 #endregion -
branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/HeuristicLab.Problems.DataAnalysis.Trading-3.4.csproj
r9743 r9744 161 161 <Compile Include="Calculators\OnlineProfitCalculator.cs" /> 162 162 <Compile Include="HeuristicLabProblemsDataAnalysisTradingPlugin.cs" /> 163 <Compile Include="Interfaces\ITradingEnsembleModel.cs" />164 163 <Compile Include="Interfaces\ITradingModel.cs" /> 165 164 <Compile Include="Interfaces\ITradingProblem.cs" /> … … 171 170 <Compile Include="Symbolic\Interfaces\ISymbolicTradingSingleObjectiveEvaluator.cs" /> 172 171 <Compile Include="Symbolic\Interfaces\ISymbolicTradingSolution.cs" /> 172 <Compile Include="Symbolic\SingleObjective\ProfitEvaluator.cs" /> 173 173 <Compile Include="Symbolic\SingleObjective\SymbolicTradingSingleObjectiveEvaluator.cs" /> 174 174 <Compile Include="Symbolic\SingleObjective\SymbolicTradingSingleObjectiveProblem.cs" /> … … 184 184 <DependentUpon>SymbolicTradingSolutionView.cs</DependentUpon> 185 185 </Compile> 186 <Compile Include="TradingEnsembleModel.cs" />187 186 <Compile Include="TradingProblem.cs" /> 188 187 <Compile Include="TradingProblemData.cs" /> -
branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/Symbolic/SingleObjective/SymbolicTradingSingleObjectiveSharpeRatioEvaluator.cs
r9743 r9744 68 68 69 69 private static IEnumerable<double> GetSignals(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, Dataset dataset, IEnumerable<int> rows) { 70 return from x in interpreter.GetSymbolicExpressionTreeValues(solution, dataset, rows) 71 select x > 0.5 ? 1.0 : x < 0.5 ? -1.0 : 0.0; 70 return SymbolicTradingModel.GetSignals(interpreter.GetSymbolicExpressionTreeValues(solution, dataset, rows)); 72 71 } 73 72 74 73 public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, ITradingProblemData problemData, IEnumerable<int> rows) { 75 74 SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context; 76 77 75 double sharpRatio = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, problemData, rows); 78 79 76 SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null; 80 81 77 return sharpRatio; 82 78 } -
branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/Symbolic/SymbolicTradingModel.cs
r9743 r9744 49 49 ISymbolicDataAnalysisExpressionTreeInterpreter interpreter = Interpreter; 50 50 ISymbolicExpressionTree tree = SymbolicExpressionTree; 51 return from x in interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows) 52 select x > 0.66 ? 1.0 : x < 0.33 ? -1.0 : 0.0; 51 return GetSignals(interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows)); 52 } 53 54 // Transforms an enumerable of real values to an enumerable of trading signals (buy(1) / hold(0) / sell(-1)) 55 public static IEnumerable<double> GetSignals(IEnumerable<double> xs) { 56 // two iterations over xs 57 // 1) determine min / max to calculate the mid-range value 58 // 2) range is split into three thirds 59 double max = double.NegativeInfinity; 60 double min = double.PositiveInfinity; 61 foreach (var x in xs) { 62 if (x > max) max = x; 63 if (x < min) min = x; 64 } 65 if (double.IsInfinity(max) || double.IsNaN(max) || double.IsInfinity(min) || double.IsNaN(min)) 66 return xs.Select(x => 0.0); 67 68 double range = (max - min); 69 double midRange = range / 2.0 + min; 70 double offset = range / 6.0; 71 return from x in xs 72 select x > midRange + offset ? 1.0 : x < midRange - offset ? -1.0 : 0.0; 53 73 } 54 74 } -
branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/Symbolic/SymbolicTradingSolution.cs
r9743 r9744 32 32 /// </summary> 33 33 [StorableClass] 34 [Item(Name = "SymbolicTradingSolution", Description = "Represents a symbolic trading solution (model + data) and attributes of the solution like accuracy and complexity.")] 34 [Item(Name = "SymbolicTradingSolution", 35 Description = 36 "Represents a symbolic trading solution (model + data) and attributes of the solution like accuracy and complexity." 37 )] 35 38 public sealed class SymbolicTradingSolution : TradingSolution, ISymbolicTradingSolution { 36 39 private const string ModelLengthResultName = "Model Length"; … … 41 44 set { base.Model = value; } 42 45 } 46 43 47 ISymbolicDataAnalysisModel ISymbolicDataAnalysisSolution.Model { 44 48 get { return (ISymbolicDataAnalysisModel)base.Model; } 45 49 } 50 46 51 public int ModelLength { 47 52 get { return ((IntValue)this[ModelLengthResultName].Value).Value; } … … 55 60 56 61 [StorableConstructor] 57 private SymbolicTradingSolution(bool deserializing) : base(deserializing) { } 62 private SymbolicTradingSolution(bool deserializing) 63 : base(deserializing) { 64 } 65 58 66 private SymbolicTradingSolution(SymbolicTradingSolution original, Cloner cloner) 59 67 : base(original, cloner) { 60 68 } 69 61 70 public SymbolicTradingSolution(ISymbolicTradingModel model, ITradingProblemData problemData) 62 71 : base(model, problemData) { … … 75 84 } 76 85 77 private new void RecalculateResults() { 86 protected override void RecalculateResults() { 87 base.RecalculateResults(); 88 CalculateResults(); 89 } 90 91 private void CalculateResults() { 78 92 ModelLength = Model.SymbolicExpressionTree.Length; 79 93 ModelDepth = Model.SymbolicExpressionTree.Depth; -
branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/TradingProblemData.cs
r9743 r9744 37 37 38 38 #region default data 39 private static double[,] audInUsd = new double[,] {39 private static double[,] audInUsdDiff = new double[,] { 40 40 { 0.0000}, 41 41 { 0.0003}, … … 1589 1589 1590 1590 static TradingProblemData() { 1591 defaultDataset = new Dataset(new string[] { "AUD" }, audInUsd );1591 defaultDataset = new Dataset(new string[] { "AUD" }, audInUsdDiff); 1592 1592 defaultDataset.Name = "AUD in USD"; 1593 1593 defaultDataset.Description = "Price of Australian dollar in US dollar."; … … 1630 1630 : base(dataset, allowedInputVariables) { 1631 1631 var variables = InputVariables.Select(x => x.AsReadOnly()).ToList(); 1632 Parameters.Add(new ConstrainedValueParameter<StringValue>(PriceVariableParameterName, new ItemSet<StringValue>(variables), variables. Where(x => x.Value == targetVariable).First()));1632 Parameters.Add(new ConstrainedValueParameter<StringValue>(PriceVariableParameterName, new ItemSet<StringValue>(variables), variables.First(x => x.Value == targetVariable))); 1633 1633 Parameters.Add(new FixedValueParameter<DoubleValue>(TransactionCostsParameterName, "The absolute cost of on buy/sell transaction (assumed to be constant and independent of transaction volume)", new DoubleValue(0.0002))); 1634 1634 RegisterParameterEvents(); … … 1646 1646 OnChanged(); 1647 1647 } 1648 1649 1650 1651 1652 //#region Import from file1653 //public static TradingProblemData ImportFromFile(string fileName) {1654 // TableFileParser csvFileParser = new TableFileParser();1655 // csvFileParser.Parse(fileName);1656 1657 // Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);1658 // dataset.Name = Path.GetFileName(fileName);1659 1660 // TradingProblemData problemData = new TradingProblemData(dataset, dataset.VariableNames.Skip(1), dataset.VariableNames.First());1661 // problemData.Name = "Data imported from " + Path.GetFileName(fileName);1662 // return problemData;1663 //}1664 //#endregion1665 1648 } 1666 1649 } -
branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/TradingSolution.cs
r9743 r9744 78 78 Add(new Result(TrainingProfitResultName, "Profit of the model on the training partition", new DoubleValue())); 79 79 Add(new Result(TestProfitResultName, "Profit of the model on the test partition", new DoubleValue())); 80 81 RecalculateResults();82 80 } 83 81 … … 94 92 95 93 protected override void RecalculateResults() { 94 CalculateTradingResults(); 95 } 96 97 protected void CalculateTradingResults() { 96 98 double[] trainingSignals = TrainingSignals.ToArray(); // cache values 97 99 IEnumerable<double> trainingReturns = ProblemData.Dataset.GetDoubleValues(ProblemData.PriceVariable, ProblemData.TrainingIndices); -
branches/HeuristicLab.Problems.DataAnalysis.Trading/HeuristicLab.Problems.DataAnalysis.Trading/3.4/Views/TradingSolutionLineChartView.cs
r9743 r9744 25 25 using System.Windows.Forms; 26 26 using System.Windows.Forms.DataVisualization.Charting; 27 using HeuristicLab.Common;28 27 using HeuristicLab.MainForm; 29 using HeuristicLab.MainForm.WindowsForms;30 28 using HeuristicLab.Problems.DataAnalysis.Views; 31 29 … … 61 59 this.chart.Series.Clear(); 62 60 if (Content != null) { 63 //this.chart.Series.Add(PRICEVARIABLE_SERIES_NAME);64 //this.chart.Series[PRICEVARIABLE_SERIES_NAME].LegendText = Content.ProblemData.PriceVariable;65 //this.chart.Series[PRICEVARIABLE_SERIES_NAME].ChartType = SeriesChartType.FastLine;66 //this.chart.Series[PRICEVARIABLE_SERIES_NAME].Points.DataBindY(Content.ProblemData.Dataset.GetVariableValues(Content.ProblemData.PriceVariable));67 68 69 61 this.chart.Series.Add(SIGNALS_SERIES_NAME); 70 62 this.chart.Series[SIGNALS_SERIES_NAME].LegendText = SIGNALS_SERIES_NAME; … … 80 72 this.chart.Series[PRICEVARIABLE_SERIES_NAME].Tag = Content; 81 73 82 IEnumerable<double> profit = GetProfits(Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.PriceVariable), Content.Signals, Content.ProblemData.TransactionCosts);74 IEnumerable<double> profit = OnlineProfitCalculator.GetProfits(Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.PriceVariable), Content.Signals, Content.ProblemData.TransactionCosts); 83 75 IEnumerable<double> accumulatedProfits = GetAccumulatedPrices(profit); 84 76 this.chart.Series.Add(ASSET_SERIES_NAME); … … 89 81 90 82 this.UpdateStripLines(); 91 92 // UpdateCursorInterval();93 }94 }95 96 private IEnumerable<double> GetProfits(IEnumerable<double> returns, IEnumerable<double> signals, double transactionCost) {97 int p = (int)signals.First();98 yield return 0.0;99 foreach (var signalReturn in returns.Skip(1).Zip(signals.Skip(1), (r, s) => new { Return = r, Signal = s })) {100 double iterationReturn = 0;101 double signal = signalReturn.Signal;102 double actualReturn = signalReturn.Return;103 if (p == 0 && signal.IsAlmost(0)) {104 } else if (p == 0 && signal.IsAlmost(1)) {105 iterationReturn = 0;106 p = 1;107 } else if (p == 0 && signal.IsAlmost(-1)) {108 iterationReturn = 0;109 p = -1;110 } else if (p == 1 && signal.IsAlmost(1)) {111 iterationReturn = actualReturn;112 } else if (p == 1 && signal.IsAlmost(0)) {113 iterationReturn = actualReturn - transactionCost;114 p = 0;115 } else if (p == 1 && signal.IsAlmost(-1)) {116 iterationReturn = actualReturn - transactionCost;117 p = -1;118 } else if (p == -1 && signal.IsAlmost(-1)) {119 iterationReturn = -actualReturn;120 } else if (p == -1 && signal.IsAlmost(0)) {121 iterationReturn = -actualReturn - transactionCost;122 p = 0;123 } else if (p == -1 && signal.IsAlmost(1)) {124 iterationReturn = -actualReturn - transactionCost;125 p = 1;126 }127 yield return iterationReturn;128 83 } 129 84 } … … 136 91 } 137 92 } 138 139 //private void UpdateCursorInterval() {140 // var estimatedValues = this.chart.Series[SIGNALS_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);141 // var targetValues = this.chart.Series[PRICEVARIABLE_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);142 // double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();143 // double targetValuesRange = targetValues.Max() - targetValues.Min();144 // double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));145 // double digits = (int)Math.Log10(interestingValuesRange) - 3;146 // double yZoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);147 // this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;148 //}149 93 150 94 #region events
Note: See TracChangeset
for help on using the changeset viewer.