예제 #1
0
        public void Process(Price[] shareData, SimpleSearchSettings settings)
        {
            this.Results = new List<List<Result>>();
            int count = shareData.Count();
            Price? lastSellPoint = null;

            List<Result> currentRun = new List<Result>();
            int buyPointIndex = 0;
            decimal? phase2Slope = null, phase2Intercept = null;
            while (buyPointIndex < count)
            {
                if (currentRun.Count < settings.numerOfRepeats)
                {
                    var buyPoint = shareData[buyPointIndex];
                    var sellPoint = buyPoint;

                    bool found = false;
                    for (int sellPointIndex = buyPointIndex + 1; sellPointIndex < count && (sellPoint.date - buyPoint.date).TotalDays < settings.riseSearchPeriodInDays; sellPointIndex++)
                    {
                        sellPoint = shareData[sellPointIndex];

                        if (((sellPoint.closePrice - buyPoint.closePrice) * 100 / buyPoint.closePrice) > settings.requiredChangeRate)
                        {
                            currentRun.Add(new Result() { buy = buyPoint, sell = sellPoint, state = ResultState.OK });
                            lastSellPoint = sellPoint;
                            buyPointIndex = sellPointIndex + 1;
                            phase2Slope = phase2Intercept = null;
                            found = true;
                            break;
                        }
                    }

                    bool withinFallBuyPeriod = lastSellPoint == null || (buyPoint.date - lastSellPoint.Value.date).TotalDays < settings.fallSearchPeriodInDays;

                    if (!found && !withinFallBuyPeriod)
                    {
                        currentRun.Clear();
                        lastSellPoint = null;
                    }
                }
                else
                {
                    bool foundBuyPoint = false, foundSellPoint = false;
                    do
                    {
                        double[] x = currentRun.Select(c => (double)c.buy.date.Ticks).ToArray();
                        double[] y = currentRun.Select(c => (double)c.buy.closePrice).ToArray();
                        double slope, intercept;
                        MathExtension.GenerateLinearBestFit(x, y, out slope, out intercept);
                        phase2Slope = (decimal)slope; phase2Intercept = (decimal)intercept;

                        foundBuyPoint = foundSellPoint = false;
                        Price buyPoint, sellPoint;
                        do
                        {
                            buyPoint = shareData[buyPointIndex++];
                            foundBuyPoint = (buyPoint.closePrice <= (phase2Slope * buyPoint.date.Ticks + phase2Intercept));
                        } while (buyPointIndex < count-1 && !foundBuyPoint && (buyPoint.date - lastSellPoint.Value.date).TotalDays < settings.fallSearchPeriodInDays);

                        sellPoint = buyPoint;
                        if (foundBuyPoint)
                        {
                            for (int sellPointIndex = buyPointIndex; sellPointIndex < count && !foundSellPoint && (sellPoint.date - buyPoint.date).TotalDays < settings.riseSearchPeriodInDays; sellPointIndex++)
                            {
                                sellPoint = shareData[sellPointIndex];

                                if (((sellPoint.closePrice - buyPoint.closePrice) * 100 / buyPoint.closePrice) > settings.requiredChangeRate)
                                {
                                    foundSellPoint = true;
                                    buyPointIndex = sellPointIndex;
                                    break;
                                }
                            }

                            currentRun.Add(new Result() { buy = buyPoint, sell = sellPoint, state = foundSellPoint ? ResultState.OK : ResultState.FailedFindingSellPoint });
                        }

                    } while (foundSellPoint);

                    if (currentRun.Count >= settings.numerOfRepeats)
                        Results.Add(currentRun);
                    currentRun = new List<Result>();
                }

                buyPointIndex++;
            }
        }
