コード例 #1
0
        //        private double GetMarketPosition()
        //        {
        //            return this.Environment.IsAutoTradingMode ? StrategyInfo.MarketPositionAtBrokerForTheStrategy : StrategyInfo.MarketPosition;
        //        }

        //        private bool GetSignalDown(double crtdr, double rsi, Trend trend)
        //        {
        //            if(rsi >= RsiUpMinimumForShort && trend == Trend.Down)
        //            {
        //                if(crtdr * 100 + rsi >= 200 - ShortLimitDown) return true;
        //            }
        //
        //            return false;
        //        }

        protected override void OnOrderRejected(EOrderAction action, OrderCategory category, int quantity, double stopPrice, double limitPrice)
        {
            LogAndMail("Order rejected: {0} {1} ({2} @ {3}/{4}).", action, quantity, category, stopPrice, limitPrice);
            DumpFileLog();
            DumpMailLog();
            ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(recalcFrequency));                                            // If there were no instructions from MM-signal, we will keep waiting for them.
        }
コード例 #2
0
        protected override void CalcBar()
        {
            m_last_tick_val = Bars.TicksValue;
            m_last_cb       = Bars.CurrentBar;

            if (!Bars.LastBarOnChart)
            {
                var p_levels = (Bars.HighValue - Bars.LowValue) / m_price_step + 1;
                for (var i = 0; i < p_levels; i++)
                {
                    add_volume(Bars.LowValue + i * m_price_step, Bars.TicksValue / p_levels);
                }
                return;
            }

            ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(UpdateSpeedsec));

            double _inc_volume;

            if (Bars.CurrentBar > m_last_cb)
            {
                _inc_volume = Bars.TicksValue - m_last_tick_val;
            }
            else
            {
                _inc_volume = Bars.TicksValue;
            }

            add_volume(Bars.CloseValue, _inc_volume);
        }
コード例 #3
0
 protected override void CalcBar()
 {
     if (Bars.LastBarOnChart)
     {
         ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(0.5));
     }
 }
コード例 #4
0
        protected override void CalcBar()
        {
            barNumber.Value = BarsOfData(BasedOnData).CurrentBar;

            if (barNumber.Value > barNumber[1])
            {
                double rank = Formula(this);
                MyPortfolioData["RankStrategyR"] = rank;

                if (TraceOutput)
                {
                    Output.WriteLine("CurrentBar = {0}. Put MyIndicator value = {1} for symbol {2}.", Bars.CurrentBar, rank, Bars.Info.Name);
                }
            }

            buy.Send();
            sellshort.Send();

            // money management
            double moneyCostForInvestPerCntrct = this.CalcMoneyForEntryPerCntrct(Bars.CloseValue, Portfolio.MarginPerContract) +
                                                 this.CalcMoneyForEntryPerCntrct(Bars.CloseValue, Portfolio.MaxPotentialLossPerContract);

            if (moneyCostForInvestPerCntrct < 0)
            {
                ExecControl.Abort("Error! Price = {0}, PMargin = {1}, PMaxPLoss = {2}", Bars.CloseValue, Portfolio.MarginPerContract, Portfolio.MaxPotentialLossPerContract);
            }

            MyPortfolioData[PortfolioHelpFunctions.MoneyCostForInvestPerCtrct] = this.FromSymbolToPortfolioCurrency(moneyCostForInvestPerCntrct);
        }
コード例 #5
0
        protected override void CalcBar()
        {
            if (!Bars.LastBarOnChart)
            {
                return;
            }

            ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(updatespeed_seconds));

            if (Bars.DOM.Connected)
            {
                m_value11 = 0;

                foreach (var domPrice in Bars.DOM.Ask)
                {
                    m_value11 = Math.Max(m_value11, domPrice.Size);
                }
                foreach (var domPrice in Bars.DOM.Bid)
                {
                    m_value11 = Math.Max(m_value11, domPrice.Size);
                }

                m_draw_dom_level1.Call();
                m_draw_dom_level2.Call();

                Plot1.Set("OK", Color.White);
            }
            else
            {
                Plot1.Set("Level2 data is not avaliable", Color.Red);
            }
        }
