//************************************************************************************** public WekaInfo(int?iID, Type iType, int iParametersID, Candlestick.Period iPeriod, int iProfitTime) { ID = iID; Type = iType; ParametersID = iParametersID; Period = iPeriod; ProfitTime = iProfitTime; }
//************************************************************************************** /// <summary> /// Retrieves candlesticks from a server. /// </summary> public static List <Candlestick> RetrieveCandlesticks(Candlestick.Period iCandlestickPeriod) { HttpWebRequest request; switch (iCandlestickPeriod) { case Candlestick.Period.D1: request = (HttpWebRequest)WebRequest.Create("https://www.alphavantage.co/query?function=FX_DAILY&from_symbol=EUR&to_symbol=USD&apikey=" + kAlphaVantageAPIKey + "&datatype=csv&outputsize=full"); break; case Candlestick.Period.m1: request = (HttpWebRequest)WebRequest.Create("https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol=EUR&to_symbol=USD&interval=1min&apikey=" + kAlphaVantageAPIKey + "&datatype=csv&outputsize=full"); break; case Candlestick.Period.m5: request = (HttpWebRequest)WebRequest.Create("https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol=EUR&to_symbol=USD&interval=5min&apikey=" + kAlphaVantageAPIKey + "&datatype=csv&outputsize=full"); break; case Candlestick.Period.m15: request = (HttpWebRequest)WebRequest.Create("https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol=EUR&to_symbol=USD&interval=15min&apikey=" + kAlphaVantageAPIKey + "&datatype=csv&outputsize=full"); break; case Candlestick.Period.m30: request = (HttpWebRequest)WebRequest.Create("https://www.alphavantage.co/query?function=FX_INTRADAY&from_symbol=EUR&to_symbol=USD&interval=30min&apikey=" + kAlphaVantageAPIKey + "&datatype=csv&outputsize=full"); break; default: throw new ArgumentException("Unsuported candlestick period", "iCandlestickPeriod"); } HttpWebResponse response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode != HttpStatusCode.OK) { throw new Exception("Could not load candlesticks."); } using (Stream stream = response.GetResponseStream()) using (StreamReader reader = new StreamReader(stream)) { List <Candlestick> results = Candlestick.LoadCSV(reader, iCandlestickPeriod, 0); results.Reverse(); // Remove not full periods. if (Utils.UnixToDateTime(results[results.Count - 1].EndTime) > DateTime.UtcNow) { results.RemoveAt(results.Count - 1); } return(results); } }
//************************************************************************************** public static WekaJ48 CreateNew(int iParamtersID, List <ClassifierParameter> iParameters, Candlestick.Period iPeriod, int iProfitTime, List <int> iTrainingPoints) { // Create WekaInfo and retrive ID var info = new WekaInfo(null, typeof(WekaJ48), iParamtersID, iPeriod, iProfitTime); WekaInfo.InsertToDB(info); if (info.ID is null) { throw new Exception("Could not deduct ID"); } // Create J48Info var j48Info = new WekaJ48Info((int)info.ID); WekaJ48Info.UpdateDB(j48Info); // Save training points if (iTrainingPoints != null) { SaveTrainingPoints(iTrainingPoints, "Data/TrainingPoints/Classifier_" + info.ID.ToString() + ".dat"); } // Create classifier return(new WekaJ48(info, iParameters, j48Info)); }
//************************************************************************************** /// <summary> /// Creates and fills in weka instances object. /// </summary> protected static weka.core.Instances CreateInstances(CandlestickCollection iCandlesticks, List <int> iTrainingPoints, java.util.ArrayList iAttributes, List <ClassifierParameter> iParameters, Candlestick.Period iPeriod, int iMaxProfitTime) { int dataSize = iTrainingPoints.Count; // Create instance object var instances = new weka.core.Instances("Data", iAttributes, dataSize); // Set class index instances.setClassIndex(instances.numAttributes() - 1); // Fill instances FillInstances(instances, CalculateDecisions(iCandlesticks[kTrainingPeriod], iTrainingPoints, iMaxProfitTime), CalculateParameters(iParameters, iCandlesticks, iTrainingPoints, iPeriod)); return(instances); }
//************************************************************************************** public static WekaLinearRegression CreateNew(int iParamtersID, List <ClassifierParameter> iParameters, Candlestick.Period iPeriod, int iProfitTime, List <int> iTrainingPoints, bool iEliminateColinearAttributes, bool iMinimal) { // Create WekaInfo and retrive ID var info = new WekaInfo(null, typeof(WekaJ48), iParamtersID, iPeriod, iProfitTime); WekaInfo.InsertToDB(info); if (info.ID is null) { throw new Exception("Could not deduct ID"); } // Create LinearRegressionInfo var lrInfo = new WekaLinearRegressionInfo((int)info.ID, iEliminateColinearAttributes, iMinimal); WekaLinearRegressionInfo.UpdateDB(lrInfo); // Save training points if (iTrainingPoints != null) { SaveTrainingPoints(iTrainingPoints, "Data/TrainingPoints/Classifier_" + info.ID.ToString() + ".dat"); } // Create classifier return(new WekaLinearRegression(info, iParameters, lrInfo)); }
//************************************************************************************** public List <Candlestick> this[Candlestick.Period candlestickPeriod] { get => this[(int)candlestickPeriod];
//************************************************************************************** /// <summary> /// Returns calculated parameters. /// </summary> /// <param name="iCurrentPrice">Last known price.</param> /// <param name="iCandlestickIndex">Provides index (current time) for each candlestick list. If this value is set to null, the most recent entry will be used.</param> /// <param name="iCandlesticks">Maximum amount of daily candlesticks: 270; 12H: 25; 6H: 50; 3H: 100; 2H: 150; 1H: 300; 30m: 600; 15m: 0; 5m: 0; 1m:0</param> public static float[] CalculateParameters(List <ClassifierParameter> iParameters, CandlestickCollection iCandlesticks, Candlestick.Period iPeriod, float iCurrentPrice, CandlestickIndexCollection iCandlestickIndex) { var candlesticks = iCandlesticks[iPeriod]; int candlestickIndex = iCandlestickIndex == null ? candlesticks.Count - 1 : iCandlestickIndex[iPeriod]; if (candlestickIndex >= iCandlesticks[iPeriod].Count) { throw new Exception("Candlestick index is higher than total number of candlesticks"); } // Make sure we have enough periods for (int i = 0; i < iParameters.Count; i++) { if (candlesticks.Count < iParameters[i].Periods + 10) { return(null); } } float[] results = new float[iParameters.Count]; var macd = new SortedDictionary <int, MACD>(); var macdCurrentPrice = new SortedDictionary <int, MACD>(); for (int i = 0; i < iParameters.Count; i++) { //int candlestickIndex = Candlestick.GetIndex(iParameters[i].Candlesticks, iCandlesticks, iCandlestickIndex); int periods = iParameters[i].Periods; switch (iParameters[i].Type) { case ParameterType.RSI: results[i] = TechnicalIndicators.CalculateRSI(candlesticks, periods, candlestickIndex); break; case ParameterType.RSIWithCurrentPrice: results[i] = TechnicalIndicators.CalculateRSI(candlesticks, periods, candlestickIndex, iCurrentPrice); break; case ParameterType.RSIInt: results[i] = TechnicalIndicators.RSIToInt(TechnicalIndicators.CalculateRSI(candlesticks, periods, candlestickIndex)); break; case ParameterType.RSIIntWithCurrentPrice: results[i] = TechnicalIndicators.RSIToInt(TechnicalIndicators.CalculateRSI(candlesticks, periods, candlestickIndex, iCurrentPrice)); break; case ParameterType.LastCriticalRSI: int startIndex = Math.Max(candlestickIndex - 270 + iParameters[i].Periods, iParameters[i].Periods); int lastCriticalRSI = 0; for (int k = startIndex; k >= candlestickIndex; k++) { lastCriticalRSI = TechnicalIndicators.CalculateLastCriticalRSI(TechnicalIndicators.RSIToInt(TechnicalIndicators.CalculateRSI(candlesticks, periods, k)), lastCriticalRSI); } results[i] = lastCriticalRSI; break; case ParameterType.LastCriticalRSIWithCurrentPrice: startIndex = Math.Max(candlestickIndex - 270 + iParameters[i].Periods, iParameters[i].Periods); lastCriticalRSI = 0; for (int k = startIndex; k >= candlestickIndex; k++) { lastCriticalRSI = TechnicalIndicators.CalculateLastCriticalRSI(TechnicalIndicators.RSIToInt(TechnicalIndicators.CalculateRSI(candlesticks, periods, k, iCurrentPrice)), lastCriticalRSI); } results[i] = lastCriticalRSI; break; case ParameterType.MeanToStd: results[i] = TechnicalIndicators.CalculateMeanToStdDev(candlesticks, periods, candlestickIndex, iCurrentPrice); break; case ParameterType.MeanToStdInt: results[i] = (float)Math.Floor(TechnicalIndicators.CalculateMeanToStdDev(candlesticks, periods, candlestickIndex, iCurrentPrice)); break; case ParameterType.LinearRegressionSlope: results[i] = (float)TechnicalIndicators.CalculateLinearRegressionSlope(candlesticks, periods, candlestickIndex); break; case ParameterType.LinearRegressionSlopePN: results[i] = TechnicalIndicators.CalculateLinearRegressionSlope(candlesticks, periods, candlestickIndex) >= 0 ? 1 : -1; break; case ParameterType.MarginSlope: results[i] = TechnicalIndicators.CalculateMarginSlope(candlesticks, periods, candlestickIndex, iCurrentPrice, iParameters[i].Attributes[0]); break; case ParameterType.MarginSlopePN: results[i] = TechnicalIndicators.CalculateMarginSlopePN(candlesticks, periods, candlestickIndex, iCurrentPrice, iParameters[i].Attributes[0]); break; case ParameterType.MACDSign: if (!macd.ContainsKey(periods)) { macd.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex)); } results[i] = macd[periods].Signal; break; case ParameterType.MACDSignWithCurrentPrice: if (!macdCurrentPrice.ContainsKey(periods)) { macdCurrentPrice.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex, iCurrentPrice)); } results[i] = macdCurrentPrice[periods].Signal; break; case ParameterType.MACDHist: if (!macd.ContainsKey(periods)) { macd.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex)); } results[i] = macd[periods].Hist; break; case ParameterType.MACDHistWithCurrentPrice: if (!macdCurrentPrice.ContainsKey(periods)) { macdCurrentPrice.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex, iCurrentPrice)); } results[i] = macdCurrentPrice[periods].Hist; break; case ParameterType.MACDHistChange: if (!macd.ContainsKey(periods)) { macd.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex)); } MACD macd90 = macd[periods]; MACD previousMACD90 = TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex - 1); results[i] = previousMACD90.Hist == 0 ? 0 : (macd90.Hist / previousMACD90.Hist - 1); break; case ParameterType.MACDHistChangeWithCurrentPrice: if (!macdCurrentPrice.ContainsKey(periods)) { macdCurrentPrice.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex, iCurrentPrice)); } macd90 = macdCurrentPrice[periods]; previousMACD90 = TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex - 1); results[i] = previousMACD90.Hist == 0 ? 0 : (macd90.Hist / previousMACD90.Hist - 1); break; case ParameterType.MACDHistSlope: float[] hist = new float[(int)iParameters[i].Attributes[0]]; for (int k = hist.Length - 1; k >= 0; k--) { hist[hist.Length - 1 - k] = TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex - k).Hist; } results[i] = new LinearRegression(hist).Slope; break; case ParameterType.MACDHistPN: if (!macd.ContainsKey(periods)) { macd.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex)); } results[i] = macd[periods].Hist >= 0 ? 1 : -1; break; case ParameterType.MACDHistCrossed: if (!macd.ContainsKey(periods)) { macd.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex)); } macd90 = macd[periods]; previousMACD90 = TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex - 1); if (macd90.Hist >= 0) { results[i] = previousMACD90.Hist >= 0 ? 0 : 1; } else { results[i] = previousMACD90.Hist < 0 ? 0 : -1; } break; case ParameterType.MACDHistDifference: if (!macd.ContainsKey(periods)) { macd.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex)); } macd90 = macd[periods]; previousMACD90 = TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex - 1); results[i] = macd90.Hist - previousMACD90.Hist; break; case ParameterType.MACD: if (!macd.ContainsKey(periods)) { macd.Add(periods, TechnicalIndicators.CalculateMACD(candlesticks, periods, candlestickIndex)); } results[i] = macd[periods].Macd; break; case ParameterType.SlopesEMA: List <float> slopes = new List <float>(); for (int k = 0; k < iParameters[i].Attributes.Count; k++) { int periodLength = (int)iParameters[i].Attributes[k]; slopes.Add(new LinearRegression(TechnicalIndicators.CreatePriceArray(candlesticks, periodLength, candlestickIndex)).Slope); } results[i] = Utils.Last(Statistics.EMA(slopes.ToArray(), slopes.Count)); break; case ParameterType.ABAverage: results[i] = (TechnicalIndicators.CalculatePriceABaverage(candlesticks, periods, candlestickIndex, iCurrentPrice) ? 1.0f : 0.0f); break; case ParameterType.PercentMargin: results[i] = (TechnicalIndicators.CalculateOnePercentMargin(candlesticks, periods, candlestickIndex, iCurrentPrice, iParameters[i].Attributes[0]) ? 1.0f : 0.0f); break; case ParameterType.Classifier: results[i] = WekaClassifier.Find((int)iParameters[i].Attributes[0]).PredictDFP(iCandlesticks, iCurrentPrice, iCandlestickIndex); break; case ParameterType.ClassifierTargetChangeOldest: var classifier = WekaClassifier.Find((int)iParameters[i].Attributes[0]); var targetTime = iCandlesticks[WekaClassifier.kTrainingPeriod][iCandlestickIndex[WekaClassifier.kTrainingPeriod] - classifier.ProfitTime].StartTime; var pastIndex = new CandlestickIndexCollection(); for (int k = (int)WekaClassifier.kTrainingPeriod; k >= 0; k--) { pastIndex[k] = Math.Max(0, Math.Min(iCandlesticks[k].Count - 1, Candlestick.FindIndex(iCandlesticks[k], targetTime))); } var priceBefore = iCandlesticks[WekaClassifier.kTrainingPeriod][pastIndex[WekaClassifier.kTrainingPeriod]].MedianPrice; var wfp = classifier.PredictDFP(iCandlesticks, priceBefore, pastIndex); var targetPriceChange = (float)Math.Exp(wfp); results[i] = priceBefore * targetPriceChange / iCurrentPrice - 1.0f; break; } } return(results); }
//************************************************************************************** public int this[Candlestick.Period candlestickPeriod] { get => this[(int)candlestickPeriod];
//************************************************************************************** /// <summary> /// Performs simulation and outputs results to a DataTable /// </summary> public static DataTable PerformSimulation(CandlestickCollection iCandlesticks, List <WekaClassifier> iClassifiers, DateTime iStartTime, int iNumberOfHours, Candlestick.Period iOutputPeriod = Candlestick.Period.H1) { // Create new data table. var table = new DataTable(iCandlesticks.type.ToString() + "Simulation_" + iStartTime.Year + "_" + iStartTime.Month + "_" + iStartTime.Day + "_" + iNumberOfHours); table.Columns.Add("EndTime", typeof(DateTime)); if (iCandlesticks.type != CandlestickCollection.Type.Realtime) { table.Columns.Add("RealPrice", typeof(float)); } table.Columns.Add("SimulationPrice", typeof(float)); try { CandlestickCollection.Split(iCandlesticks, iStartTime, Candlestick.Period.H1, out CandlestickCollection results, out CandlestickCollection oPart2); var startIndex = results[iOutputPeriod].Count; Start(iCandlesticks, results, iClassifiers, iNumberOfHours); var endIndex = iCandlesticks.type == CandlestickCollection.Type.Realtime ? results[iOutputPeriod].Count : Math.Min(results[iOutputPeriod].Count, iCandlesticks[iOutputPeriod].Count); for (int i = startIndex; i < endIndex; i++) { var row = table.NewRow(); row["EndTime"] = Utils.UnixToDateTime(results[iOutputPeriod][i].EndTime); if (iCandlesticks.type != CandlestickCollection.Type.Realtime) { row["RealPrice"] = iCandlesticks[iOutputPeriod][i].MedianPrice; } row["SimulationPrice"] = results[iOutputPeriod][i].MedianPrice; table.Rows.Add(row); } if (iCandlesticks.type == CandlestickCollection.Type.Realtime) { var medians = new List <float>(24); var sindex = Candlestick.FindIndex(results[Candlestick.Period.H1], Utils.DateTimeToUnix(iStartTime)); for (int i = sindex; i < Math.Min(sindex + 24, results[Candlestick.Period.H1].Count); i++) { medians.Add(results[Candlestick.Period.H1][i].MedianPrice); } var low = float.MaxValue; var high = float.MinValue; for (int i = sindex; i < results[Candlestick.Period.H1].Count; i++) { var p = results[Candlestick.Period.H1][i].MedianPrice; if (p < low) { low = p; } if (p > high) { high = p; } } Console.WriteLine("Next 24 hours estimated median price: " + medians.Median()); Console.WriteLine("Next 7 days High/Low: " + high.ToString() + "/" + low.ToString()); } } catch (Exception ex) { Console.WriteLine("Exception was thrown while performing simulation: " + table.TableName + " Exp.:" + ex.ToString()); } return(table); }