예제 #1
0
 /// <summary>
 /// Initializes a new instance of the TradeHelper class.
 /// </summary>
 /// <param name="tradeSystem">The trading system to use.</param>
 public TradeHelper(TradeSystem tradeSystem)
 {
     this.tradeSystem = tradeSystem;
     this.Capital = tradeSystem.FinancialSettings.InitialCapital;
     this.currentTrade = new Trade(this.tradeSystem.FinancialSettings.MaxDrawdown, this.tradeSystem.FinancialSettings.DollarsPerPoint, this.tradeSystem.FinancialSettings.RoundTripCommission, this.Capital);
 }
예제 #2
0
        public Trades EvalTrades(TradeSystem tradeSystem, TradeCondition buyCondition, TradeCondition sellCondition, double stopOutValue, bool log = false)
        {
            object[] logRowData = null;
            if (log)
            {
                int logIndex = -1;
                this.LogTables = new DataTable("LogTable");
                this.LogTables.Columns.Add("Date");
                this.LogTables.Columns.Add("Time");
                this.LogTables.Columns.Add("Open");
                this.LogTables.Columns.Add("High");
                this.LogTables.Columns.Add("Low");
                this.LogTables.Columns.Add("Close");
                this.LogTables.Columns.Add("Volume");
                this.LogTables.Columns.Add("StopOut");
                this.LogTables.Columns.Add("Buy Signal");
                this.LogTables.Columns.Add("Sell Signal");

                TradeRule tr;
                for (int i = 0; i < buyCondition.TradeRules.Count; i++)
                {
                    tr = buyCondition.TradeRules[i];
                    logIndex++;
                    this.LogTables.Columns.Add(string.Format("{0} {1} {2} -BR{3}", tr.IndicatorName1, tr.CompareType.ToString(), tr.IndicatorName2, logIndex));
                    this.LogTables.Columns.Add(string.Format("Result -BR{0}", logIndex));
                    this.LogTables.Columns.Add(string.Format("JoinType -BR{0}", logIndex));
                }

                logIndex = 0;
                for (int i = 0; i < sellCondition.TradeRules.Count; i++)
                {
                    tr = sellCondition.TradeRules[i];
                    logIndex++;
                    this.LogTables.Columns.Add(string.Format("{0} {1} {2} -SR{3}", tr.IndicatorName1, tr.CompareType.ToString(), tr.IndicatorName2, logIndex));
                    this.LogTables.Columns.Add(string.Format("Result -SR{0}", logIndex));
                    this.LogTables.Columns.Add(string.Format("JoinType -SR{0}", logIndex));
                }

                logRowData = GetEmptyArray(this.LogTables.Columns.Count);
            }

            bool stopout = stopOutValue != double.MaxValue;
            DateTime startDate = tradeSystem.StartDate;
            DateTime endDate = tradeSystem.EndDate;

            TradeType? tradeType = null;
            if(tradeSystem.Longs && ! tradeSystem.Shorts)
            {
                tradeType = TradeType.longTrade;
            }
            else if (!tradeSystem.Longs && tradeSystem.Shorts)
            {
                tradeType = TradeType.shortTrade;
            }

            this.Winners = 0;
            this.Losers = 0;
            this.StopOuts = 0;
            this.Trades = new Trades();
            this.Capital = tradeSystem.FinancialSettings.InitialCapital;

            bool[] buys = GetValues(buyCondition);
            bool[] sells = GetValues(sellCondition);
            List<int> endOfDaysIndexes = this.IndicatorLibraryAdapter.EndOfDayIndex;

            bool buySignal;
            bool sellSignal;
            bool longEntered = false;
            bool shortEntered = false;

            double maxDrawDown = tradeSystem.FinancialSettings.MaxDrawdown;
            double dollarsPerPoint = tradeSystem.FinancialSettings.DollarsPerPoint;
            double roundTripCommision = tradeSystem.FinancialSettings.RoundTripCommission;
            double currentCapital = tradeSystem.FinancialSettings.InitialCapital;
            double equityPerContract = tradeSystem.FinancialSettings.EquityPerContract;
            int maxContracts = tradeSystem.FinancialSettings.MaxContracts;

            int counter = 0;
            Trade trade = null;
            StockPoint stockPoint = null;
            DateTime currentDateTime;

            #region Enter/Exit and Log Trade Func

            int stopOutCounter = 0;
            Action EnterLog = () =>
            {
                StockPoint point = StockPoints[counter];
                logRowData[0] = point.Date;
                logRowData[1] = point.Time;
                logRowData[2] = point.Open.ToString("0.00");
                logRowData[3] = point.High.ToString("0.00");
                logRowData[4] = point.Low.ToString("0.00");
                logRowData[5] = point.Close.ToString("0.00");
                logRowData[6] = point.Volume.ToString();
                if (stopOutCounter != this.StopOuts)
                {
                    stopOutCounter = this.StopOuts;
                    this.LogTables.Rows[this.LogTables.Rows.Count - 1][7] = "1";
                }
                logRowData[7] = "0";
                if (endOfDaysIndexes.Contains(counter))
                {
                    logRowData[8] = "end of day";
                    logRowData[9] = "end of day";
                }
                else
                {
                    logRowData[8] = buys[counter] ? "1" : "0";
                    logRowData[9] = sells[counter] ? "1" : "0";
                }
                int logIndex = 9;

                TradeRule tr;
                double[] evalData;
                for (int i = 0; i < buyCondition.TradeRules.Count; i++)
                {
                    tr = buyCondition.TradeRules[i];
                    evalData = this.Data[tr.Name];
                    logRowData[++logIndex] = string.Format("{0} {1} {2}",
                                                            this.IndicatorLibraryAdapter.Data[tr.IndicatorName1][counter].ToString(),
                                                            tr.CompareType.ToString(),
                                                            tr.IndicatorName2.Contains("#")
                                                                ? tr.IndicatorName2.Replace("#", "")
                                                                : Convert.ToString(this.IndicatorLibraryAdapter.Data[tr.IndicatorName2][counter]));
                    logRowData[++logIndex] = evalData[counter].ToString("0");
                    logRowData[++logIndex] = buyCondition.RuleJoinTypes[i].ToString();
                }

                for (int i = 0; i < sellCondition.TradeRules.Count; i++)
                {
                    tr = sellCondition.TradeRules[i];
                    evalData = this.Data[tr.Name];
                    logRowData[++logIndex] = string.Format("{0} {1} {2}",
                                                            this.IndicatorLibraryAdapter.Data[tr.IndicatorName1][counter],
                                                            tr.CompareType.ToString(),
                                                            tr.IndicatorName2.Contains("#")
                                                                ? tr.IndicatorName2.Replace("#", "")
                                                                : Convert.ToString(this.IndicatorLibraryAdapter.Data[tr.IndicatorName2][counter]));
                    logRowData[++logIndex] = evalData[counter].ToString("0");
                    logRowData[++logIndex] = sellCondition.RuleJoinTypes[i].ToString();
                }

                this.LogTables.Rows.Add(logRowData);

                logRowData = GetEmptyArray(this.LogTables.Columns.Count);
            };

            // returns if entry point is the last point
            Action<TradeType> EnterTrade = (entryTradeType) =>
            {
                longEntered = entryTradeType == TradeType.longTrade;
                shortEntered = entryTradeType == TradeType.shortTrade;

                trade = new Trade(maxDrawDown, dollarsPerPoint, roundTripCommision, currentCapital);
                trade.Enter(this.StockPoints[counter + 1], entryTradeType, Math.Min((int)(currentCapital / equityPerContract), maxContracts));
            };

            // returns if the needs to exit
            Func<bool, int, int, bool> ExitTrade = (isStopped, indexIncreamentvalue, decrement) =>
            {
                trade.Exit(this.StockPoints[counter + indexIncreamentvalue], decrement, isStopped);

                currentCapital = Math.Round(Math.Max(currentCapital + trade.Profit, 0D), 2);
                if (trade.Profit > 0)
                {
                    this.Winners++;
                }
                else if (trade.Profit < 0)
                {
                    this.Losers++;
                }
                if(isStopped)
                {
                    this.StopOuts++;
                }
                Trades.Add(trade);

                longEntered = false;
                shortEntered = false;

                return currentCapital < equityPerContract;
            };

            #endregion Enter/Exit Trade Func

            for (counter = 0; counter < this.StockPoints.Count(); counter++)
            {
                if (this.Cancelled)
                {
                    this.Cancelled = false;
                    return Trades;
                }

                buySignal = buys[counter];
                sellSignal = sells[counter];
                stockPoint = StockPoints[counter];

                currentDateTime = stockPoint.PointDateTime;

                if (currentDateTime >= endDate)
                {
                    if (longEntered || shortEntered)
                    {
                        ExitTrade(false, 0, 0);
                    }
                    break;
                }

                if (currentDateTime < startDate)
                {
                    continue;
                }

                if (log) EnterLog();

                if (currentDateTime.AddMinutes(30).Hour >= 9)
                {
                    if (longEntered || shortEntered)
                    {
                        // exit end of day, if long/short entered or beyond specified date
                        if (endOfDaysIndexes.Contains(counter))
                        {
                            if (ExitTrade(false, 0, 0)) break;
                        }
                        // exit trade logic
                        else if ((longEntered && sellSignal) || (shortEntered && buySignal))
                        {
                            if (ExitTrade(false, 1, 5)) break;
                        }
                        //stopout
                        else if (stopout && ((trade.TradeType == TradeType.longTrade && trade.EntryPrice - stockPoint.Low >= stopOutValue) ||
                                            (trade.TradeType == TradeType.shortTrade && stockPoint.High - trade.EntryPrice >= stopOutValue)))
                        {
                            if (ExitTrade(true, 1, 5)) break;
                        }
                        continue;
                    }

                    // enter trade logic
                    if (!(longEntered || shortEntered || endOfDaysIndexes.Contains(counter)))
                    {
                        if (buySignal && (tradeType == null || tradeType.Value == TradeType.longTrade))
                        {
                            EnterTrade(TradeType.longTrade);
                        }
                        else if (sellSignal && (tradeType == null || tradeType.Value == TradeType.shortTrade))
                        {
                            EnterTrade(TradeType.shortTrade);
                        }
                    }
                }
            }

            return Trades;
        }