コード例 #6
0
        protected override void CalcBar()
        {
            if (Environment.ApplicationCode != EApplicationCode.Portfolio)
            {
                ExecControl.Abort("Signal can be applied in portfolio only.");
            }

            MyPortfolioData["RotationalValue"] = myFormula(myLength, 0);

            buy.Send();
            sell.Send();

            // money management
            double entryprice = this.EntryPrice() == 0 ? Bars.CloseValue : this.EntryPrice();
            double moneyCostForInvestPerCntrct =
                this.CalcMoneyForEntryPerCntrct(entryprice, Portfolio.MarginPerContract) +
                this.CalcMoneyForEntryPerCntrct(entryprice, Portfolio.MaxPotentialLossPerContract);

            if (moneyCostForInvestPerCntrct < 0)
            {
                ExecControl.Abort("Error! Price = {0}, PMargin = {1}, PMaxPLoss = {2}", entryprice, Portfolio.MarginPerContract, Portfolio.MaxPotentialLossPerContract);
            }

            MyPortfolioData[PortfolioHelpFunctions.MoneyCostForInvestPerCtrct] = this.FromSymbolToPortfolioCurrency(moneyCostForInvestPerCntrct);

            // exits
            CurSpecOrdersMode = ESpecOrdersMode.PerPosition;
            GenerateStopLoss(StopLossPcntsOfPortfolio * .01 * this.PortfolioEquity());
            GenerateProfitTarget(ProfitTargetPcntsOfPortfolio * .01 * this.PortfolioEquity());
        }
コード例 #7
0
        protected override void StartCalc()
        {
            if (Environment.ApplicationCode != EApplicationCode.Portfolio)
            {
                ExecControl.Abort("Signal can be applied in portfolio only.");
            }

            m_KRatio.NumberOfDataBarsInCalendarYear = 252;
        }
コード例 #8
0
 protected override void CalcBar()
 {
     // we only deal with the last bar
     if (!Bars.LastBarOnChart)
     {
         return;
     }
     ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(UpdateSpeedSecs));
 }
コード例 #9
0
        protected override void CalcBar()
        {
            Ratio.Value = Bars.CloseValue / BarsOfData(2).CloseValue;
            if (Bars.CurrentBar < Length)
            {
                return;
            }
            double contracts = this.PortfolioEquity() * PercentEquity / 100;

            if (Bars.CurrentBar > 1)
            {
                if (PublicFunctions.DoubleLess(m_expAvgRatioVal + m_stdDevRatioVal, Ratio.Value))
                {
                    if (!PublicFunctions.DoubleEquals(m_cur_pos, -1))
                    {
                        m_cur_pos = -1;
                        m_short.Send((int)contracts);
                    }
                }
                else
                if (PublicFunctions.DoubleGreater(m_expAvgRatioVal - m_stdDevRatioVal, Ratio.Value))
                {
                    if (!PublicFunctions.DoubleEquals(m_cur_pos, 1))
                    {
                        m_cur_pos = 1;
                        m_long.Send((int)contracts);
                    }
                }
                else
                {
                    m_cur_pos = 0;
                    m_lx.Send();
                    m_sx.Send();
                }
            }

            m_expAvgRatioVal = m_expAvgRatio.Value;
            m_stdDevRatioVal = Ratio.StandardDeviationCustom(Length, 1);

            if (Environment.ApplicationCode == EApplicationCode.Portfolio)
            {
                int slaveIdx = this.GetFirstStrategyIndexBySymbolName(BarsOfData(2).Info.Name);
                if (slaveIdx < 0)
                {
                    ExecControl.Abort(@"specified slave trader on instrument ""{0}"" not found", BarsOfData(2).Info.Name);
                }

                double money = Math.Abs(m_cur_pos * contracts) * Bars.CloseValue * Bars.Info.BigPointValue;

                if (PublicFunctions.DoubleGreater(money, 0))
                {
                    money = this.FromSymbolToPortfolioCurrency(money);
                }

                PortfolioStrategies[slaveIdx].PortfolioData[MasterMoney] = -m_cur_pos * money;
            }
        }
コード例 #10
0
        private void _new_track(object sender, EventArgs e)
        {
            var _tsi = (TrackBar)sender;

            if (Length != _tsi.Value)
            {
                Length = _tsi.Value;
                ExecControl.Recalculate();
            }
        }
コード例 #11
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
            }
        }
コード例 #12
0
        protected override void StartCalc()
        {
            triggerTime = TimeSpan.Parse(TriggerTime);

            if (Environment.ApplicationCode != EApplicationCode.Portfolio)
            {
                ExecControl.Abort("Signal can be applied in portfolio only.");
            }

            m_KRatio.NumberOfDataBarsInCalendarYear = 1; //252;
        }
