//************************************************************************************** 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)); }
//************************************************************************************** public override void RebuildClassifier() { Console.WriteLine("Rebuilding classifier: " + ID); // Start removal from children foreach (var i in J48Info.ChildrenID) { if (i != null) { var c = Find((int)i); if (c != null) { c.RemoveClassifier(); } } } // Update info J48Info.OnClassifierRebuild(); WekaJ48Info.UpdateDB(J48Info); // Remove model DeleteModel(ID); // Remove training data DeleteTrainingPoints(ID); }
//************************************************************************************** public override void RemoveClassifier() { if (!Exist(ID)) { return; } Console.WriteLine("Removing classifier: " + ID); // Start removal from children foreach (var i in J48Info.ChildrenID) { if (i != null) { var c = Find((int)i); if (c != null) { c.RemoveClassifier(); } } } // Remove model DeleteModel(ID); // Remove training data DeleteTrainingPoints(ID); // Remove info from parents if (J48Info.ParentID != null) { if (Find((int)J48Info.ParentID) is WekaJ48 parent) { for (int i = 0; i < parent.J48Info.ChildrenID.Length; i++) { if (parent.J48Info.ChildrenID[i] == ID) { parent.J48Info.ChildrenID[i] = null; WekaJ48Info.UpdateDB(parent.J48Info); } } } } // Remove info WekaJ48Info.RemoveFromDB(ID); WekaInfo.RemoveFromDB(ID); // Remove target classifier from static list classifiers.Remove(ID); }
//************************************************************************************** /// <summary> /// Inserts prediction profits info to DB /// </summary> public static void UpdateDB(WekaJ48Info iInfo) { var sql = "IF EXISTS(SELECT * FROM J48Info WHERE Id = @ID) " + "Update J48Info SET " + "ProfitAverage = @ProfitAverage, ProfitStdDev = @ProfitStdDev, Precision = @Precision, ParentID=@ParentID, ChildWeakBuyID=@ChildWeakBuyID, ChildBuyID=@ChildBuyID, ChildStrongBuyID=@ChildStrongBuyID, ChildWeakSellID=@ChildWeakSellID, ChildSellID=@ChildSellID, ChildStrongSellID=@ChildStrongSellID, ReproductionComplete=@ReproductionComplete, IsSingular=@IsSingular, PPWeakBuy=@PPWeakBuy, PPBuy=@PPBuy, PPStrongBuy=@PPStrongBuy, PPWeakSell=@PPWeakSell, PPSell=@PPSell, PPStrongSell=@PPStrongSell " + " Where ID = @ID " + "ELSE" + " INSERT INTO J48Info (Id, ProfitAverage, ProfitStdDev, Precision, ParentID, ChildWeakBuyID, ChildBuyID, ChildStrongBuyID, ChildWeakSellID, ChildSellID, ChildStrongSellID, ReproductionComplete, IsSingular, PPWeakBuy, PPBuy, PPStrongBuy, PPWeakSell, PPSell, PPStrongSell) VALUES(@ID, @ProfitAverage, @ProfitStdDev, @Precision, @ParentID, @ChildWeakBuyID, @ChildBuyID, @ChildStrongBuyID, @ChildWeakSellID, @ChildSellID, @ChildStrongSellID, @ReproductionComplete, @IsSingular, @PPWeakBuy, @PPBuy, @PPStrongBuy, @PPWeakSell, @PPSell, @PPStrongSell)"; using (var connection = new SqlConnection(Program.SQLConnectionName)) { connection.Open(); var cmd = new SqlCommand(sql, connection); cmd.Parameters.AddWithValue("@Id", iInfo.ID); cmd.Parameters.AddWithValue("@ProfitAverage", (object)iInfo.ProfitAverage ?? DBNull.Value); cmd.Parameters.AddWithValue("@ProfitStdDev", (object)iInfo.ProfitStdDev ?? DBNull.Value); cmd.Parameters.AddWithValue("@Precision", (object)iInfo.Precision ?? DBNull.Value); cmd.Parameters.AddWithValue("@ParentID", (object)iInfo.ParentID ?? DBNull.Value); foreach (WekaJ48.Prediction p in (WekaJ48.Prediction[])Enum.GetValues(typeof(WekaJ48.Prediction))) { cmd.Parameters.AddWithValue("@Child" + p.ToString() + "ID", (object)iInfo.ChildrenID[(int)p] ?? DBNull.Value); } cmd.Parameters.AddWithValue("@ReproductionComplete", (object)iInfo.ReproductionComplete ?? DBNull.Value); cmd.Parameters.AddWithValue("@IsSingular", (object)iInfo.IsSingular ?? DBNull.Value); foreach (WekaJ48.Prediction p in (WekaJ48.Prediction[])Enum.GetValues(typeof(WekaJ48.Prediction))) { cmd.Parameters.AddWithValue("@PP" + p.ToString(), (object)iInfo.PredictionProfits[(int)p] ?? DBNull.Value); } var dataAdapter = new SqlDataAdapter { InsertCommand = cmd }; dataAdapter.InsertCommand.ExecuteNonQuery(); dataAdapter.InsertCommand.Dispose(); } }
//************************************************************************************** /// <summary> /// Build cllasifier model and save it to a file. /// </summary> public override void Build(CandlestickCollection iCandlestick) { List <int> trainingPoints = null; // Calculate average profit and std dev if (J48Info.ProfitAverage is null || J48Info.ProfitStdDev is null) { trainingPoints = LoadTrainingPoints(iCandlestick, ID, ProfitTime); float[] profits = FullToTraining(new List <float>(CalculateFutureProfits(iCandlestick[kTrainingPeriod], ProfitTime)), trainingPoints).ToArray(); J48Info.ProfitStdDev = Statistics.StandardDeviation(profits); J48Info.ProfitAverage = J48Info.ParentID is null ? 0.0f : Statistics.ArithmeticMean(profits); WekaJ48Info.UpdateDB(J48Info); } // Build model if (!File.Exists(ModelFilename)) { OutputMessage("Building model"); if (trainingPoints is null) { trainingPoints = LoadTrainingPoints(iCandlestick, ID, ProfitTime); } Model = new weka.classifiers.trees.J48(); Model.buildClassifier(CreateInstances(iCandlestick, trainingPoints, Attributes, Parameters, Period, ProfitTime)); weka.core.SerializationHelper.write(ModelFilename, Model); } // Perfrom crossfold test if (J48Info.Precision is null) { if (Model is null) { LoadModel(); } OutputMessage("Perfroming crossfold"); if (trainingPoints is null) { trainingPoints = LoadTrainingPoints(iCandlestick, ID, ProfitTime); } var instances = CreateInstances(iCandlestick, trainingPoints, Attributes, Parameters, Period, ProfitTime); var evaluation = new weka.classifiers.Evaluation(instances); evaluation.crossValidateModel(Model, instances, 10, new java.util.Random(0)); J48Info.Precision = (float)evaluation.pctCorrect(); WekaJ48Info.UpdateDB(J48Info); } // Perfrom singular test if (J48Info.IsSingular == null) { if (Model is null) { LoadModel(); } OutputMessage("Perfroming singular test"); var results = new SortedList <Prediction, List <int> >(); foreach (Prediction p in (Prediction[])Enum.GetValues(typeof(Prediction))) { results.Add(p, new List <int>()); } if (trainingPoints is null) { trainingPoints = LoadTrainingPoints(iCandlestick, ID, ProfitTime); } var parameters = CalculateParameters(Parameters, iCandlestick, trainingPoints, Period); for (int k = 0; k < parameters.Count; k++) { var pred = Predict(parameters[k]); results[pred].Add(trainingPoints[k]); } J48Info.IsSingular = results.Count(x => x.Value.Count > 0) <= 1; WekaJ48Info.UpdateDB(J48Info); } // Calculating prediction profits if (J48Info.PredictionProfits.Count(x => x != null) == 0) { if (Model is null) { LoadModel(); } OutputMessage("Calculating prediction profits"); if (trainingPoints is null) { trainingPoints = LoadTrainingPoints(iCandlestick, ID, ProfitTime); } var predictionPoints = GetHistoricalPredictionPoints(iCandlestick, trainingPoints); foreach (Prediction p in (Prediction[])Enum.GetValues(typeof(Prediction))) { float[] profits = FullToTraining(new List <float>(CalculateFutureProfits(iCandlestick[kTrainingPeriod], ProfitTime)), predictionPoints[p]).ToArray(); if (profits.Length < 10) { J48Info.PredictionProfits[(int)p] = DecisionToFutureProfit(p, (float)J48Info.ProfitStdDev, (float)J48Info.ProfitAverage); } else { J48Info.PredictionProfits[(int)p] = Statistics.ArithmeticMean(profits); } } WekaJ48Info.UpdateDB(J48Info); } // Create children if (!J48Info.ReproductionComplete.GetValueOrDefault(false)) { lock (this) { if (J48Info.Precision > 50.0f && !J48Info.IsSingular.GetValueOrDefault(false)) { OutputMessage("Creating children"); if (trainingPoints is null) { trainingPoints = LoadTrainingPoints(iCandlestick, ID, ProfitTime); } var predictionPoints = GetHistoricalPredictionPoints(iCandlestick, trainingPoints); foreach (Prediction p in (Prediction[])Enum.GetValues(typeof(Prediction))) { if (predictionPoints[p] != null && predictionPoints[p].Count >= 1000 && J48Info.ChildrenID[(int)p] == null) { var child = CreateNew(ParametersID, Parameters, Period, ProfitTime, predictionPoints[p]); // Set parent child.J48Info.ParentID = ID; WekaJ48Info.UpdateDB(child.J48Info); // Update parent info J48Info.ChildrenID[(int)p] = (int)child.ID; WekaJ48Info.UpdateDB(J48Info); childs[(int)p] = child; } } } J48Info.ReproductionComplete = true; WekaJ48Info.UpdateDB(J48Info); } } }
//************************************************************************************** public WekaJ48(WekaInfo iInfo, List <ClassifierParameter> iParameters, WekaJ48Info iJ48Info) : base(iInfo, iParameters) { J48Info = iJ48Info ?? throw new ArgumentNullException("iJ48Info"); }
//************************************************************************************** /// <summary> /// Loads prediction profits from DB. /// </summary> public static List <WekaJ48Info> LoadFromDB() { var results = new List <WekaJ48Info>(); var sql = "Select * from J48Info"; using (var connection = new SqlConnection(Program.SQLConnectionName)) { connection.Open(); var command = new SqlCommand(sql, connection); using (var reader = command.ExecuteReader()) while (reader.Read()) { var info = new WekaJ48Info(reader.GetInt32(reader.GetOrdinal("Id"))); if (!reader.IsDBNull(reader.GetOrdinal("ProfitAverage"))) { info.ProfitAverage = (float)reader.GetDouble(reader.GetOrdinal("ProfitAverage")); } if (!reader.IsDBNull(reader.GetOrdinal("ProfitStdDev"))) { info.ProfitStdDev = (float)reader.GetDouble(reader.GetOrdinal("ProfitStdDev")); } if (!reader.IsDBNull(reader.GetOrdinal("Precision"))) { info.Precision = (float)reader.GetDouble(reader.GetOrdinal("Precision")); } if (!reader.IsDBNull(reader.GetOrdinal("ParentID"))) { info.ParentID = reader.GetInt32(reader.GetOrdinal("ParentID")); } foreach (WekaJ48.Prediction p in (WekaJ48.Prediction[])Enum.GetValues(typeof(WekaJ48.Prediction))) { if (!reader.IsDBNull(reader.GetOrdinal("Child" + p.ToString() + "ID"))) { info.ChildrenID[(int)p] = reader.GetInt32(reader.GetOrdinal("Child" + p.ToString() + "ID")); } } if (!reader.IsDBNull(reader.GetOrdinal("ReproductionComplete"))) { info.ReproductionComplete = reader.GetBoolean(reader.GetOrdinal("ReproductionComplete")); } if (!reader.IsDBNull(reader.GetOrdinal("IsSingular"))) { info.IsSingular = reader.GetBoolean(reader.GetOrdinal("IsSingular")); } foreach (WekaJ48.Prediction p in (WekaJ48.Prediction[])Enum.GetValues(typeof(WekaJ48.Prediction))) { if (!reader.IsDBNull(reader.GetOrdinal("PP" + p.ToString()))) { info.PredictionProfits[(int)p] = (float)reader.GetDouble(reader.GetOrdinal("PP" + p.ToString())); } } results.Add(info); } } return(results); }