Ejemplo n.º 1
0
        internal void ToSerie(StockSerie stockSerie, StockSerie referenceSerie = null)
        {
            float open = 0.0f;
             float high = 0.0f;
             float low = 0.0f;
             float close = 0.0f;
             int volume = 1;
             float cash = TotalDeposit;

             Dictionary<string, PositionValues> stockPositionDico = new Dictionary<string, PositionValues>();

             // Statistics
             int nbTrades = 0;
             int nbWinTrades = 0;
             float maxDrawdown = float.MaxValue;
             float maxGain = float.MinValue;
             float maxLoss = float.MinValue;

             if (referenceSerie == null)
             {
            referenceSerie = StockDictionary.StockDictionarySingleton["CAC40"];
             }
             referenceSerie.Initialise();

             foreach (DateTime date in referenceSerie.GetValues(StockSerie.StockBarDuration.Daily).Where(d => d.DATE.Year > 2014).Select(v => v.DATE.Date))
             {
            // Calculate open value

            // Retrieve orders for this date/time
            var orderList = this.OrderList.FindAll(order => order.ExecutionDate.Date == date).OrderBy(o => o.ID);

            // Manage new orders
            foreach (StockOrder stockOrder in orderList)
            {
               int numberOfShare = stockOrder.IsShortOrder ? -stockOrder.Number : stockOrder.Number;
               if (stockOrder.IsBuyOrder()) // Buy position
               {
                  cash -= stockOrder.TotalCost;
                  if (stockPositionDico.ContainsKey(stockOrder.StockName))
                  {
                     stockPositionDico[stockOrder.StockName].Position += numberOfShare;
                     stockPositionDico[stockOrder.StockName].OpenValue =
                        (stockPositionDico[stockOrder.StockName].Position *
                         stockPositionDico[stockOrder.StockName].OpenValue + numberOfShare * stockOrder.Value) /
                        (stockPositionDico[stockOrder.StockName].Position + numberOfShare);
                  }
                  else
                  {
                     if (stockDictionary.ContainsKey(stockOrder.StockName) &&
                         stockDictionary[stockOrder.StockName].Initialise())
                     {
                        stockPositionDico.Add(stockOrder.StockName,
                           new PositionValues(numberOfShare, stockOrder.Value,
                              stockDictionary[stockOrder.StockName].GetValues(StockSerie.StockBarDuration.Daily)));
                     }
                     else
                     {
                        StockLog.Write("Initialisation failed: " + stockOrder.StockName);
                        stockPositionDico.Add(stockOrder.StockName,
                           new PositionValues(numberOfShare, stockOrder.Value, null));
                     }
                  }
               }
               else // Closing Position
               {
                  if (stockPositionDico.ContainsKey(stockOrder.StockName))
                  {
                     cash += stockOrder.TotalCost;
                     PositionValues position = stockPositionDico[stockOrder.StockName];
                     if (position.Position == numberOfShare)
                     {
                        maxDrawdown = Math.Min(maxDrawdown, position.MaxDrawdown);
                        stockPositionDico.Remove(stockOrder.StockName);
                        nbTrades++;
                     }
                     else
                     {
                        position.Position -= numberOfShare;
                     }
                     if (stockOrder.IsShortOrder)
                     {
                        if (position.OpenValue > stockOrder.Value)
                        {
                           nbWinTrades++;
                           maxGain = Math.Max(maxGain, (position.OpenValue - stockOrder.Value) / position.OpenValue);
                        }
                        else
                        {
                           maxLoss = Math.Max(maxLoss, -(position.OpenValue - stockOrder.Value) / position.OpenValue);
                        }
                     }
                     else
                     {
                        if (position.OpenValue < stockOrder.Value)
                        {
                           nbWinTrades++;
                           maxGain = Math.Max(maxGain, -(position.OpenValue - stockOrder.Value) / position.OpenValue);
                        }
                        else
                        {
                           maxLoss = Math.Max(maxLoss, (position.OpenValue - stockOrder.Value) / position.OpenValue);
                        }
                     }
                  }
                  else
                  {
                     // Open short position
                     cash += stockOrder.TotalCost;

                     if (stockDictionary.ContainsKey(stockOrder.StockName) &&
                         stockDictionary[stockOrder.StockName].Initialise())
                     {
                        stockPositionDico.Add(stockOrder.StockName,
                           new PositionValues(-numberOfShare, stockOrder.Value,
                              stockDictionary[stockOrder.StockName].GetValues(StockSerie.StockBarDuration.Daily)));
                     }
                     else
                     {
                        StockLog.Write("Initialisation failed: " + stockOrder.StockName);
                        stockPositionDico.Add(stockOrder.StockName,
                           new PositionValues(-numberOfShare, stockOrder.Value, null));
                     }

                     //throw new System.Exception("Sell order found on non bought stock " + stockOrder.StockName + " in " + this.Name);
                     // @@@@ Need to have proper error manegement otherwise the applications crashes.
                     //return referenceSerie;
                  }
               }
            }

            // Calculate new value after taking into account the orders.
            low = cash;
            high = cash;
            close = cash;
            open = cash;
            if (stockPositionDico.Count != 0)
            {
               foreach (PositionValues position in stockPositionDico.Values)
               {
                  StockDailyValue currentValue = position.AtDate(date);
                  if (currentValue == null)
                  {
                     // Position on stock not in dico
                     if (position.Position > 0)
                     {
                        close += position.OpenValue * position.Position;
                        open += position.OpenValue * position.Position;
                        low += position.OpenValue * position.Position;
                        high += position.OpenValue * position.Position;
                     }
                  }
                  else
                  {
                     // Position on stock  in dico
                     close += currentValue.CLOSE * position.Position;
                     open += currentValue.OPEN * position.Position;
                     if (position.Position > 0)
                     {
                        position.MaxValue = Math.Max(position.MaxValue, currentValue.HIGH);
                        position.MinValue = Math.Min(position.MinValue, currentValue.LOW);

                        low += currentValue.LOW * position.Position;
                        high += currentValue.HIGH * position.Position;
                     }
                     else
                     {
                        // We are facing a short order, everything is reversed
                        low += currentValue.HIGH * position.Position;
                        high += currentValue.LOW * position.Position;

                        position.MaxValue = Math.Max(position.MaxValue, currentValue.LOW);
                        position.MinValue = Math.Min(position.MinValue, currentValue.HIGH);
                     }
                  }
               }
            }

            StockDailyValue dailyValue = new StockDailyValue(stockSerie.StockName, open, high, low, close, volume, date);
            stockSerie.Add(date, dailyValue);
            dailyValue.Serie = stockSerie;
             }

             StockLog.Write("Statistics for " + stockSerie.StockName);
             StockLog.Write("NbTrades: " + nbTrades);
             StockLog.Write("Win %: " + ((float)nbWinTrades / (float)nbTrades).ToString("P2"));
             StockLog.Write("MaxDrowdown: " + maxDrawdown.ToString("P2"));
             StockLog.Write("MaxGain: " + maxGain.ToString("P2"));
             StockLog.Write("MaxLoss: " + maxLoss.ToString("P2"));
        }
        public override bool LoadIntradayDurationArchiveData(string rootFolder, StockSerie serie, StockSerie.StockBarDuration duration)
        {
            StockLog.Write("LoadIntradayDurationArchiveData Name:" + serie.StockName + " duration:" + duration);
             string durationFileName = rootFolder + ARCHIVE_FOLDER + "\\" + duration + "\\" + serie.ShortName.Replace(':', '_') + "_" + serie.StockName + "_" + serie.StockGroup.ToString() + ".txt";
             if (File.Exists(durationFileName))
             {
            var values = serie.GetValues(duration);
            if (values == null)
               StockLog.Write("LoadIntradayDurationArchiveData Cache File Found, current size is: 0");
            else  StockLog.Write("LoadIntradayDurationArchiveData Cache File Found, current size is: " + values.Count);
            serie.ReadFromCSVFile(durationFileName, duration);

            StockLog.Write("LoadIntradayDurationArchiveData New serie size is: " + serie.GetValues(duration).Count);
            if (serie.GetValues(duration).Count > 0)
            {
               StockLog.Write("LoadIntradayDurationArchiveData First bar: " +
                              serie.GetValues(duration).First().ToString());
               StockLog.Write("LoadIntradayDurationArchiveData Last bar: " + serie.GetValues(duration).Last().ToString());
            }
            else
            {
               return false;
            }
             }
             else
             {
            return false;
             }
             return true;
        }