예제 #1
0
        public void InitializeValuesFrom(ParameterDefinitions other)
        {
            foreach (ParameterDefinition pdNew in this)
            {
                ParameterDefinition pdOld = other.Find(pdNew);
                if (pdOld == null)
                {
                    continue;
                }

                SetParameterDefinition spdOld = pdOld as SetParameterDefinition;
                SetParameterDefinition spdNew = pdNew as SetParameterDefinition;
                if (spdOld == null || spdNew == null)
                {
                    continue;
                }

                spdNew.InitializeFrom(spdOld);
            }
        }
예제 #2
0
        public override void Optimize()
        {
            bool fFirstRun = (_form == null);

            _rgParameterDefinitions = new ParameterDefinitions(this.Strategy, fFirstRun);
            if (fFirstRun)
            {
                _form = new StochasticsOptionsDialog();
            }
            _form.InitializeParameters(_rgParameterDefinitions);

            DateTime dateStartLast = _dateStartLast;

            _dateStartLast = Strategy.BackTestFrom;

            if (!_form.WalkForward || Strategy.BackTestFrom <= dateStartLast)
            {
                if (_form.ShowDialog(Form.ActiveForm) != DialogResult.OK)
                {
                    return;
                }
            }

#if !NT7
            _nPopulationSize   = _form.PopulationSize;
            _cMaxGenerations   = _form.MaxGenerations;
            _fitnessGainMax    = _form.FitnessGain;
            _nPopulationSize   = 10;          //_form.PercentAnnealing;
            _nMinimumPerformce = _form.MinimumPerformance;
#endif

            int cParams = _rgParameterDefinitions.Count;

            _rgParameterRunCounts  = new int [cParams] [];
            _rgParameterRunTotals  = new double [cParams] [];
            _rgParameterRunAverage = new double [cParams] [];

            decimal cCombinationsActual = _rgParameterDefinitions.CountCombinations;
            long    cCombinations       = (long)Math.Min(cCombinationsActual, (decimal)long.MaxValue);

            for (int ipd = 0; ipd < _rgParameterDefinitions.Count; ipd++)
            {
                ParameterDefinition pd = _rgParameterDefinitions [ipd];

                int cValues = pd.CountValues;

                _rgParameterRunCounts [ipd]  = new int [cValues];
                _rgParameterRunTotals [ipd]  = new double [cValues];
                _rgParameterRunAverage [ipd] = new double [cValues];
            }

            Dictionary <ParameterSet, bool> setChildren = new Dictionary <ParameterSet, bool> ();
            List <ParameterSet>             rgChildren  = new List <ParameterSet> ();


            int fitnessGainMin = 1;
            int cAnnealing     = _nPopulationSize * _percentAnnealing / 100;

            // create an initial generation of aliens
            int cIterations = 0;
            while (rgChildren.Count < _nPopulationSize)
            {
                ParameterSet child = CreateAlien();
                if (setChildren.ContainsKey(child))
                {
                    continue;
                }

                setChildren.Add(child, true);
                rgChildren.Add(child);
            }


            DateTime     timeStart   = DateTime.Now;
            ParameterSet bestChild   = null;
            int          iGeneration = 0;
            try
            {
                Strategy.Print(
                    string.Format(
                        "{0}: PH Stochastic Optimizer Start @ {1}, combinations: {2:N0}",
                        Strategy.Instrument.FullName,
                        timeStart,
                        cCombinationsActual
                        )
                    );

                double diffMax     = 0;
                double diffCurr    = 0;
                int    fitnessGain = fitnessGainMin;

                ParameterSet bestPrev = null;
                for (iGeneration = 0; iGeneration < _cMaxGenerations; iGeneration++)
                {
                    // score the new generation
                    ScoreGeneration(rgChildren);

                    rgChildren.Sort();

                    if (bestChild == null)
                    {
                        bestChild = rgChildren [0];
                    }
                    else if (bestChild.Performance < rgChildren [0].Performance)
                    {
                        bestChild = rgChildren [0];
                    }

                    if (bestPrev != null)
                    {
                        if (double.IsNaN(bestPrev.Performance) || bestChild.Performance > bestPrev.Performance)
                        {
                            if (fitnessGain < FitnessGainMax)
                            {
                                fitnessGain++;
                            }
                        }
                        else if (fitnessGain > fitnessGainMin)
                        {
                            fitnessGain--;
                        }
                    }
                    bestPrev = bestChild;

                    cIterations += rgChildren.Count;
                    TimeSpan diff       = DateTime.Now - timeStart;
                    double   iterPerSec = cIterations / diff.TotalSeconds;

                    Strategy.Print(string.Format(
                                       "{0}: gen {1}/{2}, {3:N1} ips, max PERF: {4:N2}, gain={5}\t{6}",
                                       Strategy.Instrument.FullName,
                                       iGeneration + 1,
                                       _cMaxGenerations,
                                       iterPerSec,
                                       bestChild.Performance,
                                       fitnessGain,
                                       bestChild == null ? "" : _rgParameterDefinitions.ToString(bestChild)));

                    if (bestChild != null && bestChild.Performance > this._nMinimumPerformce)
                    {
                        Strategy.Print(string.Format("{0}: Minimum performance reached.", Strategy.Instrument.FullName));
                        return;
                    }

                    if (iGeneration == _cMaxGenerations - 1)
                    {
                        break;
                    }

                    // initialize a new generation
                    rgChildren.Clear();


                    int cCollisions = _nPopulationSize;
                    while (cCollisions > 0 && rgChildren.Count < _nPopulationSize)
                    {
                        int iParam  = _rand.Next(cParams);
                        int cValues = _rgParameterDefinitions [iParam].CountValues;

                        int [] rgParams = new int [cParams];
                        for (int iParamFuzz = 0; iParamFuzz < cParams; iParamFuzz++)
                        {
                            rgParams [iParamFuzz] = bestChild.GetParam(iParamFuzz);
                        }

                        rgParams [iParam] = MutateParam(fitnessGain, cValues, rgParams [iParam]);

                        ParameterSet child = new ParameterSet(rgParams);
                        if (setChildren.ContainsKey(child))
                        {
                            cCollisions--;
                        }
                        else
                        {
                            setChildren.Add(child, true);
                            rgChildren.Add(child);
                        }
                    }

                    double loopFitnessGain = fitnessGain;
                    if (rgChildren.Count < _nPopulationSize)
                    {
                        // pre-calculate the parameter value weights
                        double [] [] rgrgWeights    = new double [cParams] [];
                        double []    rgTotalWeights = new double [cParams];

                        for (int iParam = 0; iParam < cParams; iParam++)
                        {
                            int cValues = _rgParameterDefinitions [iParam].CountValues;
                            rgrgWeights [iParam] = new double [cValues];

                            double [] rgAverages = _rgParameterRunAverage [iParam];


                            // get the range of PERF values
                            double minPerformance = double.PositiveInfinity;
                            double maxPerformance = double.NegativeInfinity;
                            for (int i = 0; i < cValues; i++)
                            {
                                double performance = rgAverages [i];
                                if (minPerformance > performance)
                                {
                                    minPerformance = performance;
                                }
                                if (maxPerformance < performance)
                                {
                                    maxPerformance = performance;
                                }
                            }

                            // weight the procreation probabilities
                            double totalWeight = 0;
                            //if (maxPerformance != minPerformance)
                            {
                                for (int iValue = 0; iValue < cValues; iValue++)
                                {
                                    double average = rgAverages [iValue];
                                    if (double.IsNaN(average) || double.IsInfinity(average))
                                    {
                                        average = maxPerformance;
                                    }

                                    double weight = Math.Pow((average - minPerformance) / (maxPerformance - minPerformance), loopFitnessGain);
                                    if (double.IsNaN(weight))
                                    {
                                        weight = 0.0;
                                    }
                                    weight += 0.001;

                                    rgrgWeights [iParam] [iValue] = weight;
                                    totalWeight += weight;
                                }
                            }

                            rgTotalWeights [iParam] = totalWeight;
                        }

                        cCollisions = _nPopulationSize;
                        while (cCollisions > 0 && rgChildren.Count < _nPopulationSize && setChildren.Count < cCombinations)
                        {
                            // create a new set of genes
                            int [] rgParams = new int [cParams];
                            for (int iParam = 0; iParam < cParams; iParam++)
                            {
                                int       cValues   = _rgParameterDefinitions [iParam].CountValues;
                                double [] rgWeights = rgrgWeights [iParam];

                                double weightRandom = _rand.NextDouble() * rgTotalWeights [iParam];
                                int    iValueRandom = 0;
                                while (iValueRandom < cValues && weightRandom > rgWeights [iValueRandom])
                                {
                                    weightRandom -= rgWeights [iValueRandom];
                                    iValueRandom++;
                                }

                                rgParams [iParam] = iValueRandom;
                            }


                            // create the new child, and make sure it's unique
                            ParameterSet child = new ParameterSet(rgParams);
                            if (setChildren.ContainsKey(child))
                            {
                                if (loopFitnessGain > 1)
                                {
                                    loopFitnessGain--;
                                }

                                cCollisions--;
                            }
                            else
                            {
                                setChildren.Add(child, true);
                                rgChildren.Add(child);
                            }
                        }
                    }
                }
            }
            catch (AbortOptimizationException)
            {
                Strategy.Print("Optimization Aborted...");
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e);
                Strategy.Print(e.ToString());
                //throw;
            }
            finally
            {
#if NT7
                WaitForIterationsCompleted(true);
#endif

                DateTime timeEnd    = DateTime.Now;
                TimeSpan tsDuration = timeEnd - timeStart;

                if (iGeneration > 0)
                {
                    Strategy.Print(string.Format(
                                       "{0}: PH Optimizer End @ {1}, duration: {2} ({3} per iteration)",
                                       Strategy.Instrument.FullName,
                                       timeEnd,
                                       tsDuration,
                                       TimeSpan.FromTicks(tsDuration.Ticks / iGeneration)
                                       )
                                   );
                }

                if (bestChild != null)
                {
                    Dump(bestChild);
                }
            }
        }