コード例 #13
0
 protected override void StartCalc()
 {
     if (Environment.ApplicationCode != EApplicationCode.Portfolio)
     {
         ExecControl.Abort("Portfolio Rank Money Management Signal can be applied for MCPortfolio application only.");
     }
     if (PortfolioStrategies.Count < BuyBestX + SellWorstY)
     {
         ExecControl.Abort("Portfolio Rank Monem Management Signal, please check inputs, BuyBestX + SellWorstY should be less or equal to tradeable Instruments number");
     }
 }
コード例 #14
0
        protected override void StartCalc()
        {
            // In this method it is specified that the signal is calculated in Portfolio Trader.
            if (Environment.ApplicationCode != EApplicationCode.Portfolio)
            {
                ExecControl.Abort("The signal can be used in MultiCharts Portfolio Trader only.");
            }

            // and initialize the function
            m_RSI.price  = Bars.Close;
            m_RSI.length = RSI_Length;
        }
コード例 #15
0
        private void button1_Click(object sender, EventArgs e)
        {
            var _tbi     = (ToolStripButton)sender;
            var MyDialog = new ColorDialog {
                Color = m_plot_color
            };

            if (MyDialog.ShowDialog() == DialogResult.OK)
            {
                m_plot_color = MyDialog.Color;
                set_color_tsi(_tbi, MyDialog.Color);
                ExecControl.Recalculate();
            }
        }
コード例 #16
0
        protected override void OnBrokerStategyOrderFilled(bool isBuy, int quantity, double avgFillPrice)
        {
            double pAndL           = double.NaN;
            double pAndLPercentage = double.NaN;

            if (StrategyInfo.AvgEntryPriceAtBroker != 0)
            {
                pAndL           = quantity * (avgFillPrice - StrategyInfo.AvgEntryPriceAtBroker);
                pAndLPercentage = avgFillPrice / StrategyInfo.AvgEntryPriceAtBroker * 100 - 100;
            }
            LogAndMail("Order filled: {0} {1} @ avg. {2} (==> {3}). MarketPositionAtBroker={4}, AvgEntryPriceAtBroker={5}", isBuy ? "BUY" : "SELL", quantity, avgFillPrice, isBuy ? "Investing " + quantity * avgFillPrice : ("P/L " + pAndL + " (" + pAndLPercentage + "%)" + (pAndL > 0 ? " - yeah, baby!" : " - ouch!")), StrategyInfo.MarketPositionAtBroker, StrategyInfo.AvgEntryPriceAtBroker);
            DumpFileLog();
            DumpMailLog();
            ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(recalcFrequency));                                            // If there were no instructions from MM-signal, we will keep waiting for them.
        }
コード例 #17
0
        protected override void StartCalc()
        {
            if (Environment.ApplicationCode != EApplicationCode.Portfolio)                                  // Verification: the signal is only for the Portfolio Trader
            {
                ExecControl.Abort("The signal can be used in MultiCharts Portfolio Trader only.");
            }

            if (PortfolioStrategies.Count < MaxBest + MaxWorst)                                             // Verification: sum of the inputs should be not more than the total number of the traded symbols
            {
                throw new Exception("Portfolio RSIRankEx_MM Signal, please check inputs, MaxBest + MaxWorst should be less or equal to the number of tradeable instruments");
            }

            if (Bars.Request.TimeZone != RequestTimeZone.Local)
            {
                throw new Exception("The signal can be used only with Local time zone set.");               // Verification: only Local time zone
            }
        }
コード例 #18
0
        protected override void StartCalc()
        {
            CommonPortfolioData["RankStrategyApplied"] = "true";

            if (!IsExist(BasedOnData))
            {
                ExecControl.Abort("Portfolio Rank Signal Base needs datastream {0}." + BasedOnData);
            }
            if (Environment.ApplicationCode != EApplicationCode.Portfolio)
            {
                ExecControl.Abort("Portfolio Rank Signal Base can be applied for MCPortfolio application only.");
            }

            if (TraceOutput)
            {
                Output.Clear();
            }
        }
コード例 #19
0
        protected override void OnRecalcLastBarAfterEvent()
        {
            if (Bars.DOM.Connected)
            {
                var _changed = false;
                lock (this){
                    var _old_ask = Asks;
                    var _old_bid = Bids;

                    Asks = Bars.DOM.Ask;
                    Bids = Bars.DOM.Bid;

                    _changed = !(equal(_old_ask, Asks) && equal(_old_bid, Bids));
                }

                if (_changed)
                {
                    ChartCustomDraw.ReDraw();
                }
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(UpdateSpeedsec));
            }
        }
