/// <summary>
 /// 
 /// </summary>
 /// <param name="quote"></param>
 /// <param name="isUp"></param>
 public void Update(Quote? quote, bool isUp)
 {
     _quote = quote;
     _isUpFromPrevious = isUp;
     _lastUpdate = DateTime.Now;
 }
        public void BeginManagedOrdersUpdate(Quote? quote)
        {
            //List<Order> orders = _provider.Account.TradeEntities.GetOrdersByState(OrderStateEnum.Executed | OrderStateEnum.Submitted);

            if (quote.HasValue == false)
            {
                SystemMonitor.OperationError("Quote not assigned.");
                return;
            }

            decimal? ask = quote.Value.Ask;
            decimal? bid = quote.Value.Bid;
            decimal? spread = quote.Value.Spread;

            if (ask.HasValue == false || bid.HasValue == false || spread.HasValue == false)
            {
                return;
            }

            foreach (Order order in _orders.Values)
            {
                if (order.State != OrderStateEnum.Executed
                    && order.State != OrderStateEnum.Submitted)
                {
                    continue;
                }

                if (order.IsDelayed && order.State == OrderStateEnum.Submitted)
                {// Pending order, check for opening conditions.
                    switch (order.Type)
                    {
                        case OrderTypeEnum.BUY_LIMIT_MARKET:
                            // Submitted buy above the current price.
                            if (order.OpenPrice <= ask)
                            {
                                order.AcceptPendingExecuted(ask.Value);
                            }
                            break;
                        case OrderTypeEnum.BUY_STOP_MARKET:
                            // Submitted buy below the current price.
                            if (order.OpenPrice >= ask)
                            {
                                order.AcceptPendingExecuted(ask.Value);
                            }
                            break;
                        case OrderTypeEnum.SELL_LIMIT_MARKET:
                            // Submitted sell above the current price.
                            if (order.OpenPrice <= bid)
                            {
                                order.AcceptPendingExecuted(bid.Value);
                            }
                            break;
                        case OrderTypeEnum.SELL_STOP_MARKET:
                            // Submitted sell below the current price.
                            if (order.OpenPrice >= bid)
                            {
                                order.AcceptPendingExecuted(bid.Value);
                            }
                            break;
                    }

                    // A pending order is executed if it is between low and high.
                    if (_lastDataBar.HasValue
                        && order.OpenPrice.HasValue
                        && order.State == OrderStateEnum.Submitted
                        && order.OpenPrice <= _lastDataBar.Value.High
                        && order.OpenPrice >= _lastDataBar.Value.Low)
                    {
                        order.AcceptPendingExecuted(order.OpenPrice.Value + spread.Value);
                    }
                }

                if (order.StopLoss.HasValue
                    && order.StopLoss.Value != 0)
                {// Check Stop Loss level.
                    if ((order.IsBuy && bid <= order.StopLoss) ||
                        (order.IsBuy == false && ask >= order.StopLoss))
                    {
                        if (order.State == OrderStateEnum.Executed)
                        {
                            string tmp;
                            ((PassiveOrder)order).CloseOrCancel(null, null, out tmp);
                            continue;
                        }
                    }
                }

                if (order.TakeProfit.HasValue
                    && order.TakeProfit.Value != 0)
                {// Check Take Profit level.
                    if ((order.IsBuy && bid >= order.TakeProfit) ||
                        (order.IsBuy == false && ask <= order.TakeProfit))
                    {
                        if (order.State == OrderStateEnum.Executed)
                        {
                            string tmp;
                            ((PassiveOrder)order).CloseOrCancel(null, null, out tmp);
                            continue;
                        }
                    }
                }

                if ((CheckForConflictsInsideBar(order)
                    || CheckStopLossInsideBar(order)
                    || CheckTakeProfitInsideBar(order))
                    && order.State == OrderStateEnum.Executed)
                {
                    string tmp;
                    ((PassiveOrder)order).CloseOrCancel(null, null, out tmp);
                    continue;
                }
            } // foreach
        }
        void delivery_QuoteUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, Quote? quote)
        {
            bool isUp = true;
            SymbolInformation information;
            lock (this)
            {
                if (_symbolQuotes.ContainsKey(session.Symbol) == false
                    || _symbolQuotes[session.Symbol] == null)
                {
                    information = new SymbolInformation(session.Symbol);
                    _symbolQuotes.Add(session.Symbol, information);
                }
                else
                {
                    information = _symbolQuotes[session.Symbol];
                    if (information.Quote.HasValue && quote.HasValue)
                    {
                        if (information.Quote.Value.Ask == quote.Value.Ask
                            && information.Quote.Value.Bid == quote.Value.Bid)
                        {
                            return;
                        }

                        isUp = information.Quote.Value.Ask < quote.Value.Ask;
                    }
                }

                information.Update(quote, isUp);
            }

            if (QuotesUpdateEvent != null)
            {
                QuotesUpdateEvent(this, information);
            }
        }
