//Runs the backtest and displays the chart with buy/sell/exit icons. private string RunBacktest() { string ret = string.Empty; try { oScript.ClearRecords(); oBacktest.ClearRecords(); if (!VerifyForm()) { return(string.Empty); } if (!TestScripts()) { return(string.Empty); } if (m_ctlData == null) { return(string.Empty); } cmdBacktest.Text = "&Stop Backtest"; EnableControls(false); Periodicity periodicity; switch (cboPeriodicity.Text) { case "Minute": periodicity = Periodicity.Minutely; break; case "Hour": periodicity = Periodicity.Hourly; break; case "Day": periodicity = Periodicity.Daily; break; case "Week": periodicity = Periodicity.Weekly; break; default: periodicity = Periodicity.Minutely; break; } cmdBacktest.Enabled = false; Telerik.WinControls.UI.Docking.DockWindow activeDoc = frmMain2.GInstance.radDock2.DocumentManager.ActiveDocument; //Get the data selection M4Core.Entities.ChartSelection selection = new M4Core.Entities.ChartSelection { Periodicity = (M4Core.Entities.Periodicity)periodicity, Symbol = txtSymbol.Text, Interval = Convert.ToInt32(txtInterval.Text), Bars = Convert.ToInt32(txtBars.Text) }; m_ctlData.LoadRealTimeCtlPainelChartAsync2(selection, new Action <CtlPainelChart>(chart => { m_chart = chart; if (m_chart == null) { goto Quit; } DataManager.BarData[] bars = m_chart.GetDataFromChart(); if (bars.Length < 1) { goto Quit; } m_chart.Subscribers += 1; m_chart.RealTimeUpdates = false; //Get historic data cmdBacktest.Enabled = true; if (bars.Length < 3) { goto Quit; //Bad request } //Insert the data into all four instances of TradeScript oScript.ClearRecords(); oBacktest.ClearRecords(); DateTime td; double jdate; for (int n = 1; n < bars.Length - 1; n++) { td = bars[n].TradeDate; jdate = oScript.ToJulianDate(td.Year, td.Month, td.Day, td.Hour, td.Minute, td.Second, 0); oScript.AppendRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)bars[n].Volume); oBacktest.AppendRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)bars[n].Volume); } //TODO ret = oBacktest.Backtest(txtBuyScript, txtSellScript, txtExitLongScript, txtExitShortScript, 0.001); if (string.IsNullOrEmpty(ret)) { goto Quit; } string output = oScript.GetScriptOutput(txtBuyScript + " AND \r\n" + txtSellScript + " AND \r\n" + txtExitLongScript + " AND \r\n" + txtExitShortScript); if (string.IsNullOrEmpty(output)) { goto Quit; } int row; string[] cols; int col; string[] rows = output.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); string[] Header = SplitHeader(rows[0]); //StockChartX AxSTOCKCHARTXLib.AxStockChartX StockChartX1 = m_chart.StockChartX1; StockChartX1.RemoveAllSeries(); string symbol = selection.Symbol; StockChartX1.Symbol = symbol; StockChartX1.AddChartPanel(); StockChartX1.AddSeries(symbol + ".open", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.AddSeries(symbol + ".high", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.AddSeries(symbol + ".low", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.AddSeries(symbol + ".close", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.set_SeriesColor(symbol + ".close", ColorTranslator.ToOle(Color.Black)); //OLD BEHAVIOR: Add generic serie /* * for (col = 6; col < Header.Length; col++) * { * int panel = 0; * panel = StockChartX1.AddChartPanel(); * * StockChartX1.AddSeries(Header[col], STOCKCHARTXLib.SeriesType.stLineChart, panel); * * System.Drawing.Color color; * switch (col) * { * case 6: * color = System.Drawing.Color.Blue; * break; * case 7: * color = System.Drawing.Color.Red; * break; * case 8: * color = System.Drawing.Color.Green; * break; * case 9: * color = System.Drawing.Color.Orange; * break; * case 10: * color = System.Drawing.Color.Purple; * break; * default: * color = System.Drawing.Color.Blue; * break; * } * StockChartX1.set_SeriesColor(Header[col], System.Drawing.ColorTranslator.ToOle(color)); * * }*/ for (row = 1; row < rows.Length; row++) { cols = rows[row].Split(','); jdate = GetJDate(cols[0]); StockChartX1.AppendValue(symbol + ".open", jdate, Convert.ToDouble(cols[1], ciEnUs)); StockChartX1.AppendValue(symbol + ".high", jdate, Convert.ToDouble(cols[2], ciEnUs)); StockChartX1.AppendValue(symbol + ".low", jdate, Convert.ToDouble(cols[3], ciEnUs)); StockChartX1.AppendValue(symbol + ".close", jdate, Convert.ToDouble(cols[4], ciEnUs)); //OLD BEHAVIOR: Add generic serie /* * for (col = 6; col < cols.Length; col++) * { * double value = Convert.ToDouble(cols[col], ciEnUs); * if (value == 0 && row < rows.Length * 0.2) * { * value = (double)STOCKCHARTXLib.DataType.dtNullValue; * } * * StockChartX1.AppendValue(Header[col], jdate, value); * } */ } //NEW BEHAVIOR: Add known indicators (it doesnt work with others indicators!) for (col = 6; col < Header.Length; col++) { //Try to add until available key isnt found: bool errorKey = true; int indicatorKey = 1; while (errorKey) { try { System.Drawing.Color color; switch (col) { case 6: color = System.Drawing.Color.Blue; break; case 7: color = System.Drawing.Color.Red; break; case 8: color = System.Drawing.Color.Green; break; case 9: color = System.Drawing.Color.Orange; break; case 10: color = System.Drawing.Color.Purple; break; default: color = System.Drawing.Color.Blue; break; } //param[0 1 2 3] // MM(1,14,CLOSE,0) if (Header[col].Contains("MM(")) { string indScript = Header[col].Replace("MM(", ""); indScript = indScript.Replace(")", ""); string[] param = indScript.Split(new char[] { ',' }); string source = symbol + ".Close"; switch (param[2]) { case "OPEN": source = symbol + ".Open"; break; case "HIGH": source = symbol + ".High"; break; case "LOW": source = symbol + ".Low"; break; default: source = symbol + ".Close"; break; } StockChartX1.AddIndicatorGenericMovingAverage("MA" + indicatorKey, 0, source, int.Parse(param[1]), int.Parse(param[3]), int.Parse(param[0]), 0, color.R, color.G, color.B, 0, 1); } errorKey = false; } catch (Exception ex) { if (ex.Message == "Key not unique") { errorKey = true; indicatorKey++; } else { Telerik.WinControls.RadMessageBox.Show(ex.Message); } } } } StockChartX1.Update(); Quit: if (m_chart != null) { m_chart.Show(); } cmdBacktest.Text = "&Back Test"; EnableControls(true); if (m_chart != null) { m_chart.Subscribers -= 1; } })); //Ensure the chart is new while (ret == string.Empty) { Application.DoEvents(); } } catch (Exception ex) { } return(ret); }
//Runs the backtest and displays the chart with buy/sell/exit icons. private string RunBacktest() { string ret = string.Empty; _oScript.ClearRecords(); _oBacktest.ClearRecords(); if (!VerifyForm()) { return(string.Empty); } if (!TestScripts()) { return(string.Empty); } if (_mCtlData == null) { return(string.Empty); } cmdBacktest.Text = "&Stop Backtest"; cmdBacktest.Border.BaseColor = Color.Red; EnableControls(false); cmdBacktest.Border.Update(); Periodicity periodicity; switch (cboPeriodicity.Text) { case "Day": periodicity = Periodicity.Daily; break; case "Hour": periodicity = Periodicity.Hourly; break; case "Minute": periodicity = Periodicity.Minutely; break; case "Week": periodicity = Periodicity.Weekly; break; case "Month": periodicity = Periodicity.Month; break; case "Year": periodicity = Periodicity.Year; break; default: periodicity = Periodicity.Minutely; break; } cmdBacktest.Enabled = false; //Get the data selection ChartSelection selection = new ChartSelection { Periodicity = periodicity, Symbol = txtSymbol.Text, Interval = Convert.ToInt32(txtInterval.Text), Bars = Convert.ToInt32(txtBars.Text), Source = "PLENA" }; _ctlPainelChart = _mCtlData.GetCtlPainelChart(selection, true); //Ensure the chart is new if (_ctlPainelChart == null) { goto Quit; } DataManager.BarData[] bars = _ctlPainelChart.GetDataFromChart(); if (bars.Length < 1) { goto Quit; } _ctlPainelChart.Subscribers += 1; _ctlPainelChart.RealTimeUpdates = false; //Get historic data cmdBacktest.Enabled = true; if (bars.Length < 3) { goto Quit; //Bad request } //Insert the data into all four instances of TradeScript _oScript.ClearRecords(); _oBacktest.ClearRecords(); DateTime td; double jdate; for (int n = 1; n < bars.Length - 1; n++) { td = bars[n].TradeDate; jdate = _oScript.ToJulianDate(td.Year, td.Month, td.Day, td.Hour, td.Minute, td.Second, 0); _oScript.AppendRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)bars[n].Volume); _oBacktest.AppendRecord(jdate, bars[n].OpenPrice, bars[n].HighPrice, bars[n].LowPrice, bars[n].ClosePrice, (int)bars[n].Volume); } //TODO ret = _oBacktest.Backtest(txtBuyScript.Text, txtSellScript.Text, txtExitLongScript.Text, txtExitShortScript.Text, 0.001); if (string.IsNullOrEmpty(ret)) { goto Quit; } string output = _oScript.GetScriptOutput(txtBuyScript.Text + " AND \r\n" + txtSellScript.Text + " AND \r\n" + txtExitLongScript.Text + " AND \r\n" + txtExitShortScript.Text); if (string.IsNullOrEmpty(output)) { goto Quit; } int row; string[] cols; int col; string[] rows = output.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); string[] header = SplitHeader(rows[0]); //StockChartX AxSTOCKCHARTXLib.AxStockChartX StockChartX1 = _ctlPainelChart.StockChartX1; StockChartX1.RemoveAllSeries(); string symbol = selection.Symbol; StockChartX1.Symbol = symbol; StockChartX1.AddChartPanel(); StockChartX1.AddSeries(symbol + ".open", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.AddSeries(symbol + ".high", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.AddSeries(symbol + ".low", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.AddSeries(symbol + ".close", STOCKCHARTXLib.SeriesType.stCandleChart, 0); StockChartX1.set_SeriesColor(symbol + ".close", ColorTranslator.ToOle(Color.Black)); bool hasVolume = bars[0].Volume != -987654321; if (hasVolume) { StockChartX1.AddChartPanel(); StockChartX1.AddSeries(symbol + ".volume", STOCKCHARTXLib.SeriesType.stVolumeChart, 1); StockChartX1.set_SeriesColor(symbol + ".volume", ColorTranslator.ToOle(Color.Blue)); StockChartX1.set_SeriesWeight(symbol + ".volume", 3); StockChartX1.VolumePostfixLetter = "M"; //Google trades in millions } for (col = 6; col < header.Length; col++) { int panel = StockChartX1.AddChartPanel(); StockChartX1.AddSeries(header[col], STOCKCHARTXLib.SeriesType.stLineChart, panel); Color color; switch (col) { case 6: color = Color.Blue; break; case 7: color = Color.Red; break; case 8: color = Color.Green; break; case 9: color = Color.Orange; break; case 10: color = Color.Purple; break; default: color = Color.Blue; break; } StockChartX1.set_SeriesColor(header[col], ColorTranslator.ToOle(color)); } for (row = 1; row < rows.Length; row++) { cols = rows[row].Split(','); jdate = GetJDate(cols[0]); StockChartX1.AppendValue(symbol + ".open", jdate, Convert.ToDouble(cols[1], _ciEnUs)); StockChartX1.AppendValue(symbol + ".high", jdate, Convert.ToDouble(cols[2], _ciEnUs)); StockChartX1.AppendValue(symbol + ".low", jdate, Convert.ToDouble(cols[3], _ciEnUs)); StockChartX1.AppendValue(symbol + ".close", jdate, Convert.ToDouble(cols[4], _ciEnUs)); if (hasVolume) { StockChartX1.AppendValue(symbol + ".volume", jdate, Convert.ToDouble(cols[5], _ciEnUs) / 1000000); } for (col = 6; col < cols.Length; col++) { double value = Convert.ToDouble(cols[col], _ciEnUs); if (value == 0 && row < rows.Length * 0.2) { value = (double)STOCKCHARTXLib.DataType.dtNullValue; } StockChartX1.AppendValue(header[col], jdate, value); } } StockChartX1.Update(); Quit: if (_ctlPainelChart != null) { _ctlPainelChart.Show(); } cmdBacktest.Text = "&Back Test"; cmdBacktest.Border.BaseColor = Color.Lime; EnableControls(true); cmdBacktest.Border.Update(); if (_ctlPainelChart != null) { _ctlPainelChart.Subscribers -= 1; } return(ret); }