예제 #1
0
        protected override void CalcBar()
        {
            double Rating = m_RSI[0];        // Get RSI function value for the current bar.

            if (!Environment.IsRealTimeCalc) // There is no need to calculate on historical data, that is why backtesting is ignored
            {
                // As soon as backtesting is finished, the signal gets immediately calculated by the timer.
                // It is necessary to calculate RSI function value, which can be requested by MM-signal at any moment.
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(5));
                return;
            }

            StaretegyEvents cmd = StaretegyEvents.None;
            object          obj = MyPortfolioData["MM_Command"]; // Check, if there are any MM-signal events available

            if (!object.Equals(obj, null))
            {
                cmd = (StaretegyEvents)obj;
            }


            Output.WriteLine("\t\t{0}: Symbol: {1}, Command: {2}", DateTime.Now, Bars.Info.Name, cmd);

            switch (cmd)                                                       // Execute specific commands, depending on the event
            {
            case StaretegyEvents.GetFactor:                                    // If MM-signal requested rating coefficient from the signal, it will be sent.
                MyPortfolioData["RankingValue"] = Rating;                      // In this case it is RSI function value on the current bar.
                MyPortfolioData["MM_Command"]   = StaretegyEvents.DataWasSent; // And will inform that the data was sent.
                Output.WriteLine("\t\t{0}: Send Data for Symbol: {1}\t{2}", DateTime.Now, Bars.Info.Name, Rating);
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(5));       // Also, it is necessary to re-calculate, as the final instructions were not received yet.
                break;

            case StaretegyEvents.GenerateOrders_Long:                                                         // If MM-signal gives command to generate a long entry order
                buy_order.Send();                                                                             // the signal will execute it here.
                Output.WriteLine("\t\t{0}: Generate Buy. {1}", DateTime.Now, Bars.Info.Name);
                break;

            case StaretegyEvents.GenerateOrders_Short:                                                        // If MM-signal gives command to generate a short entry order
                sell_order.Send();                                                                            // the signal will execute it here.
                Output.WriteLine("\t\t{0}: Generate Short. {1}", DateTime.Now, Bars.Info.Name);
                break;

            case StaretegyEvents.None:
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(5));                                      // If there were no instructions from MM-signal, we will keep waiting for them.
                break;
            }

            if (Bars.Status == EBarState.Close)                                                               // During calculation at the bar close, global variables, used to exchange messages between the current signal and MM-signal
            {                                                                                                 // should be zeroed
                MyPortfolioData["RankingValue"] = 0;
                MyPortfolioData["MM_Command"]   = StaretegyEvents.None;
                Output.WriteLine("\t\tSeries {0} is Closed with Ranking Value: {1}. Status: {2}, cmd: {3}", Bars.Info.Name, Rating, Bars.Status, cmd);
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(5));                                      // And start the timer to wait for the new commands from MM-signal
            }
        }