Ejemplo n.º 4
0
        void _dataDelivery_QuoteUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, Quote? quote)
        {
            if (session.Symbol == this.Symbol)
            {
                if (quote.HasValue)
                {
                    lock(this)
                    {
                        if (this.Volume > 0)
                        {
                            _price = quote.Value.Ask;
                        }
                        else
                        {
                            _price = quote.Value.Bid;
                        }
                    }
                }
                else
                {
                    _price = null;
                }

                RecalculateParameters(true);
            }
        }
        void _dataDelivery_QuoteUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, Quote? quote)
        {
            _lastDataQuote = quote;

            BeginAccountInfoUpdate(_account.Info);

            BeginManagedOrdersUpdate(quote);
        }
        void _dataDelivery_QuoteUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, Quote? quote)
        {
            if (_sessionInfo.Equals(session) == false)
            {
                return;
            }

            lock (this)
            {
                _lastQuoteTime = DateTime.Now;
                _currentQuote = quote;
            }

            if (QuoteUpdateEvent != null)
            {
                QuoteUpdateEvent(this);
            }
        }
        /// <summary>
        /// This will work properly only for USD *BASED ACCOUNTS*.
        /// Code based on the forexOpenPnL.txt VB6 code file from the SDK.
        /// See here for details: http://finance.groups.yahoo.com/group/mbtsdk/message/6120
        /// </summary>
        /// <returns></returns>
        bool CalculatePositionOpenPnLAndBasis(MbtPosition position, Quote? positionSymbolQuote, out double openPnL, out double basis)
        {
            openPnL = 0;
            basis = 0;

            if (positionSymbolQuote.HasValue == false ||
                positionSymbolQuote.Value.Ask.HasValue == false || positionSymbolQuote.Value.Bid.HasValue == false)
            {
                return false;
            }

            long aggregatedPosition = position.AggregatePosition;
            if (aggregatedPosition == 0)
            {
                return true;
            }

            // This also assumes aggregatedPosition is not zero!
            basis = ((position.OvernightPrice * position.OvernightPosition) + (position.IntradayPrice * position.IntradayPosition)) / aggregatedPosition;
            Symbol? symbol = Symbol.CreateForexPairSymbol(position.Symbol);

            if (symbol.HasValue == false)
            {
                return false;
            }

            bool isLong = aggregatedPosition > 0;

            double ask = (double)positionSymbolQuote.Value.Ask.Value;
            double bid = (double)positionSymbolQuote.Value.Bid.Value;

            if (symbol.Value.ForexCurrency1 == "USD")
            {// Based C1.
                if (isLong)
                {// Long. long position - use Bid ' ((bid - basis) / bid) * qty
                    openPnL = ((bid - basis) / bid) * aggregatedPosition;
                    return true;
                }
                else
                {// Short. short position - use Ask ' ((ask - basis) / ask) * qty
                    openPnL = ((ask - basis) / ask) * aggregatedPosition;
                    return true;
                }
            }
            else if (symbol.Value.ForexCurrency2 == "USD")
            {// Based C2.
                if (isLong)
                {// Long. ' long position - use Bid ' (bid - basis) * qty
                    openPnL = (bid - basis) * aggregatedPosition;
                    return true;
                }
                else
                {// Short. ' short position - use Ask ' (ask - basis) * qty
                    openPnL = (ask - basis) * aggregatedPosition;
                    return true;
                }
            }
            else
            {// Not based.

                // This is the code that covers this scenario (from the forexOpenPnL.txt from the SDK),
                // however it requires the usage of other pairs data... so not implemented right now.
                //SystemMonitor.OperationWarning(string.Format("Position PnL not calculated for symbol [{0}] since pair not USD based.", position.Symbol));

                return false;

                //' Neither C1 or C2 is our base. therefore, find a "related symbol" for
                //' C2 that will relate C2 back to our base "USD", and use the related
                //' symbol's Bid/Ask as part of the calculation. Do this by creating a
                //' temp variable "f" with the value of the Bid/Ask, inverted if necessary.
                //Dim f As Double
                //    f = 0
                //    For j = 0 To mlSymCnt
                //' Find C1 base (e.g. EUR/CHF produces USD/CHF)
                //        If Left(msSyms(j), 3) = "USD" And Right(s, 3) = Right(msSyms(j), 3) Then
                //' use Ask for short, Bid for long, and invert
                //            f = 1 / (IIf(aggregatedPosition < 0, mdCAsk(j), mdCBid(j)))
                //'			dOpenPnL = (IIf(aggregatedPosition < 0, a, b) - dBasis) * f * aggregatedPosition
                //            Exit For ' found it !
                //        End If
                //    Next
                //    If f = 0 Then
                //' If C1 base not found, find C2 base (e.g. EUR/GBP produces GBP/USD)
                //        For j = 0 To mlSymCnt
                //            If Right(msSyms(j), 3) = "USD" And Right(s, 3) = Left(msSyms(j), 3) Then
                //' use Ask for short, Bid for long, but don't invert
                //                f = IIf(aggregatedPosition < 0, mdCAsk(j), mdCBid(j))
                //'				dOpenPnL = (IIf(aggregatedPosition < 0, a, b) - dBasis) * f * aggregatedPosition
                //                Exit For ' found it !
                //            End If
                //        Next
                //    End If
                //    If f = 0 Then ' for some reason, none found (you should find out why) !
                //        Debug.Print "ERROR"
                //    Else
                //' (bidOrAsk - basis) * f * qty
                //' f contains the Bid/Ask of the related symbol, inverted if necessary
                //        dOpenPnL = (IIf(aggregatedPosition < 0, a, b) - dBasis) * f * aggregatedPosition
                //    End If
                //End If

            }
        }
        void ConvertQuoteRecord(ref Quote quote, QUOTERECORD pRec)
        {
            quote.Ask = (0 == pRec.dAsk) ? (decimal?)null : (decimal)pRec.dAsk;
            quote.Bid = (0 == pRec.dBid) ? (decimal?)null : (decimal)pRec.dBid;

            quote.High = (0 == pRec.dHigh) ? (decimal?)null : (decimal)pRec.dHigh;
            quote.Low = (0 == pRec.dLow) ? (decimal?)null : (decimal)pRec.dLow;

            quote.Open = (decimal)pRec.dOpen;
            quote.Volume = pRec.lVolume;
            quote.Time = pRec.UTCDateTime;
        }
        public Quote? GetSingleSymbolQuote(string symbolName, TimeSpan timeOut, out string symbolMarket)
        {
            symbolMarket = string.Empty;
            if (IsInitialized == false)
            {
                return null;
            }

            string market = string.Empty;
            Quote? result = null;

            _messageLoopOperator.Invoke(delegate()
            {
                MbtQuotes client = _quotesClient;
                if (client == null)
                {
                    return;
                }

                QUOTERECORD record = client.GetSingleQuote(symbolName, (int)timeOut.TotalMilliseconds);
                if (string.IsNullOrEmpty(record.bstrSymbol) == false
                    && record.bstrSymbol.ToUpper() == symbolName.ToUpper())
                {// Match found.
                    Quote quoteResult = new Quote();
                    ConvertQuoteRecord(ref quoteResult, record);
                    market = record.bstrMarket;
                    result = quoteResult;
                }
                else
                {
                    // Failed to find baseCurrency.
                    SystemMonitor.OperationWarning("Failed to find requested symbol.");
                }

            });

            if (result.HasValue)
            {
                symbolMarket = market;
            }

            return result;
        }
        /// <summary>
        /// Create a dataDelivery bar based on quote.
        /// </summary>
        /// <param name="quote"></param>
        /// <returns></returns>
        public DataBar UpdateCurrentBar(DataBar currentBar, Quote quote)
        {
            if (quote.Bid.HasValue == false || quote.Ask.HasValue == false)
            {
                return currentBar;
            }

            currentBar.Low = Math.Min(quote.Bid.Value, currentBar.Low);
            currentBar.High = Math.Max(quote.Bid.Value, currentBar.High);

            currentBar.Close = quote.Bid.Value;

            if (quote.Volume.HasValue)
            {
                currentBar.Volume = quote.Volume.Value;
            }

            return currentBar;
        }
        /// <summary>
        /// Follow quotes update.
        /// </summary>
        void _dataDelivery_QuoteUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, Quote? quote)
        {
            if (_sessionInfo.Equals(session) == false || _period.HasValue == false
                || quote.HasValue == false)
            {
                return;
            }

            DataBar? lastBar = null;
            if (_dataBars.Count > 0)
            {
                lastBar = _dataBars[_dataBars.Count - 1];
            }
            else
            {// If there are no existing bars, we do not operate, to evade mixing up start / end period etc.
                return;
            }

            TimeSpan? period = _period;

            DataBarUpdateType? updateType = null;

            // The time of a bar is its open time, so everything after a "period" closeVolume of time after it is part of that bar.
            if (lastBar.Value.DateTime + period < quote.Value.Time)
            {// We need to append a new bar.
                DateTime newBarDateTime = lastBar.Value.DateTime;
                int i = 0;
                while (newBarDateTime.Add(period.Value) < quote.Value.Time)
                {// Establish end time of new bar (max 1000 steps to evade potential lockups).
                    newBarDateTime = newBarDateTime.Add(period.Value);
                    i++;

                    if (i > 1000)
                    {// We have tried and failed to establish proper new period so just abort.
                        SystemMonitor.OperationError("We have tried and failed to establish proper new period so quote aborted.");
                        return;
                    }
                }

                DataBar? newBar = BarFromQuote(lastBar, newBarDateTime, quote.Value);
                if (newBar.HasValue == false)
                {// Failed to establish bar from quote.
                    return;
                }

                updateType = DataBarUpdateType.NewPeriod;

                lock (this)
                {// Add the new bar.
                    _lastDataUpdate = DateTime.Now;
                    _dataBars.Add(newBar.Value);
                }
            }
            else
            {
                updateType = DataBarUpdateType.CurrentBarUpdate;

                lock (this)
                {// Just update the current last bar.
                    _lastDataUpdate = DateTime.Now;
                    _dataBars[_dataBars.Count - 1] = UpdateCurrentBar(lastBar.Value, quote.Value);
                }
            }

            if (updateType.HasValue && DataBarHistoryUpdateEvent != null)
            {
                DataBarHistoryUpdateEvent(this, updateType.Value, 1);
            }
        }
        public DataBar? BarFromQuote(DataBar? previousBar, DateTime time, Quote quote)
        {
            if ((quote.IsFullySet == false && previousBar.HasValue == false)
                || (quote.Ask.HasValue == false || quote.Bid.HasValue == false))
            {// We need at least previous bar if quote is not fully set.
                return null;
            }

            decimal open = quote.Open.HasValue ? quote.Open.Value : previousBar.Value.Close;
            decimal close = quote.Bid.Value;

            DataBar result = new DataBar(time,
                open,
                Math.Max(open, close),
                Math.Min(open, close),
                close,
                0);

            return result;
        }
        public void BeginManagedOrdersUpdate(Quote? quote)
        {
            //List<Order> orders = _provider.Account.TradeEntities.GetOrdersByState(OrderStateEnum.Executed | OrderStateEnum.Submitted);

            if (quote.HasValue == false)
            {
                SystemMonitor.OperationError("Quote not assigned.");
                return;
            }

            decimal? ask = quote.Value.Ask;
            decimal? bid = quote.Value.Bid;
            decimal? spread = quote.Value.Spread;

            if (ask.HasValue == false || bid.HasValue == false || spread.HasValue == false)
            {
                return;
            }

            foreach (Order order in _orders.Values)
            {
                if (order.State != OrderStateEnum.Executed
                    && order.State != OrderStateEnum.Submitted)
                {
                    continue;
                }

                if (order.IsDelayed && order.State == OrderStateEnum.Submitted)
                {// Pending order, check for opening conditions.
                    switch (order.Type)
                    {
                        case OrderTypeEnum.BUY_LIMIT_MARKET:
                            // Submitted buy below the current price.
                            if (order.OpenPrice >= ask)
                            {
                                DateTime? time = order.QuoteProvider != null && order.QuoteProvider.CurrentQuote.HasValue? order.QuoteProvider.CurrentQuote.Value.Time : null;
                                order.AcceptPendingExecuted(ask.Value, time);
                                string operationResultMessage;
                                UpdatePosition(order.Symbol, order.CurrentDirectionalVolume, out operationResultMessage);
                            }
                            break;
                        //case OrderTypeEnum.BUY_STOP_MARKET:
                        //    // Submitted buy below the current price.
                        //    if (order.OpenPrice >= ask)
                        //    {
                        //        order.AcceptPendingExecuted(ask.Value);
                        //    }
                        //    break;
                        case OrderTypeEnum.SELL_LIMIT_MARKET:
                            // Submitted sell above the current price.
                            if (order.OpenPrice <= bid)
                            {
                                DateTime? time = order.QuoteProvider != null && order.QuoteProvider.CurrentQuote.HasValue ? order.QuoteProvider.CurrentQuote.Value.Time : null;
                                order.AcceptPendingExecuted(bid.Value, time);
                                string operationResultMessage;
                                UpdatePosition(order.Symbol, order.CurrentDirectionalVolume, out operationResultMessage);
                            }
                            break;
                        //case OrderTypeEnum.SELL_STOP_MARKET:
                        //    // Submitted sell below the current price.
                        //    if (order.OpenPrice >= bid)
                        //    {
                        //        order.AcceptPendingExecuted(bid.Value);
                        //    }
                        //    break;
                    }

                    // Don't think this is needed as it should be satisfied by the above??
                    //
                    // A pending order is executed if it is between low and high.
                    //if (_lastDataBar.HasValue
                    //    && order.OpenPrice.HasValue
                    //    && order.State == OrderStateEnum.Submitted
                    //    && order.OpenPrice <= _lastDataBar.Value.High
                    //    && order.OpenPrice >= _lastDataBar.Value.Low)
                    //{
                    //    order.AcceptPendingExecuted(order.OpenPrice.Value + spread.Value);
                    //}
                }

                if (order.StopLoss.HasValue
                    && order.StopLoss.Value != 0)
                {// Check Stop Loss level.
                    if ((order.IsBuy && bid <= order.StopLoss) ||
                        (order.IsBuy == false && ask >= order.StopLoss))
                    {
                        if (order.State == OrderStateEnum.Executed)
                        {
                            string tmp;
                            ((PassiveOrder)order).CloseOrCancel(null, null, out tmp);
                            continue;
                        }
                    }
                }

                if (order.TakeProfit.HasValue
                    && order.TakeProfit.Value != 0)
                {// Check Take Profit level.
                    if ((order.IsBuy && bid >= order.TakeProfit) ||
                        (order.IsBuy == false && ask <= order.TakeProfit))
                    {
                        if (order.State == OrderStateEnum.Executed)
                        {
                            string tmp;
                            ((PassiveOrder)order).CloseOrCancel(null, null, out tmp);
                            continue;
                        }
                    }
                }

                if ((CheckForConflictsInsideBar(order)
                        || CheckStopLossInsideBar(order)
                        || CheckTakeProfitInsideBar(order))
                        && order.State == OrderStateEnum.Executed)
                {
                    string tmp;
                    ((PassiveOrder)order).CloseOrCancel(null, null, out tmp);
                    continue;
                }
            } // foreach
        }
 protected override void dataDelivery_QuoteUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, Quote? quote)
 {
     base.dataDelivery_QuoteUpdateEvent(dataDelivery, session, quote);
     DoUpdate();
 }