예제 #3
0
        internal void InitializeParameters(ParameterDefinitions rgParameterDefinitions)
        {
            if (_rgParameterDefinitions != null)
            {
                rgParameterDefinitions.InitializeValuesFrom(_rgParameterDefinitions);
            }

            tableLayoutPanel1.Controls.Clear();
            tableLayoutPanel1.RowCount = 1;
            _rgParameterDefinitions    = rgParameterDefinitions;

            bool fShowColumns = false;

            int iRow = 0;

            foreach (ParameterDefinition pd in rgParameterDefinitions)
            {
                SetParameterDefinition ed = pd as SetParameterDefinition;
                if (ed != null)
                {
                    fShowColumns = true;

                    CheckBox cbTitle = new CheckBox();
                    cbTitle.Text     = ed.Parameter.Name;
                    cbTitle.AutoSize = true;
                    cbTitle.Anchor   = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;

                    int iRowStart = iRow;

                    List <CheckBox> rgCheckboxes = new List <CheckBox> ();

                    bool fUpdating = false;

                    Action <bool> initTitleCheckbox = delegate(bool f)
                    {
                        bool fAllChecked   = true;
                        bool fAllUnchecked = true;

                        foreach (CheckBox cb in rgCheckboxes)
                        {
                            if (cb.Checked)
                            {
                                fAllUnchecked = false;
                            }
                            else
                            {
                                fAllChecked = false;
                            }
                        }

                        if (!fAllChecked && !fAllUnchecked)
                        {
                            cbTitle.CheckState = CheckState.Indeterminate;
                        }
                        else
                        {
                            cbTitle.CheckState = fAllChecked ? CheckState.Checked : CheckState.Unchecked;
                        }
                    };

                    foreach (SetParameterDefinition.ValueInfo pvdEnum in ed.GetPossibleValues())
                    {
                        SetParameterDefinition.ValueInfo pvd = pvdEnum;                         // extract for closure

                        CheckBox cbValue = new CheckBox();
                        cbValue.Text            = pvd.Name;
                        cbValue.AutoSize        = true;
                        cbValue.Anchor          = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
                        cbValue.Margin          = new Padding(0);
                        cbValue.Checked         = pvd.IsActive;
                        cbValue.CheckedChanged += delegate(object sender, EventArgs args)
                        {
                            pvd.Setter(cbValue.Checked);

                            if (fUpdating)
                            {
                                return;
                            }

                            try
                            {
                                fUpdating = true;
                                initTitleCheckbox(true);
                            }
                            finally
                            {
                                fUpdating = false;
                            }
                        };

                        rgCheckboxes.Add(cbValue);

                        while (iRow >= tableLayoutPanel1.RowCount)
                        {
                            tableLayoutPanel1.RowCount++;
                        }

                        tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.AutoSize));
                        tableLayoutPanel1.Controls.Add(cbValue, 1, iRow);

                        iRow++;
                    }

                    tableLayoutPanel1.Controls.Add(cbTitle, 0, iRowStart);
                    tableLayoutPanel1.SetRowSpan(cbTitle, tableLayoutPanel1.RowCount - iRowStart - 1);

                    initTitleCheckbox(true);

                    cbTitle.CheckedChanged += delegate(object sender, EventArgs args)
                    {
                        if (fUpdating)
                        {
                            return;
                        }

                        try
                        {
                            fUpdating = true;
                            foreach (CheckBox cb in rgCheckboxes)
                            {
                                cb.Checked = cbTitle.Checked;
                            }
                        }
                        finally
                        {
                            fUpdating = false;
                        }
                    };
                }
            }

            if (fShowColumns != panel1.Enabled)
            {
                panel1.Visible = panel1.Enabled = fShowColumns;

                if (fShowColumns)
                {
                    this.Width += panel1.Width;
                }
                else
                {
                    this.Width -= panel1.Width;
                }
            }
        }
