public void OnAccountLoaded(MbtAccount account) { this.m_account = account; if (firstTime) { orderLog.Notice("Starting account = " + Display(m_account)); m_position = m_OrderClient.Positions.Find(m_account, symbol.Symbol); if (m_position != null) { orderLog.Notice("Starting position = " + Display(m_position)); } MbtOpenOrders orders = m_OrderClient.OpenOrders; orders.LockItems(); for (int i = 0; i < orders.Count; i++) { orderLog.Notice("Order " + i + ": " + Display(orders[i])); m_orders[orders[i].OrderNumber] = orders[i]; } orders.UnlockItems(); foreach (string orderNum in m_orders.Keys) { string bstrRetMsg = null; if (m_OrderClient.Cancel(orderNum, ref bstrRetMsg) == true) { orderLog.Notice("Order " + orderNum + ": Canceled. " + bstrRetMsg); } else { orderLog.Notice("Order " + orderNum + ": Cancel Failed: " + bstrRetMsg); } } CheckSignalSync(); } firstTime = false; }
public void OnPositionUpdated(MbtPosition position) { m_position = position; if (debug) { orderLog.Debug("Account: OnPositionUpdated( )"); } }
public void OnPositionAdded(MbtPosition position) { m_position = position; if (debug) { orderLog.Debug("OnPositionAdded( )"); } }
public int GetPositionSize() { int size = 0; try { MbtPosition position = m_position; if (position != null) { size += position.PendingBuyShares - position.PendingSellShares + position.IntradayPosition + position.OvernightPosition; } } catch (Exception ex) { orderLog.Notice("Exception: " + ex); } return(size); }
/// <summary> /// Helper, converts from MBT to OFxP object. /// </summary> PositionInfo?ConvertToPositionInfo(MbtPosition position) { PositionInfo result = new PositionInfo(); Symbol?symbol = _adapter.GetSymbolByName(position.Symbol, true); if (symbol.HasValue == false) { return(null); } result.Symbol = symbol.Value; result.Volume = position.CloseableShares; result.Commission = (decimal)Math.Round(position.Commission, 4); result.PendingBuyVolume = position.PendingBuyShares; result.PendingSellVolume = position.PendingSellShares; result.Result = (decimal)Math.Round(position.RealizedPNL, 4); return(result); }
void _orderClient_OnPositionAdded(MbtPosition pPos) { }
/// <summary> /// Helper, converts from MBT to OFxP object. /// </summary> PositionInfo? ConvertToPositionInfo(MbtPosition position) { PositionInfo result = new PositionInfo(); Symbol? symbol = _adapter.GetSymbolByName(position.Symbol, true); if (symbol.HasValue == false) { return null; } result.Symbol = symbol.Value; result.Volume = position.CloseableShares; result.Commission = (decimal)Math.Round(position.Commission, 4); result.PendingBuyVolume = position.PendingBuyShares; result.PendingSellVolume = position.PendingSellShares; result.Result = (decimal)Math.Round(position.RealizedPNL, 4); return result; }
void m_OrderClient_OnPositionUpdated(MbtPosition pPos) { }
void PositionHasChanged(MbtPosition pPos) //pmh - Renamed from OnPositionChanged. This is not an event - don't name it so. { debug(String.Format("PositionHasChanged {0} {1}", pPos.Symbol, pPos.AggregatePosition)); string sym = pPos.Symbol; //TODO: check accuracy of AveragePrice2. Currently known to not correctly include prices from further than 1 day back //AveragePrice2 only available in release candidates so reverting to the calc below that //decimal price = (decimal) pPos.AveragePrice2; decimal price = //pmh check each, not together (pPos.IntradayPosition + pPos.OvernightPosition != 0) (pPos.IntradayPosition != 0 && pPos.OvernightPosition != 0) //pmh - do this instead! ? //pmh bug! (decimal)(((pPos.IntradayPosition * pPos.IntradayPrice) + (pPos.OvernightPosition * pPos.OvernightPrice)) / (pPos.IntradayPrice + pPos.OvernightPosition)) (decimal)(((pPos.IntradayPosition * pPos.IntradayPrice) + (pPos.OvernightPosition * pPos.OvernightPrice)) / (pPos.IntradayPosition + pPos.OvernightPosition)) : 0; int size = pPos.AggregatePosition; //TODO: make this pPos.RealizedPNL2 when it is available decimal cpl = (decimal)pPos.RealizedPNL; string account = pPos.Account.Account; Position p = new PositionImpl(sym, price, size, cpl, account); pt.NewPosition(p); }
void m_OrderClient_OnPositionUpdated(MbtPosition pPos) { debug(String.Format("m_OrderClient_OnPositionUpdated: {0} {1} {2}", pPos.Account.Account, pPos.Symbol, pPos.AggregatePosition)); PositionHasChanged(pPos); }
/// <summary> /// Helper, converts from MBT to OFxP object. /// </summary> PositionInfo? ConvertToPositionInfo(MbtPosition position, MBTradingQuote quotes) { PositionInfo result = new PositionInfo(); Symbol? symbol = _adapter.GetSymbolByName(position.Symbol, true); if (symbol.HasValue == false) { return null; } result.Symbol = symbol.Value; result.Volume = position.AggregatePosition;/*position.CloseableShares;*/ result.Commission = (decimal)Math.Round(position.Commission, IntegrationAdapter.AdvisedAccountDecimalsPrecision); result.PendingBuyVolume = position.PendingBuyShares; result.PendingSellVolume = position.PendingSellShares; result.MarketValue = 0; result.ClosedResult = (decimal)Math.Round(position.RealizedPNL, 4); if (quotes.SessionsQuotes.ContainsKey(symbol.Value.Name)) { double openPnL, basis; if (CalculatePositionOpenPnLAndBasis(position, quotes.SessionsQuotes[symbol.Value.Name].Quote, out openPnL, out basis)) { result.Result = (decimal)Math.Round(openPnL, IntegrationAdapter.AdvisedAccountDecimalsPrecision); result.Basis = (decimal)basis; } } return result; }
/// <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 m_OrderClient_OnPositionUpdated(MbtPosition pPos) { //debug(String.Format("updating pos: {0} {1} {2}", pPos.Account.Account, pPos.Symbol, pPos.AggregatePosition)); OnPositionChanged(pPos); }
void OnPositionChanged(MbtPosition pPos) { debug(String.Format("OnPositionChanged {0} {1}", pPos.Symbol, pPos.AggregatePosition)); string sym = pPos.Symbol; int size = pPos.AggregatePosition; //TODO: check accuracy of AveragePrice2. Currently known to not correctly include prices from further than 1 day back //AveragePrice2 only available in release candidates so reverting to the calc below that //decimal price = (decimal) pPos.AveragePrice2; decimal price = (pPos.IntradayPosition + pPos.OvernightPosition != 0) ? (decimal)(((pPos.IntradayPosition * pPos.IntradayPrice) + (pPos.OvernightPosition * pPos.OvernightPrice)) / (pPos.IntradayPrice + pPos.OvernightPosition)) : 0; //TODO: make this pPos.RealizedPNL2 when it is available decimal cpl = (decimal)pPos.RealizedPNL; string account = pPos.Account.Account; Position p = new PositionImpl(sym, price, size, cpl, account); pt.NewPosition(p); }