Ejemplo n.º 15
0
 protected virtual void dataDelivery_QuoteUpdateEvent(ISourceDataDelivery dataDelivery, DataSessionInfo session, Quote? quote)
 {
 }
 public void Quote(string sessionName, DateTime? sessionStart, Quote quote)
 {
 }
        public bool RequestQuoteUpdate(DataSessionInfo sessionInfo, bool waitResult)
        {
            Quote? quote = null;
            lock (this)
            {
                if (_sourceDataBarProvider == null || _sourceDataBarProvider.BarCount == 0)
                {// No steps done yet.
                    return true;
                }

            }

            lock (_sourceDataBarProvider)
            {
                if (_sourceDataBarProvider.BarCount < _step)
                {
                    SystemMonitor.Error("Unexpected case.");
                    return false;
                }
                else
                {
                    if (_step - 1 >= 0 && _step - 1 < _sourceDataBarProvider.BarCount)
                    {
                        quote = new Quote(_sourceDataBarProvider.BarsUnsafe[_step - 1], _spreadPoints * _sessionInfo.DecimalIncrement);
                    }
                }
            }

            if (quote.HasValue == false)
            {// No dataDelivery.
                return false;
            }

            if (QuoteUpdateEvent != null)
            {
                QuoteUpdateEvent(this, sessionInfo, quote);
            }

            return true;
        }
        void ConvertQuoteRecord(ref Quote quote, Commission? commission, QUOTERECORD pRec)
        {
            quote.Ask = (0 == pRec.dAsk) ? (decimal?)null : (decimal)pRec.dAsk;
            quote.Bid = (0 == pRec.dBid) ? (decimal?)null : (decimal)pRec.dBid;

            MBTradingConnectionManager manager = _manager;
            if (commission.HasValue && (manager != null && manager.Adapter != null && manager.Adapter.ApplyQuoteCommission))
            {
                commission.Value.ApplyCommissions(manager.Adapter, ref quote);
            }

            quote.High = (0 == pRec.dHigh) ? (decimal?)null : (decimal)pRec.dHigh;
            quote.Low = (0 == pRec.dLow) ? (decimal?)null : (decimal)pRec.dLow;

            quote.Open = (decimal)pRec.dOpen;
            quote.Volume = pRec.lVolume;
            quote.Time = pRec.UTCDateTime;
        }