예제 #2
0
        protected override void CalcBar()
        {
            if (!Bars.LastBarOnChart)
            {
                return;                                                                                    // Ignore BackTesting
            }
            TimeSpan currentTime     = DateTime.Now.TimeOfDay;                                             // Get the current time
            int      strategiesCount = PortfolioStrategies.Count;

            m_time = GetCloseTime() - TimeSpan.FromSeconds(30);                                           // and calculate the moment when the calculated coefficient will be requested from each trading strategy.
                                                                                                          // In this case - 30 seconds before the bar close
            #region Request Data
            if (Bars.Status == EBarState.Close)                                                           // When the bar closes, it is necessary to clear the collection of coefficients
            {                                                                                             // it will be a flag: if the collection is empty, then either the calculation has just started, or
                RankFromStrategies.Clear();                                                               // the new bar has appeared and we need to get new coefficients.
                return;                                                                                   // The request of new values of coefficients will be executed on the new bar already.
            }

            StaretegyEvents cmd = StaretegyEvents.None;
            if (currentTime >= m_time && RankFromStrategies.Count != strategiesCount)                     // If it is already necessary to request values from signals, we start the process of receiving values
            {
                for (int idx = 0; idx < strategiesCount; idx++)                                           // We address to each signal in cycle:
                {
                    PortfolioStrategies[idx].Status = "";
                    object obj = PortfolioStrategies[idx].PortfolioData["MM_Command"];

                    if (!object.Equals(obj, null))
                    {
                        cmd = (StaretegyEvents)obj;
                    }

                    if (cmd != StaretegyEvents.DataWasSent)                                               // if it did not yet send the data
                    {
                        PortfolioStrategies[idx].PortfolioData["MM_Command"] = StaretegyEvents.GetFactor; // we make a request
                        Output.WriteLine("{0} MMS: Request Factor", DateTime.Now);
                    }
                }
                RankFromStrategies.Clear();                                                              // Clear the collection from the old values
            }
            #endregion

            var inLongStrategies  = new List <int>();
            var inShortStrategies = new List <int>();

            #region Load Data
            if (RankFromStrategies.Count == 0)                                                           // The data should be received from all the strategies at the same time
            {
                for (int idx = 0; idx < strategiesCount; idx++)
                {
                    StaretegyEvents _flag = StaretegyEvents.None;
                    object          _o    = PortfolioStrategies[idx].PortfolioData["MM_Command"];
                    if (!object.Equals(_o, null))
                    {
                        _flag = (StaretegyEvents)_o;
                    }

                    if (_flag != StaretegyEvents.DataWasSent)                                           // if a strategy did not yet send its data
                    {
                        RankFromStrategies.Clear();                                                     // we will initiate receiving data until it is done
                        {
                            return;                                                                     // otherwise, the signal will not be able to correctly evaluate the market situation
                        }
                    }

                    double rankingValue = 0;
                    rankingValue = PortfolioStrategies[idx].PortfolioData["RankingValue"].safe_cast2double(); // The type of received values should be changed to double
                    PortfolioStrategies[idx].Status = String.Format("{0:0.00}", rankingValue);                // and output them into the table, to Custom Text column

                    Output.WriteLine("{1} MMS:  data received: {0}", PortfolioStrategies[idx].Signals[0].Bars.Info.Name, DateTime.Now);
                    RankFromStrategies.Add(idx, rankingValue);                                          // Put the received data into the collection
                    PortfolioStrategies[idx].PortfolioData["MM_Command"] = StaretegyEvents.None;        // Remove command for data request. It is not needed to execute it on the current bar.
                }

                RankFromStrategies = RankFromStrategies.OrderByDescending(elem => elem.Value).ToDictionary(x => x.Key, y => y.Value); // When values of all the coefficiens are received, sort out the collection in descending order
                                                                                                                                      // symbols with maximum coefficient value will be at the top
                                                                                                                                      // symbols with minimum values will be at the bottom
            }
            #endregion

            int inShortcnt = this.StrategiesInShort(ref inShortStrategies);           // Get the number of opened short positions
            int inLongtcnt = this.StrategiesInLong(ref inLongStrategies);             // Get the number of opened long positions

            TimeSpan dif = DateTime.Now - m_LastTraceTime;                            // Trace the intermediate values
            if (dif.Seconds > 1)
            {
                Output.WriteLine("{7} MMS:  {0} CalcBar. Bar Time: {1}, reqtime: {2}, strategiesToEnter.Count: {3}, strategiesCount: {4}, inShortcnt: {5}, inLongtcnt: {6}",
                                 currentTime, Bars.TimeValue, m_time, RankFromStrategies.Count, strategiesCount, inShortcnt, inLongtcnt, DateTime.Now);
                m_LastTraceTime = DateTime.Now;
            }


            if (RankFromStrategies.Count == strategiesCount)                                     // Make sure that all the coefficients were received and start sending commands to the signals
            {
                int CountNewPositionsBest  = MaxBest - inShortcnt;                               // Calculate how many additional short orders can be generated
                int CountNewPositionsWorst = MaxWorst - inLongtcnt;                              // and long orders

                for (int idx = 0; idx < Math.Min(CountNewPositionsBest, strategiesCount); idx++) // and select the best symbols in the cycle and send the command to generate the order
                {
                    if (idx >= RankFromStrategies.Count())
                    {
                        break;
                    }

                    int    key   = RankFromStrategies.Keys.ElementAt(idx);
                    double value = RankFromStrategies[key];

                    if (Environment.IsAutoTradingMode && Bars.LastBarOnChart)
                    {
                        Output.WriteLine(DateTime.Now.ToString() + " MMS:  " + currentTime + "; idx: " + key + "; Symbol To Enter: " + PortfolioStrategies[key].Signals[0].Bars.Info.Name + "; Rank: " + value);
                    }

                    if (value > 65)                                                                                  // ...if the coefficient values allow to do that
                    {
                        PortfolioStrategies[key].PortfolioData["MM_Command"] = StaretegyEvents.GenerateOrders_Short; // command to send short entry order is given to the specified strategy
                    }
                }

                for (int idx = strategiesCount - 1; idx > strategiesCount - Math.Min(CountNewPositionsWorst, strategiesCount) && idx > 0; idx--) // the same for the long position
                {                                                                                                                                // but coefficients are taken from the bottom of the list, that is, the worst
                    if (idx >= RankFromStrategies.Count() || idx < 0)
                    {
                        break;
                    }

                    int    key   = RankFromStrategies.Keys.ElementAt(idx);
                    double value = RankFromStrategies[key];

                    if (Environment.IsAutoTradingMode && Bars.LastBarOnChart)
                    {
                        Output.WriteLine(DateTime.Now.ToString() + " MMS:  " + currentTime + "; idx: " + key + "; Symbol To Enter: " + PortfolioStrategies[key].Signals[0].Bars.Info.Name + "; Rank: " + value);
                    }
                    if (value < 35)
                    {
                        PortfolioStrategies[key].PortfolioData["MM_Command"] = StaretegyEvents.GenerateOrders_Long;
                    }
                }
            }
        }