예제 #2
0
        public static IEnumerable<Price> Get(string symbol)
        {
            List<Price> result = new List<Price>();
            DateTime now = DateTime.Now;
            string url = string.Format("http://real-chart.finance.yahoo.com/table.csv?s={0}&d={2}&e={1}&f={3}&g=d&a=1&b=1&c=1900&ignore=.csv", symbol, now.Day, now.Month - 1, now.Year);
            string file = string.Empty;

            using (WebClient webClient = new WebClient())
            {
                file = webClient.DownloadString(url);
            }

            var rows = file.Split('\n');
            if (rows.Length == 0)
                return new Price[0];

            var fields = rows[0].Split(',');
            if (fields.Length != 7)
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) download from Yahoo does not have the correct number of columns currently has {1} expected 7", symbol, fields.Length));

            if (fields[0] != "Date")
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 0 column name has {1} expected Date", symbol, fields[0]));
            if (fields[1] != "Open")
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 1 column name has {1} expected Open", symbol, fields[0]));
            if (fields[2] != "High")
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 2 column name has {1} expected High", symbol, fields[0]));
            if (fields[3] != "Low")
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 3 column name has {1} expected Low", symbol, fields[0]));
            if (fields[4] != "Close")
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 4 column name has {1} expected Close", symbol, fields[0]));
            if (fields[5] != "Volume")
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 5 column name has {1} expected Volume", symbol, fields[0]));
            if (!fields[6].StartsWith("Adj Close"))
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 6 column name has {1} expected Adj Close", symbol, fields[0]));

            foreach (var row in rows.Skip(1))
            {
                try
                {
                    fields = row.Split(',');

                    var price = new Price()
                    {
                        date = DateTime.ParseExact(fields[0], "yyyy-MM-dd", CultureInfo.CurrentCulture),
                        openPrice = decimal.Parse(fields[1]),
                        highPrice = decimal.Parse(fields[2]),
                        lowPrice = decimal.Parse(fields[3]),
                        closePrice = decimal.Parse(fields[4]),
                        //volume = long.Parse(fields[5]),
                        //adjClose = decimal.Parse(fields[6])
                    };

                    result.Add(price);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("HistoricalPricwReader.Get failed reading line {0} error is {1}", row, ex.Message);
                }
            }

            result.Reverse();

            return result;
        }
예제 #3
0
        public static IEnumerable <Price> Get(string symbol)
        {
            List <Price> result = new List <Price>();
            DateTime     now    = DateTime.Now;
            string       url    = string.Format("http://real-chart.finance.yahoo.com/table.csv?s={0}&d={2}&e={1}&f={3}&g=d&a=1&b=1&c=1900&ignore=.csv", symbol, now.Day, now.Month - 1, now.Year);
            string       file   = string.Empty;

            using (WebClient webClient = new WebClient())
            {
                file = webClient.DownloadString(url);
            }

            var rows = file.Split('\n');

            if (rows.Length == 0)
            {
                return(new Price[0]);
            }

            var fields = rows[0].Split(',');

            if (fields.Length != 7)
            {
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) download from Yahoo does not have the correct number of columns currently has {1} expected 7", symbol, fields.Length));
            }

            if (fields[0] != "Date")
            {
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 0 column name has {1} expected Date", symbol, fields[0]));
            }
            if (fields[1] != "Open")
            {
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 1 column name has {1} expected Open", symbol, fields[0]));
            }
            if (fields[2] != "High")
            {
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 2 column name has {1} expected High", symbol, fields[0]));
            }
            if (fields[3] != "Low")
            {
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 3 column name has {1} expected Low", symbol, fields[0]));
            }
            if (fields[4] != "Close")
            {
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 4 column name has {1} expected Close", symbol, fields[0]));
            }
            if (fields[5] != "Volume")
            {
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 5 column name has {1} expected Volume", symbol, fields[0]));
            }
            if (!fields[6].StartsWith("Adj Close"))
            {
                throw new ApplicationException(string.Format("CSV file (for symbol {0}) has invalid 6 column name has {1} expected Adj Close", symbol, fields[0]));
            }

            foreach (var row in rows.Skip(1))
            {
                try
                {
                    fields = row.Split(',');

                    var price = new Price()
                    {
                        date       = DateTime.ParseExact(fields[0], "yyyy-MM-dd", CultureInfo.CurrentCulture),
                        openPrice  = decimal.Parse(fields[1]),
                        highPrice  = decimal.Parse(fields[2]),
                        lowPrice   = decimal.Parse(fields[3]),
                        closePrice = decimal.Parse(fields[4]),
                        //volume = long.Parse(fields[5]),
                        //adjClose = decimal.Parse(fields[6])
                    };

                    result.Add(price);
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine("HistoricalPricwReader.Get failed reading line {0} error is {1}", row, ex.Message);
                }
            }

            result.Reverse();

            return(result);
        }