void doupdate(string sym)
        {
            // is update ignored?
            if (IgnoreUpdate(sym)) return;
            // wait till next tick if we send cancels
            bool sentcancel = false;
            // get our offset values
            OffsetInfo off = GetOffset(sym);
            // get position
            Position p = new PositionImpl(_pt[sym]);
            // if we're flat, nothign to do
            if (p.isFlat) return;
            // see whats current
            bool cprofit = off.isProfitCurrent(p);
            bool cstop = off.isStopCurrent(p);
            // if not current, mark for update
            bool updateprofit = !cprofit;
            bool updatestop = !cstop;
            // if we're up to date then quit
            if (!updatestop && !updateprofit) return;
            // see if we have stop update
            if ((updatestop && off.hasStop && !CancelOnce)
                || (updatestop && off.hasStop && CancelOnce && !off.StopcancelPending))
            {
                // notify
                if (!off.StopcancelPending)
                    debug(string.Format("attempting stop cancel: {0} {1}", sym, off.StopId));
                // cancel existing stops
                cancel(off.StopId);
                // mark cancel pending
                off.StopcancelPending = true;
                // mark as sent
                sentcancel |= true;
            }
            // see if we have profit update
            if ((updateprofit && off.hasProfit && AllowSimulatenousCancels) ||
                (updateprofit && off.hasProfit && AllowSimulatenousCancels && !sentcancel))
            {
                if (!CancelOnce || (CancelOnce && !off.ProfitcancelPending))
                {
                    // notify
                    if (!off.ProfitcancelPending)
                        debug(string.Format("attempting profit cancel: {0} {1}", sym, off.ProfitId));
                    // cancel existing profits
                    cancel(off.ProfitId);
                    // mark cancel pending
                    off.ProfitcancelPending = true;
                    // mark as sent
                    sentcancel |= true;
                }
            }

            // wait till next tick if we sent cancel
            if (sentcancel && WaitAfterCancel)
                return;
            bool sentorder = false;
            // send stop first
            if (!off.hasStop)
            {
                // since we have no stop, it's cancel can't be pending
                off.StopcancelPending = false;
                // get new stop
                Order stop = Calc.PositionStop(p, off.StopDist, off.StopPercent, off.NormalizeSize, off.MinimumLotSize);
                // mark size
                off.SentStopSize = stop.size;
                // if it's valid, send and track
                if (stop.isValid)
                {
                    stop.id = Ids.AssignId;
                    off.StopId = stop.id;
                    SendOrderEvent(stop);
                    // notify
                    debug(string.Format("sent new stop: {0} {1}", stop.id, stop.ToString(DebugDecimals)));
                    sentorder = true;
                }
                else if (_verbdebug)
                {
                    debug(sym + " invalid stop: " + stop.ToString(DebugDecimals));
                }

            }

            if ((!off.hasProfit && AllowSimulatenousOrders) || (!off.hasProfit && !AllowSimulatenousOrders && !sentorder))
            {
                // since we have no stop, it's cancel can't be pending
                off.ProfitcancelPending = false;
                // get new profit
                Order profit = Calc.PositionProfit(p, off.ProfitDist, off.ProfitPercent, off.NormalizeSize, off.MinimumLotSize);
                // mark size
                off.SentProfitSize = profit.size;
                // if it's valid, send and track it
                if (profit.isValid)
                {
                    profit.id = Ids.AssignId;
                    off.ProfitId = profit.id;
                    SendOrderEvent(profit);
                    // notify
                    debug(string.Format("sent new profit: {0} {1}", profit.id, profit.ToString(DebugDecimals)));
                    sentorder = true;
                }
                else if (_verbdebug)
                {
                    debug(sym + " invalid profit: " + profit.ToString(DebugDecimals));
                }
            }
            // make sure new offset info is reflected
            SetOffset(sym, off);

        }