コード例 #20
0
        // Drawing is triggered here on a timer rather than in
        // CalcBar() because the bid and ask can change without CalcBar()
        // being called.
        protected override void OnRecalcLastBarAfterEvent()
        {
            if (Bars.DOM.Connected)
            {
                var _changed = false;
                // confusing logic; necessary because Bids/Asks will be null
                // on the first pass through.
                DOMPrice _old_ask  = new DOMPrice(double.NaN, double.NaN);
                DOMPrice _old_bid  = new DOMPrice(double.NaN, double.NaN);
                double   _old_last = double.NaN;
                lock (this){
                    if (null == Asks)
                    {
                        _changed = true;
                    }
                    else
                    {
                        _old_ask  = Asks[0];
                        _old_bid  = Bids[0];
                        _old_last = LastPrice;
                    }
                    Asks      = Bars.DOM.Ask;
                    Bids      = Bars.DOM.Bid;
                    LastPrice = Bars.Close[0];
                    _changed  = _changed || !((_old_ask == Asks[0]) &&
                                              (_old_bid == Bids[0]) &&
                                              (_old_last == LastPrice));
                }
                _changed = _changed || !(LastPrice == Bars.Close[0]);

                if (_changed)
                {
                    ChartCustomDraw.ReDraw();
                }
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(UpdateSpeedSecs));
            }
        }
コード例 #21
0
 protected override void OnRecalcLastBarAfterEvent()
 {
     TradeManager.ProcessEvents();
     ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(0.5));
 }
コード例 #22
0
        protected override void CalcBar()
        {
            if (Environment.ApplicationCode != EApplicationCode.Portfolio)
            {
                ExecControl.Abort("Signal can be applied (as money management) in portfolio only.");
            }
            if (PortfolioStrategies.Count < BuyBestX + SellWorstY)
            {
                ExecControl.Abort(
                    "Portfolio has no enough instruments: instruments number = {0}; BuyBestX = {1}; SellWorstY = {2}",
                    PortfolioStrategies.Count, BuyBestX, SellWorstY);
            }

            this.StrategiesDenyEntriesAll();

            bestStrategies.Clear();
            worstStrategies.Clear();

            for (int idx = 0; idx < PortfolioStrategies.Count; idx++)
            {
                double value = PortfolioStrategies[idx].PortfolioData["RotationalValue"].safe_cast2double();
                bestStrategies.Add(idx, value);
                worstStrategies.Add(idx, value);
                if (TraceOutput)
                {
                    Output.WriteLine("{0}. For {1} strategy value = {2}", Bars.CurrentBar, idx, value);
                }
            }

            bestStrategies  = bestStrategies.OrderByDescending(elem => elem.Value).ToDictionary(x => x.Key, y => y.Value);
            worstStrategies = worstStrategies.OrderBy(elem => elem.Value).ToDictionary(x => x.Key, y => y.Value);

            if (TraceOutput)
            {
                foreach (var bestElem in bestStrategies)
                {
                    Output.WriteLine("{0}. Best = {1}:{2}.", Bars.CurrentBar, bestElem.Key, bestElem.Value);
                }
            }

            var inLongStrategies = new List <int>();

            this.StrategiesInLong(ref inLongStrategies);

            for (int idx = 0; idx < BuyBestX; idx++)
            {
                if (!inLongStrategies.Contains(bestStrategies.Keys.ElementAt(idx)))
                {
                    PortfolioStrategies[bestStrategies.Keys.ElementAt(idx)].AllowEntriesLong = true;
                }
            }

            var inShortStrategies = new List <int>();

            this.StrategiesInShort(ref inShortStrategies);

            for (int idx = 0; idx < SellWorstY; idx++)
            {
                if (!inShortStrategies.Contains(worstStrategies.Keys.ElementAt(idx)))
                {
                    PortfolioStrategies[worstStrategies.Keys.ElementAt(idx)].AllowEntriesShort = true;
                }
            }

            // money management
            if (UsePortfolioMoneyPcnt)
            {
                for (int idx = 0; idx < BuyBestX; idx++)
                {
                    PortfolioStrategies[bestStrategies.Keys.ElementAt(idx)].EntryContracts =
                        this.CalcContractsForEntry(PortfolioMoneyPcntForEntry, bestStrategies.Keys.ElementAt(idx));
                }

                for (int idx = 0; idx < SellWorstY; idx++)
                {
                    PortfolioStrategies[worstStrategies.Keys.ElementAt(idx)].EntryContracts =
                        this.CalcContractsForEntry(PortfolioMoneyPcntForEntry, worstStrategies.Keys.ElementAt(idx));
                }
            }
        }
