public List<TradeRule> GenerateTradeRuleForGroups(int size)
        {
            var dt = DateTime.Now;

            int totalCount = 0;
            List<RandomPicker>  groupItemPicker = new List<RandomPicker>();
            foreach (List<string> group in this.Groups)
            {
                groupItemPicker.Add(new RandomPicker(0, group.Count));
                totalCount = totalCount + group.Count;
            }
            RandomPicker groupPicker = new RandomPicker(0, totalCount);

            List<TradeRule> tradeRules = new List<TradeRule>();

            int groupIndexer;
            int selectedGroupIndex;
            int indicator1Index;
            int indicator2Index;
            List<string> selectedGroup;
            TradeRule tradeRule;
            for (int i = 0; i < size; i++ )
            {
                groupIndexer = groupPicker.GetNextPick();
                selectedGroupIndex = GetGroupIndex(groupIndexer);
                selectedGroup = this.Groups[selectedGroupIndex];

                indicator1Index = groupItemPicker[selectedGroupIndex].GetNextPick();
                indicator2Index = groupItemPicker[selectedGroupIndex].GetNextPick();

                tradeRule = TradeRuleFactory.GenerateTradeRule(selectedGroup[indicator1Index], GetJoinType(), selectedGroup[indicator2Index]);

                tradeRules.Add(tradeRule);
            }

            var time = DateTime.Now.Subtract(dt).TotalMilliseconds;

            return tradeRules;
        }
        private List<Chromosome> Breed(List<Chromosome> chromosomes)
        {
            if (chromosomes == null || !chromosomes.Any())
                return chromosomes;

            // Breed
            List<Chromosome> returnList = new List<Chromosome>();

            RandomPicker rp = new RandomPicker(0, chromosomes.Count);
            double mutationRate = this.MutationRate;
            int[] mutationIndex = Enumerable.Range(0, (int)this.MutationRate * chromosomes.Count).Select(val => rp.GetNextPick()).OrderBy(val => val).ToArray();
            List<Chromosome> mutationChromosomes = Enumerable.Range(0, mutationIndex.Count()).Select(idx => chromosomes[mutationIndex[idx]]).ToList();
            List<Chromosome> crossoverChromosomes = chromosomes.Where(chr => !mutationChromosomes.Contains(chr)).ToList();

            Chromosome chromosome1;
            Chromosome chromosome2;
            for (int i = 0; i < mutationChromosomes.Count; i++)
            {
                chromosome1 = mutationChromosomes[i];
                if (chromosome1.BuyCondition.TradeRules.Count > 1 && chromosome1.SellCondition.TradeRules.Count > 1 && i % 2 == 0)
                {
                    returnList.Add(Chromosome.TweakJoinConditions(chromosome1));
                }
                else
                {
                    returnList.Add(Chromosome.TweakRules(chromosome1, this.BuyRules, this.SellRules));
                }
            }

            rp = new RandomPicker(0, crossoverChromosomes.Count);
            for (int i = 0; i < crossoverChromosomes.Count; i = i + 2)
            {
                chromosome1 = crossoverChromosomes[rp.GetNextPick()];
                chromosome2 = crossoverChromosomes[rp.GetNextPick()];

                returnList = returnList.Concat(Chromosome.SwapChromosomes(chromosome1, chromosome2)).ToList();
            }

            return returnList;
        }
        public List<Chromosome> GeneratePopulation()
        {
            List<Chromosome> tradeChromosomes = new List<Chromosome>();

            RandomPicker buyPicker = new RandomPicker(0, this.BuyRules.Count);
            RandomPicker sellPicker = new RandomPicker(0, this.SellRules.Count);
            Chromosome chromosome;
            for (int popSize = 0; popSize < this.PopulationSize; popSize++)
            {
                if (!Proceed)
                    return tradeChromosomes;

                chromosome = new Chromosome();
                chromosome.BuyCondition = new TradeCondition();
                chromosome.SellCondition = new TradeCondition();

                int loopBuySize = rand.Next(this.MinSize, this.MaxSize + 1);
                int loopSellSize = rand.Next(this.MinSize, this.MaxSize + 1);
                int loopSize = Math.Max(loopBuySize, loopSellSize);
                for (int i = 0; i < loopSize; i++)
                {
                    if (i < loopBuySize)
                    {
                        chromosome.BuyCondition.TradeRules.Add(this.BuyRules[buyPicker.GetNextPick()]);
                        chromosome.BuyCondition.RuleJoinTypes.Add(GetRuleJoinType(i == loopBuySize - 1));
                    }

                    if (i < loopSellSize)
                    {
                        chromosome.SellCondition.TradeRules.Add(this.SellRules[sellPicker.GetNextPick()]);
                        chromosome.SellCondition.RuleJoinTypes.Add(GetRuleJoinType(i == loopSellSize - 1));
                    }
                }
                tradeChromosomes.Add(chromosome);
            }

            return tradeChromosomes;
        }