예제 #4
0
        public override void Optimize()
        {
            DNA dnaBestEver = null;

            try
            {
                // initialize the parameter definition

                bool fFirstRun = (_form == null);
                _rgParameterDefinitions = new ParameterDefinitions(this.Strategy, fFirstRun);
                if (fFirstRun)
                {
                    _form = new GeneticOptionsDialog();
                }
                _form.InitializeParameters(_rgParameterDefinitions);

                DateTime dateStartLast = _dateStartLast;
                _dateStartLast = Strategy.BackTestFrom;

                if (!_form.WalkForward || Strategy.BackTestFrom <= dateStartLast)
                {
                    if (_form.ShowDialog(Form.ActiveForm) != DialogResult.OK)
                    {
#if NT7
                        WaitForIterationsCompleted(true);
#endif
                        return;
                    }
                }

#if !NT7
                _nPopulationSize   = _form.PopulationSize;
                _cMaxGenerations   = _form.MaxGenerations;
                _mutationRate      = _form.MutationRate;
                _mutationStrength  = _form.MutationStrength;
                _fitnessGain       = _form.FitnessGain;
                _percentAliens     = _form.Aliens;
                _stabilitySize     = _form.StabilitySize;
                _resetSize         = _form.ResetSize;
                _nMinimumPerformce = _form.MinimumPerformance;
#endif

                int cAliens        = (int)Math.Ceiling(_nPopulationSize * _percentAliens);
                int nStabilitySize = (int)Math.Ceiling(_nPopulationSize * _stabilitySize);
                int nResetSize     = _nPopulationSize - (int)Math.Ceiling(_nPopulationSize * _resetSize);

                DateTime timeStart = DateTime.Now;

                int cParams = _rgParameterDefinitions.Count;

                decimal cCombinationsActual = _rgParameterDefinitions.CountCombinations;
                long    cCombinations       = (long)Math.Min(cCombinationsActual, (decimal)long.MaxValue);

                Strategy.Print(
                    string.Format(
                        "{0}: PH Genetic Optimizer Start @ {1}, combinations: {2:N0}",
                        Strategy.Instrument.FullName,
                        timeStart,
                        cCombinationsActual
                        )
                    );


                List <DNA>             rgChildren  = new List <DNA> ();
                Dictionary <DNA, bool> setChildren = new Dictionary <DNA, bool> ();

                // create an initial generation of aliens
                int cIterations = 0;


                double stabilityScorePrev = double.NaN;

                List <DNA> rgParents = new List <DNA> ();
                int        iGeneration;
                for (iGeneration = 1; iGeneration <= _cMaxGenerations; iGeneration++)
                {
                    // fill the rest of this generation with aliens
                    while (rgChildren.Count < _nPopulationSize && setChildren.Count < cCombinations)
                    {
                        DNA child = CreateAlien(0);
                        if (setChildren.ContainsKey(child))
                        {
                            continue;
                        }

                        setChildren.Add(child, true);
                        rgChildren.Add(child);
                    }

                    DNA dnaBestSinceReset = null;

                    try
                    {
                        // score the new generation
                        ScoreGeneration(rgChildren);

                        //if (rgParents.Count > nPopulationSize)
                        //	rgParents.RemoveRange (nPopulationSize, rgParents.Count - nPopulationSize);

                        rgParents.AddRange(rgChildren);
                        rgParents.Sort();

                        dnaBestSinceReset = rgParents [0];
                    }
                    finally
                    {
                        if (rgParents.Count > 0 &&
                            dnaBestSinceReset != null &&
                            (dnaBestEver == null || dnaBestEver.Performance < dnaBestSinceReset.Performance))
                        {
                            dnaBestEver = dnaBestSinceReset;
                        }
                    }

                    double stabilityScore        = 0.0;
                    int    cStabilityIndividuals = (int)Math.Min(rgParents.Count, nStabilitySize);
                    if (cStabilityIndividuals < 1)
                    {
                        cStabilityIndividuals = 1;
                    }

                    for (int i = 0; i < cStabilityIndividuals; i++)
                    {
                        double scoreParent = rgParents [i].Performance;
                        if (scoreParent > double.NegativeInfinity)
                        {
                            stabilityScore += rgParents [i].Performance;
                        }
                    }

                    cIterations += rgChildren.Count;
                    TimeSpan diff       = DateTime.Now - timeStart;
                    double   iterPerSec = cIterations / diff.TotalSeconds;

                    Strategy.Print(string.Format(
                                       "{0}: gen {1}/{2}, {3:N1} ips, max PERF: {4:N2}, stability PERF: {5:N2}\t{6}",
                                       Strategy.Instrument.FullName,
                                       iGeneration,
                                       _cMaxGenerations,
                                       iterPerSec,
                                       dnaBestSinceReset.Performance,
                                       stabilityScore / cStabilityIndividuals,
                                       rgParents.Count == 0 ? "" : _rgParameterDefinitions.ToString(dnaBestSinceReset)));


                    if (dnaBestEver != null)
                    {
                        Strategy.Print(dnaBestEver.Performance + ", " + _nMinimumPerformce);
                    }
                    if (dnaBestEver != null && dnaBestEver.Performance > _nMinimumPerformce)
                    {
                        Strategy.Print(string.Format("{0}: Minimum performance reached.", Strategy.Instrument.FullName));
                        return;
                    }

                    if (iGeneration == _cMaxGenerations)
                    {
                        break;
                    }

                    if (setChildren.Count >= cCombinations)
                    {
                        break;
                    }

                    if (stabilityScore == stabilityScorePrev)
                    {
                        //rgParents.RemoveRange (1, rgParents.Count - 1);
                        rgParents.Clear();
                        rgChildren.Clear();
                        Strategy.Print(string.Format(
                                           "{0}: reset",
                                           Strategy.Instrument.FullName
                                           )
                                       );
                        //stabilityScore = double.NaN;

                        continue;
                    }

                    // get the range of PERF values
                    double minPerformance = double.MaxValue;
                    double maxPerformance = double.MinValue;
                    for (int i = 0; i < rgParents.Count; i++)
                    {
                        double performance = rgParents [i].Performance;
                        if (performance == double.NegativeInfinity)
                        {
                            continue;
                        }
                        if (minPerformance > performance)
                        {
                            minPerformance = performance;
                        }
                        if (maxPerformance < performance)
                        {
                            maxPerformance = performance;
                        }
                    }

                    // weight the procreation probabilities
                    if (maxPerformance != minPerformance)
                    {
                        for (int i = 0; i < rgParents.Count; i++)
                        {
                            DNA    parent      = rgParents [i];
                            double performance = parent.Performance;
                            if (performance == double.NegativeInfinity)
                            {
                                parent.Weight = 0;
                            }
                            else
                            {
                                double weight = (parent.Performance - minPerformance) / (maxPerformance - minPerformance);
#if true
                                parent.Weight = Math.Pow(weight, _fitnessGain) + 0.001;
#else
                                parent.Weight = (Math.Pow(weight, fitnessGain / (iGeneration - parent.Generation)) + 0.001);
#endif
                            }
                        }
                    }

                    double totalWeight = 0;
                    for (int i = 0; i < rgParents.Count; i++)
                    {
                        totalWeight += rgParents [i].Weight;
                    }


                    // initialize a new generation
                    rgChildren.Clear();

                    // a certain percentage of the new population are aliens:
                    int cAliensThisGeneration;
                    if (stabilityScore == stabilityScorePrev)
                    {
                        cAliensThisGeneration = nResetSize;
                    }
                    else
                    {
                        cAliensThisGeneration = cAliens;
                    }

                    while (rgChildren.Count < cAliensThisGeneration && setChildren.Count < cCombinations)
                    {
                        DNA child = CreateAlien(iGeneration);
                        if (setChildren.ContainsKey(child))
                        {
                            continue;
                        }

                        setChildren.Add(child, true);
                        rgChildren.Add(child);
                    }

                    // fuzz each param individually
                    for (int iParam = 0; iParam < cParams; iParam++)
                    {
                        int cValues = _rgParameterDefinitions [iParam].CountValues;

                        for (int iFuzz = 0; iFuzz < 5; iFuzz++)
                        {
                            int [] rgParams = new int [cParams];
                            for (int iParamFuzz = 0; iParamFuzz < cParams; iParamFuzz++)
                            {
                                rgParams [iParamFuzz] = dnaBestSinceReset.GetParam(iParamFuzz);
                            }

                            rgParams [iParam] = MutateParam(_mutationStrength, cValues, rgParams [iParam]);

                            DNA child = new DNA(rgParams, dnaBestSinceReset.Generation + 1);
                            if (!setChildren.ContainsKey(child))
                            {
                                setChildren.Add(child, true);
                                rgChildren.Add(child);
                            }
                        }
                    }

                    while (rgChildren.Count < _nPopulationSize - cAliensThisGeneration && setChildren.Count < cCombinations)
                    {
                        if (UserAbort)
                        {
                            throw new AbortOptimizationException();
                        }

                        // find parents rendomly according to weighted fitness
                        double weightA  = _rand.NextDouble() * totalWeight;
                        int    iParentA = 0;
                        while (iParentA < rgParents.Count && weightA > rgParents [iParentA].Weight)
                        {
                            weightA -= rgParents [iParentA].Weight;
                            iParentA++;
                        }

                        double weightB  = _rand.NextDouble() * totalWeight;
                        int    iParentB = 0;
                        while (iParentB < rgParents.Count && weightB > rgParents [iParentB].Weight)
                        {
                            weightB -= rgParents [iParentB].Weight;
                            iParentB++;
                        }

                        // these are the parents:
                        DNA parentA = rgParents [iParentA];
                        DNA parentB = rgParents [iParentB];

                        // create a new set of genes
                        int [] rgParams = new int [cParams];
                        for (int iParam = 0; iParam < cParams; iParam++)
                        {
                            // Take an attribute from parents
                            DNA parent = (_rand.Next(100) < 50) ? parentA : parentB;
                            rgParams [iParam] = parent.GetParam(iParam);

                            // Should we mutate?
                            int cValues = _rgParameterDefinitions [iParam].CountValues;
                            if (cValues > 1 && _rand.NextDouble() < _mutationRate)
                            {
                                rgParams [iParam] = MutateParam(_mutationStrength, cValues, rgParams [iParam]);
                            }
                        }

                        // create the new child, and make sure it's unique
                        //int iGenerationChild = iGeneration;
                        //int iGenerationChild = 1 + Math.Min (parentA.Generation, parentB.Generation);
                        int iGenerationChild = (parentA.Generation + parentB.Generation) / 2;
                        DNA child            = new DNA(rgParams, iGenerationChild);
                        if (!setChildren.ContainsKey(child))
                        {
                            setChildren.Add(child, true);
                            rgChildren.Add(child);
                        }
                    }

                    stabilityScorePrev = stabilityScore;
                }

                DateTime timeEnd    = DateTime.Now;
                TimeSpan tsDuration = timeEnd - timeStart;

                Strategy.Print(string.Format(
                                   "{0}: PH Optimizer End @ {1}, duration: {2} ({3} per iteration)",
                                   Strategy.Instrument.FullName,
                                   timeEnd,
                                   tsDuration,
                                   TimeSpan.FromTicks(tsDuration.Ticks / iGeneration)
                                   )
                               );
            }
            catch (AbortOptimizationException)
            {
                Strategy.Print("Optimization Aborted...");
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e);
                Strategy.Print(e.ToString());
                //throw;
            }
            finally
            {
                if (dnaBestEver != null)
                {
                    Dump(dnaBestEver);
                }
            }

#if NT7
            WaitForIterationsCompleted(true);
#endif
        }