コード例 #23
0
        protected override void CalcBar()
        {
            CurSpecOrdersMode = ESpecOrdersMode.PerPosition;

            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 the CRTDR and other values which can be requested by MM-signal at any moment.
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(recalcFrequency));
                return;
            }

            // This method will be called over and over again because of the RecalcLastBarAfter setting
            // Since we do not want to get the same logs all the time we have a throttling in place
            // which will allow only certain calls to really log their output.
            // Depending on the time of the day we log more of less often.
            UpdateLogThrottling();

            var high  = Bars.HighValue;
            var low   = Bars.LowValue;
            var close = Bars.CloseValue;

            var crtdr = CRTDRIndicatorMath.CalcNextValue(high, low, close);

            var xAverageLongValue  = xAverageLong.Value;
            var xAverageShortValue = xAverageShort.Value;

            var trend = GetTrend(close, xAverageLongValue, xAverageShortValue);

            var rsiDown = cutlersRSIIndicatorMathDown.Value;
            var rsiFlat = cutlersRSIIndicatorMathFlat.Value;
            var rsiUp   = cutlersRSIIndicatorMathUp.Value;

            var rsi = trend == Trend.Down ? rsiDown : (trend == Trend.Up ? rsiUp : rsiFlat);

            MyPortfolioData[PortfolioDataKeys.IWantToBuy]  = false;
            MyPortfolioData[PortfolioDataKeys.IWantToSell] = false;
            MyPortfolioData[PortfolioDataKeys.CRTDR]       = crtdr;

            LogThrottled("Reason: {0}, Status: {1}, Open: {2}, High: {3}, Low: {4}, Close: {5}, RSI: {6}, CRTDR: {7}, xAvgLong: {8}, xAvgShort: {9}", Environment.CalcReason, Bars.Status, Bars.OpenValue, Bars.HighValue, Bars.LowValue, Bars.CloseValue, rsi, crtdr, xAverageLongValue, xAverageShortValue);

            if (StrategyInfo.MarketPosition == 0)
            {
                if (GetSignalUp(crtdr, rsi, trend))
                {
                    //var numLots = Convert.ToInt32((InitialCapital + (doReinvestment ? Portfolio.NetProfit : 0.0)) / Bars.CloseValue);
                    MyPortfolioData[PortfolioDataKeys.IWantToBuy] = true;
                    LogThrottled("Signal says: We would like to buy @ {0}$", Bars.CloseValue);
                }
                //                else if (GetSignalDown(crtdr, rsi, trend))
                //                {
                //                       Output.WriteLine("SHORT on {0}, high {1} low {2} close {3} rsi {4} crtdr {5} xAverageLong {6} xAverageShort {7}", Bars.TimeValue, high, low, close, rsi, crtdr, xAverageLongValue, xAverageShortValue);
                //                    MyPortfolioData[PortfolioHelpFunctions.PotentialEntryPrice] = -Bars.CloseValue;
                //                    sellShortOrder.Send(Convert.ToInt32((InitialCapital + (doReinvestment ? Portfolio.NetProfit : 0.0)) / 10.0 / Bars.CloseValue));
                //                }
                //                else
                //                {
                //                       Log("---  FLAT - NOP ---");
                //                }
            }
            else if (StrategyInfo.MarketPosition > 0)
            {
                // WE ARE LONG
                //var barsSinceEntry = Bars.CurrentBar - CurrentPosition.OpenTrades[0].EntryOrder.BarNumber;
                // BarsSinceEntry() doesn't work upon the restart of a trading session in which case BarsSinceEntry() will be zero no matter when the deals were actually opened
                var barsSinceEntry = Math.Min(1, this.BarsSinceEntry());
                var openProfit     = CurrentPosition.OpenProfit;
                var signalUp       = GetSignalUp(crtdr, rsi, trend);
                var rsiSellLevel   = GetRsiSellLevel(trend);
                LogThrottled("Should we sell? Bars since entry: {0}, open profit: {1}, signal up: {2}, rsi: {3}, rsiSellLevel: {4}", barsSinceEntry, openProfit, signalUp, rsi, rsiSellLevel);

                // close non-profitable positions straight away because we have picked a loser and need to free up money for new deals
                if (openProfit < 0)
                {
                    LogThrottled("Loser cut! Assumed loss: {0}$", CurrentPosition.OpenProfit);
                    MyPortfolioData[PortfolioDataKeys.IWantToSell] = true;
                }
                else if (barsSinceEntry > 2 && !signalUp)
                {
                    LogThrottled("SELL! Bars since entry > 2 and no up signal. Assuming to cash in ~{0}$", CurrentPosition.OpenProfit);
                    MyPortfolioData[PortfolioDataKeys.IWantToSell] = true;
                }
                else if (rsi > rsiSellLevel)
                {
                    LogThrottled("SELL! RSI condition satisfied, we take the profit (~{0}$) and run!", CurrentPosition.OpenProfit);
                    MyPortfolioData[PortfolioDataKeys.IWantToSell] = true;
                }
                else
                {
                    //Log("---  LONG - NOP ---");
                }
            }
            //            else if(marketPosition < 0)
            //            {
            //                // WE ARE SHORT
            //                GenerateStopLoss(StrategyInfo.AvgEntryPrice * Math.Abs(marketPosition) * StopLossLevel);
            //
            //                if(this.BarsSinceEntry() > 2 && !GetSignalDown(crtdr, rsi, trend))
            //                {
            //                       //Output.WriteLine("{8}: COVER1 on {0}, high {1} low {2} close {3} rsi {4} crtdr {5} xAverageLong {6} xAverageShort {7}", Bars.TimeValue, high, low, close, rsi, crtdr, xAverageLongValue, xAverageShortValue, Bars.Info.Name);
            //                    buyToCoverOrder.Send();
            //                }
            //                else if(rsi < (trend == Trend.Down ? RsiCoverLevelDown : (trend == Trend.Up ? RsiCoverLevelUp : RsiCoverLevelFlat)))
            //                {
            //                       //Output.WriteLine("{8}: COVER2 on {0}, high {1} low {2} close {3} rsi {4} crtdr {5} xAverageLong {6} xAverageShort {7}", Bars.TimeValue, high, low, close, rsi, crtdr, xAverageLongValue, xAverageShortValue, Bars.Info.Name);
            //                    buyToCoverOrder.Send();
            //                }
            //                else
            //                {
            //                       Log("--- SHORT - NOP ---");
            //                }
            //            }

            StrategyEvents cmd = StrategyEvents.None;
            object         obj = MyPortfolioData[PortfolioDataKeys.MoneyManagementCommand]; // Check, if there are any MM-signal events available

            if (obj != null)
            {
                cmd = (StrategyEvents)obj;
            }

            //Log("Got command {0}", cmd);

            switch (cmd) // Execute specific commands, depending on the event
            {
            case StrategyEvents.GenerateOrders_Long:
                int numberOfShares = Convert.ToInt32(MyPortfolioData[PortfolioDataKeys.NumberOfShares]);
                buyOrder.Send(numberOfShares);
                LogThrottled("Generated Buy: {0}#", numberOfShares);
                GenerateOrAdjustStopLosses();
                break;

            case StrategyEvents.GenerateOrders_Short:
                sellOrder.Send();
                LogThrottled("Generated Sell.");
                break;

            case StrategyEvents.None:
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(recalcFrequency));
                break;
            }

            // During calculation at the bar close, global variables, used to exchange messages between the current signal and MM-signal should be reset
            if (Bars.Status == EBarState.Close)
            {
                Log("Close event received."); // only send email output if trade has been sent on this day
                DumpFileLog();

                MyPortfolioData[PortfolioDataKeys.CRTDR] = 1.0;
                MyPortfolioData[PortfolioDataKeys.MoneyManagementCommand] = StrategyEvents.None;
                MyPortfolioData[PortfolioDataKeys.IWantToBuy]             = false;
                MyPortfolioData[PortfolioDataKeys.IWantToSell]            = false;
                MyPortfolioData[PortfolioDataKeys.NumberOfShares]         = 0;
                ExecControl.RecalcLastBarAfter(TimeSpan.FromSeconds(recalcFrequency)); // And start the timer to wait for the new commands from MM-signal
            }
        }