protected void signalPerformanceOptimization(TA.PriceVolumeSeries series, double[] data, int windowSize) { double stopLossFrom = 0.02; double stopLossTo = 0.04; double stopLossStep = 0.001; double buySignalFrom = 0.9;; double buySignalTo = 1.1; double sellSignalFrom = 0.9; double sellSignalTo = 1.1; double signalStep = 0.002; int maxDays = 1000; int daysFrom = 1; int daysTo = 10; int daysStep = 1; long loopsTotal = (long)(((buySignalTo - buySignalFrom) / signalStep) * ((sellSignalFrom - sellSignalTo) / signalStep) * ((stopLossTo - stopLossFrom) / stopLossStep) * (daysFrom - daysTo)); System.Collections.Generic.List <TradeSession> bestBlocks = new System.Collections.Generic.List <TradeSession>(40); double buySignal = buySignalFrom; while (buySignal < buySignalTo) { double sellSignal = sellSignalFrom; while (sellSignal < sellSignalTo) { double stopLoss = stopLossFrom; while (stopLoss < stopLossTo) { int days = daysFrom; while (days < daysTo) { signalPerformanceOptimization(series, data, windowSize, stopLoss, maxDays, sellSignal, buySignal, days, bestBlocks); loopsTotal--; if ((loopsTotal & 0xFFFF) == 0) { System.Console.Write("." + loopsTotal); } days = days + daysStep; } stopLoss += stopLossStep; } sellSignal += signalStep; } buySignal += signalStep; } TradeSession bs = findBest(bestBlocks); System.Console.WriteLine("pTotal=" + (int)(100 * bs.p) + ", days=" + bs.days + ", hits=" + bs.hits + ", maxDrawDown=" + (int)(100 * bs.maxDrawDown) + "" + ", trades=" + bs.trades.Count + ", stopLoss=" + bs.stopLoss + ", maxDays=" + bs.maxDays + ", sellSig=" + bs.sellSignal + ", buySig=" + bs.buySignal + ", wind=" + windowSize); signalPerformancePrintTrades(bs.trades); }
protected bool signalBuy(TA.PriceVolumeSeries series, int idx, double diff, int days) { bool res = false; if (idx >= days) { TA.Candle candleCur = (TA.Candle)series.Data[idx]; TA.Candle candlePrev = (TA.Candle)series.Data[idx - days]; res = (candleCur.high * diff > candlePrev.high); } return(res); }
protected void feedFisherTransformCallback(IWrite iWrite, string cmdName, object[] cmdArguments) { TA.PriceVolumeSeries series = FeedSeries; // first step is to calculate max, min, average etc. series.CalculateParams(); iWrite.WriteLine("Series: count=" + series.Data.Count + ", max=" + series.Max + ", min=" + series.Min + ", average=" + series.Average + ", sd=" + series.StdDeviation); double average, max, min; double[] data = TA.PriceVolumeSeries.GetClose(series); TA.PriceVolumeSeries.CalculateAverage(data, 0, data.Length, out average, out max, out min); iWrite.WriteLine("Data: count=" + data.Length + ",max=" + series.Max + ", min=" + series.Min + ", average=" + series.Average + ", sd=" + series.StdDeviation); int windowSize = 10; // now normalize the data data = TA.PriceVolumeSeries.Normalize(data, windowSize); TA.PriceVolumeSeries.CalculateAverage(data, 0, data.Length, out average, out max, out min); iWrite.WriteLine("Normalize(data): count=" + data.Length + ",max=" + max + ", min=" + min + ", average=" + average); TA.PriceVolumeSeries.EMA(data, 0.5); TA.PriceVolumeSeries.CalculateAverage(data, 0, data.Length, out average, out max, out min); iWrite.WriteLine("EMA(Normalize(data)): count=" + data.Length + ",max=" + max + ", min=" + min + ", average=" + average); TA.PriceVolumeSeries.Fisher(data); TA.PriceVolumeSeries.CalculateAverage(data, 0, data.Length, out average, out max, out min); iWrite.WriteLine("Fisher(EMA(Normalize(data))): count=" + data.Length + ",max=" + max + ", min=" + min + ", average=" + average); TA.PriceVolumeSeries.EMA(data, 0.5); TA.PriceVolumeSeries.CalculateAverage(data, 0, data.Length, out average, out max, out min); iWrite.WriteLine("EMA(Fisher(EMA(Normalize(data)))): count=" + data.Length + ",max=" + max + ", min=" + min + ", average=" + average); int i; for (i = 0; i < data.Length; i++) { // iWrite.WriteLine(""+data[i]); } signalPerformanceOptimization(series, data, windowSize); }
protected void _signalPerformanceOptimization(TA.PriceVolumeSeries series, double[] data, int windowSize) { double stopLossStep = 0.001; System.Collections.Generic.List <TradeSession> bestBlocks = new System.Collections.Generic.List <TradeSession>(40); double buySignal = -1.94; double sellSignal = 1.7; double stopLoss = 0.026; signalPerformanceOptimization(series, data, windowSize, stopLoss, 1000, 1.05, 0.9, 3, bestBlocks); TradeSession bs = findBest(bestBlocks); System.Console.WriteLine("pTotal=" + (int)(100 * bs.p) + ", days=" + bs.days + ", hits=" + bs.hits + ", maxDrawDown=" + (int)(100 * bs.maxDrawDown) + "" + ", trades=" + bs.trades.Count + ", stopLoss=" + bs.stopLoss + ", maxDays=" + bs.maxDays + ", sellSig=" + bs.sellSignal + ", buySig=" + bs.buySignal + ", wind=" + windowSize); signalPerformancePrintTrades(bs.trades); }
public bool GetSeries(DateTime start, DateTime end, Equity equity, DataFeed.DataType dataType, out TA.PriceVolumeSeries series) { string symbol = equity.Symbol; bool result = false; series = null; do { int size = (int)Math.Round((end - start).TotalDays); if (size <= 0) { break; } // preallocate some memory series = new TA.PriceVolumeSeries(size); string url; result = buildURL(symbol, start, end, dataType, out url); if (!result) { break; } Console.WriteLine("Get data from URL " + url + " between " + start + " and " + end); HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url); HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse(); Stream readStream = httpResponse.GetResponseStream(); result = fillDataArray(readStream, series); }while (false); return(result); }
protected void feedGetSeriesFromFileCallback(IWrite iWrite, string cmdName, object[] cmdArguments) { int argsNum = cmdArguments.Length; string[] args = (string[])cmdArguments; // string filename = "yahoo_feed_data.csv"; string filename = "yahoo_feed_data_5y.csv"; switch (argsNum) { case 2: filename = args[1]; break; default: break; } if (filename == null) { iWrite.WriteLine("Filename is not specified"); } else { IDataFeed dataFeed = new FeedYahoo(); bool result = dataFeed.GetSeries(filename, out FeedSeries); TA.PriceVolumeSeries series = FeedSeries; if (result) { iWrite.WriteLine("Parsed " + series.Data.Count + " entries"); } else { iWrite.WriteLine("Failed to read data from server"); } } }
public bool GetSeries(string fileName, out TA.PriceVolumeSeries series) { bool result = false; series = null; FileStream fileStream = null; do { try { fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); } catch (IOException e) { System.Console.WriteLine("Failed to open file " + fileName + " for reading"); System.Console.WriteLine(e.ToString()); break; } // preallocate some memory series = new TA.PriceVolumeSeries(50); result = fillDataArray(fileStream, series); if (!result) { System.Console.WriteLine("Failed to parse file " + fileName); } }while (false); if (fileStream != null) { fileStream.Close(); } return(result); }
static bool fillDataArray(Stream streamReader, TA.PriceVolumeSeries series) { bool result = false; byte[] buf = new byte[8192]; StringBuilder sb = new StringBuilder(); // read all data from the stream while (true) { int count = streamReader.Read(buf, 0, buf.Length); // nothing to read ? if (count == 0) { break; } // translate from bytes to ASCII text string tempString = Encoding.ASCII.GetString(buf, 0, count); // continue building the string sb.Append(tempString); } string str = sb.ToString(); // buffer sb contains lines separated by 0x0A (line feed) // skip first line int indexEnd; int indexStart = str.IndexOf((char)0x0A, 0); result = false; do { indexStart += 1; indexEnd = str.IndexOf((char)0x0A, indexStart); if (indexEnd <= 0) { System.Console.WriteLine("195:Failed to parse price data " + str); break; } result = ((indexEnd - indexStart) > 1); if (!result) { System.Console.WriteLine("202:Failed to parse price data " + str); break; } string data = str.Substring(indexStart, indexEnd - indexStart); TA.Candle candle; result = strToCandle(data, out candle); if (!result) { System.Console.WriteLine("211:Failed to parse candle data " + data + " indexStart=" + indexStart + " indexEnd=" + indexEnd); break; } series.Data.Insert(0, candle); indexStart = indexEnd; // end of data ? if (indexEnd >= (str.Length - 1)) { result = true; break; } }while (true); if (!result) { } return(result); }
public bool GetSeries(string fileName, out TA.PriceVolumeSeries series) { bool result = false; series = null; FileStream fileStream = null; do { try { fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read); } catch (IOException e) { System.Console.WriteLine("Failed to open file " + fileName + " for reading"); System.Console.WriteLine(e.ToString()); break; } // preallocate some memory series = new TA.PriceVolumeSeries(50); result = fillDataArray(fileStream, series); if (!result) { System.Console.WriteLine("Failed to parse file " + fileName); } } while (false); if (fileStream != null) { fileStream.Close(); } return result; }
public bool GetSeries(DateTime start, DateTime end, Equity equity, DataFeed.DataType dataType, out TA.PriceVolumeSeries series) { string symbol = equity.Symbol; bool result = false; series = null; do { int size = (int)Math.Round((end - start).TotalDays); if (size <= 0) { break; } // preallocate some memory series = new TA.PriceVolumeSeries(size); string url; result = buildURL(symbol, start, end, dataType, out url); if (!result) { break; } Console.WriteLine("Get data from URL " + url + " between " + start + " and " + end); HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(url); HttpWebResponse httpResponse = (HttpWebResponse)httpRequest.GetResponse(); Stream readStream = httpResponse.GetResponseStream(); result = fillDataArray(readStream, series); } while (false); return result; }
protected void signalPerformance(TA.PriceVolumeSeries series, double stopLoss, int maxDays, int idx, bool isBuy, double diffSell, double diffBuy, int sigDays, out Trade trade) { trade = new Trade(); trade.isBuy = isBuy; trade.idx = idx; int count = series.Data.Count; TA.Candle candle = (TA.Candle)series.Data[idx]; trade.candleEntry = candle; double entryPoint = candle.close; double close = entryPoint; double bestClose = close; bool isSell = !isBuy; int i; int days = 0; for (i = idx + 1; i < count; i++) { candle = (TA.Candle)series.Data[i]; days++; if (signalStop(isBuy, stopLoss, maxDays, entryPoint, close, candle.close, days, bestClose)) { break; } if (isBuy && signalSell(series, idx, diffSell, sigDays)) { break; } if (isSell && signalBuy(series, idx, diffSell, sigDays)) { break; } close = candle.close; if (isBuy) { if (bestClose < close) { bestClose = close; } } else { if (bestClose > close) { bestClose = close; } } } double delta; delta = entryPoint - candle.close; if (isBuy) { delta = -delta; } double p = delta / entryPoint; trade.candleExit = candle; trade.entry = entryPoint; trade.exit = candle.close; trade.p = p; trade.days = days; }
protected void signalPerformanceOptimization(TA.PriceVolumeSeries series, double[] data, int windowSize, double stopLoss, int maxDays, double diffSell, double diffBuy, int days, System.Collections.Generic.List <TradeSession> bestBlocks) { Trade trade; System.Collections.Generic.List <Trade> trades = new System.Collections.Generic.List <Trade>(10); int i = 0; while (i < (data.Length - 1)) { int idx = i + windowSize; TA.Candle candle = (TA.Candle)series.Data[idx]; double p; if (signalSell(series, idx, diffSell, days)) { signalPerformance(series, stopLoss, maxDays, idx, false, diffSell, diffBuy, days, out trade); if (trades.Count < 200) { trades.Add(trade); } else { break; } i += Math.Max(1, trade.days); // System.Console.Write("\tSell at "+idx+" entry="+trade.entry+" exit="+trade.exit+" "+candle.ToString()); // System.Console.WriteLine(" p="+trade.p+", days="+trade.days+", exit at "+(idx+trade.days)); } else if (signalBuy(series, idx, diffBuy, days)) // buy condition and trigger { signalPerformance(series, stopLoss, maxDays, idx, true, diffSell, diffBuy, days, out trade); if (trades.Count < 200) { trades.Add(trade); } else { break; } i += Math.Max(1, trade.days); // System.Console.Write("\tBuy at "+idx+" entry="+trade.entry+" exit="+trade.exit+" "+candle.ToString()); // System.Console.WriteLine(" p="+trade.p+", days="+trade.days+", exit at "+(idx+trade.days)); } else { i++; } } double pTotal; int daysTotal; int hits; double maxDrawDown; signalPerformanceGetTrades(trades, out daysTotal, out hits, out pTotal, out maxDrawDown); int misses = trades.Count - hits; if ((pTotal > 1.1) && (trades.Count > 5) && (bestBlocks.Count < 1000)) { TradeSession ts = new TradeSession(); ts.trades = trades; ts.maxDays = maxDays; ts.p = pTotal; ts.days = daysTotal; ts.hits = hits; ts.stopLoss = stopLoss; ts.sellSignal = diffSell; ts.buySignal = diffBuy; ts.maxDays = maxDays; ts.maxDrawDown = maxDrawDown; bestBlocks.Add(ts); System.Console.Write("+"); // System.Console.WriteLine("p="+pTotal); // signalPerformancePrintTrades(trades); } if ((pTotal > 2) && (trades.Count > 5) && (bestBlocks.Count > 1000)) { System.Console.Write("-"); } // System.Console.Write("1"); }
protected void feedGetSeriesCallback(IWrite iWrite, string cmdName, object[] cmdArguments, bool outputToFile) { int argsNum = cmdArguments.Length; string symbol = null; DateTime from = DateTime.Today - TimeSpan.FromDays(30); DateTime to = DateTime.Now; DateTime tmp; bool result = true; string[] args = (string[])cmdArguments; string filename = null; switch (argsNum) { case 1: result = false; break; case 2: if (outputToFile) { result = false; } else { symbol = args[1]; } break; case 3: if (outputToFile) { symbol = args[1]; filename = args[2]; } else { symbol = args[1]; result = DateTime.TryParse(args[2], out tmp); if (result) { from = tmp; } } break; case 4: if (outputToFile) { symbol = args[1]; filename = args[2]; result = DateTime.TryParse(args[3], out tmp); if (result) { from = tmp; } } else { symbol = args[1]; result = DateTime.TryParse(args[2], out tmp); if (result) { from = tmp; } result = DateTime.TryParse(args[3], out tmp); if (result) { to = tmp; } } break; case 5: default: if (outputToFile) { symbol = args[1]; filename = args[2]; result = DateTime.TryParse(args[3], out tmp); if (result) { from = tmp; } result = DateTime.TryParse(args[4], out tmp); if (result) { to = tmp; } } else { symbol = args[1]; result = DateTime.TryParse(args[2], out tmp); if (result) { from = tmp; } result = DateTime.TryParse(args[3], out tmp); if (result) { to = tmp; } } break; } if (!result) { iWrite.WriteLine("Please, specify symbol, from and to date"); return; } IDataFeed dataFeed = new FeedYahoo(); result = dataFeed.GetSeries(from, to, new Equity(symbol), DataFeed.DataType.Daily, out FeedSeries); TA.PriceVolumeSeries series = FeedSeries; if (result) { System.IO.FileStream fileStream = null; iWrite.WriteLine("Parsed " + series.Data.Count + " entries"); if (outputToFile) { bool shouldClose = false; try { fileStream = new System.IO.FileStream(filename, FileMode.CreateNew, FileAccess.Write, FileShare.Read); shouldClose = true; StreamWriter streamWriter = new StreamWriter(fileStream); streamWriter.Write(series.ToString(TA.PriceVolumeSeries.Format.Table)); streamWriter.Flush(); fileStream.Close(); shouldClose = false; } catch (IOException e) { iWrite.WriteLine(e.ToString()); } if (shouldClose) { fileStream.Close(); } } else { iWrite.WriteLine(series.ToString(TA.PriceVolumeSeries.Format.Table)); } } else { iWrite.WriteLine("Failed to read data from server"); } }