Example #1
0
        public static string Serialize(OffsetInfo oi)
        {
            string m =
                string.Format("{0},{1},{2},{3},{4},{5}", oi.ProfitDist, oi.StopDist, oi.ProfitPercent, oi.StopPercent, oi.NormalizeSize, oi.MinimumLotSize);

            return(m);
        }
Example #2
0
        public void CustomOffsets()
        {

            // get default offset
            ot.DefaultOffset = SampleOffset();
            // verify that random symbol has default values
            Assert.AreEqual(ot.DefaultOffset.ProfitPercent, ot[SYMB].ProfitPercent);
            Assert.AreEqual(ot.DefaultOffset.StopPercent, ot[SYMB].StopPercent);
            Assert.AreEqual(ot.DefaultOffset.ProfitDist, ot[SYMB].ProfitDist);
            Assert.AreEqual(ot.DefaultOffset.StopDist, ot[SYMB].StopDist);
            // add custom offset different than default
            ot[SYMB] = new OffsetInfo(POFFSET * 2, SOFFSET * 2, .5m, .5m,true,100);
            // verify custom has taken effect
            Assert.AreEqual(ot.DefaultOffset.ProfitPercent/2, ot[SYMB].ProfitPercent);
            Assert.AreEqual(ot.DefaultOffset.StopPercent/2, ot[SYMB].StopPercent);
            Assert.AreEqual(ot.DefaultOffset.ProfitDist*2, ot[SYMB].ProfitDist);
            Assert.AreEqual(ot.DefaultOffset.StopDist*2, ot[SYMB].StopDist);
            // verify another symbol still has default
            Assert.AreEqual(ot.DefaultOffset.ProfitPercent, ot[SYMC].ProfitPercent);
            Assert.AreEqual(ot.DefaultOffset.StopPercent, ot[SYMC].StopPercent);
            Assert.AreEqual(ot.DefaultOffset.ProfitDist, ot[SYMC].ProfitDist);
            Assert.AreEqual(ot.DefaultOffset.StopDist, ot[SYMC].StopDist);


        }
Example #3
0
        /// <summary>
        /// this must be called once per position tracker, for each position update.
        /// if you are using your own position tracker with this trailing stop(eg from offset tracker, or somewhere else)
        /// you only need to adjust it once, so if you adjust it directly you don't need to call again here.
        /// </summary>
        /// <param name="fill"></param>
        public void Adjust(Trade fill)
        {
            // get index for symbol
            int idx = symidx(fill.symbol);

            // only do following if we're tracking trail for this symbol
            if (idx != NOSYM)
            {
                // get current position size
                int psize = _pt[fill.symbol].UnsignedSize;
                // get trailing information
                OffsetInfo trail = _trail[idx];
                // get expected position size
                int esize = psize - Calc.Norm2Min(psize * trail.StopPercent, trail.MinimumLotSize);
                // get actual position size after change
                int asize = psize - fill.UnsignedSize;
                // if expected and actual match, mark pending as false
                if (esize == asize)
                {
                    D("filled trailing stop for: " + fill.symbol);
                    _pendingfill[idx] = false;
                }
            }

            _pt.Adjust(fill);
            // if we're flat now, make sure ref price is reset
            if (_pt[fill.symbol].isFlat)
            {
                _ref[idx] = 0;
            }
        }
Example #4
0
 public static string Serialize(OffsetInfo oi)
 {
     string m =
         string.Format("{0},{1},{2},{3},{4},{5}", oi.ProfitDist, oi.StopDist, oi.ProfitPercent, oi.StopPercent, oi.NormalizeSize, oi.MinimumLotSize);
     return m;
     
 }
Example #5
0
 public void SerializeDeserialize()
 {
     OffsetInfo oi = new OffsetInfo(2, 1);
     string msg = OffsetInfo.Serialize(oi);
     OffsetInfo co = OffsetInfo.Deserialize(msg);
     Assert.AreEqual(2,oi.ProfitDist);
     Assert.AreEqual(1, oi.StopDist);
     
 }
Example #6
0
        void doupdate(string sym, bool poschange)
        {
            // is update ignored?
            if (IgnoreUpdate(sym))
            {
                return;
            }
            // get our offset values
            OffsetInfo off = GetOffset(sym);

            // see if we have profit
            if (off.hasProfit)
            {
                // cancel existing profits
                cancel(off.ProfitId);
                // wait a moment to allow cancel to be received
                System.Threading.Thread.Sleep(_cancelpause);
            }
            // see if we have stop
            if (off.hasStop)
            {
                // cancel existing stops
                cancel(off.StopId);
                // wait a moment to allow cancel to be received
                System.Threading.Thread.Sleep(_cancelpause);
            }

            if (!off.hasProfit)
            {
                // get new profit
                Order profit = Calc.PositionProfit(_pt[sym], off.ProfitDist, off.ProfitPercent, off.NormalizeSize, off.MinimumLotSize);
                // if it's valid, send and track it
                if (profit.isValid)
                {
                    profit.id    = Ids.AssignId;
                    off.ProfitId = profit.id;
                    SendOffset(profit);
                }
            }
            if (!off.hasStop)
            {
                // get new stop
                Order stop = Calc.PositionStop(_pt[sym], off.StopDist, off.StopPercent, off.NormalizeSize, off.MinimumLotSize);
                // if it's valid, send and track
                if (stop.isValid)
                {
                    stop.id    = Ids.AssignId;
                    off.StopId = stop.id;
                    SendOffset(stop);
                }
            }
            // make sure new offset info is reflected
            SetOffset(sym, off);
        }
Example #7
0
        void SetOffset(string sym, OffsetInfo off)
        {
            OffsetInfo v;

            if (_offvals.TryGetValue(sym, out v))
            {
                _offvals[sym] = off;
            }
            else
            {
                _offvals.Add(sym, off);
            }
        }
Example #8
0
        public void ResendTest2()
        {
            // reset "book" to start from scratch
            reset();
            
            // SETOFFSET("IBM", 0.03, 0, 1, 0);
            const string sym = "IBM";
            const decimal pdist = .03m;
            const decimal pct = 1;
            ot[sym] = new OffsetInfo(pdist, 0, pct, 0, false, 1);
            Assert.AreEqual(pdist, ot[sym].ProfitDist);
            Assert.AreEqual(pct, ot[sym].ProfitPercent);
            // entry fill
            // 094508: fill: 20100423,94532,IBM,SELL,10,128.85, 0
            fill(new TradeImpl(sym, 128.85m, -10));
            Assert.AreEqual(-10, ot.PositionTracker[sym].Size);
            // profit 
            // 094508: sent new profit: 634076112353906253  BUY10 [email protected] [] 634076112353906253
            Assert.AreEqual(1, profits.Count);
            Order profit = profits[0];
            Assert.AreEqual(128.82m, profit.price);
            Assert.AreEqual(10, profit.size);
            // fill profit
            // 094609: fill: 20100423,94632,IBM,BUY,10,128.82, 634076112353906253
            // 094609: IBM hit profit: 634076112353906253
            Assert.IsTrue(profit.Fill(TickImpl.NewTrade(sym, 128.82m, 10)));
            Trade profitfill = (Trade)profit;
            fill(profitfill);

            // we're now flat
            // 094609: IBM now flat.
            Assert.IsTrue(ot.PositionTracker[sym].isFlat);
            // tick
            ot.newTick(TickImpl.NewTrade(sym,128.82m,100));
            Assert.AreEqual(0, profits.Count);
            // re-enter
            //094722: fill: 20100423,94746,IBM,SELL,10,128.86, 100947
            fill(new TradeImpl(sym, 128.86m, -10));
            Assert.AreEqual(-10, ot.PositionTracker[sym].Size);
            // we should now have a profit offset
            Assert.AreEqual(1, profits.Count);
            profit = profits[0];
            Assert.AreEqual(128.83m, profit.price);
            Assert.AreEqual(10, profit.size);

        }
Example #9
0
        /// <summary>
        /// this must be called once per position tracker, for each position update.
        /// if you are using your own position tracker with this trailing stop(eg from offset tracker, or somewhere else)
        /// you MUST call TrailTrackers Adjust and NOT call your position tracker's adjust
        /// </summary>
        /// <param name="fill"></param>
        public void Adjust(Trade fill)
        {
            // get index for symbol
            int idx = symidx(fill.symbol);

            // only do following if we're tracking trail for this symbol
            if (idx != NOSYM)
            {
                // get current position size
                int psize = _pt[fill.symbol].UnsignedSize;
                // get trailing information
                OffsetInfo trail = _trail[idx];
                // get actual position size after change
                int asize = psize - fill.UnsignedSize;
                // if expected and actual match, mark pending as false
                if (esize[idx] == asize)
                {
                    D(fill.symbol + " trailing stop completely filled with: " + fill.ToString());
                    _pendingfill[idx] = false;
                }
                else
                {
                    v(fill.symbol + " trail partial fill: " + fill.ToString() + " e: " + esize[idx] + " != a: " + asize);
                }
            }
            else
            {
                v(fill.symbol + " fill: " + fill.ToString() + " ignored while trail disabled.");
            }

            _pt.Adjust(fill);
            // if we're flat now, make sure ref price is reset
            if (_pt[fill.symbol].isFlat)
            {
                _ref[idx] = 0;
                v(fill.symbol + " flat, reset trail reference price.");
            }
        }
Example #10
0
 /// <summary>
 /// get a stop order for a position given offset information
 /// </summary>
 /// <param name="p"></param>
 /// <param name="offset"></param>
 /// <returns></returns>
 public static Order PositionStop(Position p, OffsetInfo offset)
 {
     return PositionStop(p, offset.StopDist, offset.StopPercent, offset.NormalizeSize,offset.MinimumLotSize);
 }
Example #11
0
 /// <summary>
 /// get profit order for given position given offset information
 /// </summary>
 /// <param name="p"></param>
 /// <param name="offset"></param>
 /// <returns></returns>
 public static Order PositionProfit(Position p, OffsetInfo offset)
 {
     return PositionProfit(p, offset.ProfitDist, offset.ProfitPercent,offset.NormalizeSize,offset.MinimumLotSize);
 }
Example #12
0
 /// <summary>
 /// copy an existing offset to this one
 /// </summary>
 /// <param name="copy"></param>
 public OffsetInfo(OffsetInfo copy) : this(copy.ProfitDist, copy.StopDist, copy.ProfitPercent, copy.StopPercent, copy.NormalizeSize, copy.MinimumLotSize) { }
Example #13
0
 void SetOffset(string sym, OffsetInfo off)
 {
     OffsetInfo v;
     if (_offvals.TryGetValue(sym, out v))
         _offvals[sym] = off;
     else
         _offvals.Add(sym, off);
 }
Example #14
0
 void cancel(OffsetInfo offset) { cancel(offset.ProfitId); cancel(offset.StopId); }
Example #15
0
        public void TrailStartedAfterFirePoint()
        {
            // setup trail tracker
            TrailTracker tt = new TrailTracker();
            tt.isValid = true;
            const string acct = "DEFAULT";
            tt.pt.DefaultAccount = acct;
            tt.SendOrder += new OrderDelegate(tt_SendOrder);
            //tt.SendDebug += new DebugFullDelegate(tt_SendDebug);
            // set 15c trailing stop
            tt.DefaultTrail = new OffsetInfo(0, .15m);
            // verify it's set
            Assert.AreEqual(.15m, tt.DefaultTrail.StopDist);
            //
            tt.TrailByDefault = true;
            // put in a position to track
            tt.Adjust(new PositionImpl(SYM, 11.00m, 100, 0m,acct));
            // check position in tt-pt
            Assert.AreEqual(1, tt.pt.Count);
            // manually enter a trail
            tt[SYM] = new OffsetInfo(0m, .25m);
            // check if trail entered for symbol
            Assert.AreEqual(.25m, tt[SYM].StopDist);

            // get feed
            Tick[] tape = SampleData();
            // test broker
            Broker b = new Broker();
            // get fills over to trail tracker
            b.GotFill += new FillDelegate(tt.Adjust);
            // get orders from trail tracker
            tt.SendOrder += new OrderDelegate(b.SendOrder);
            // no orders to start
            oc = 0;
            // iterate through feed
            for (int i = 0; i < tape.Length; i++)
            {
                Tick k = tape[i];
                // set a date and time
                k.date = 20070926;
                k.time = 95500;
                // execute orders, nothing to do on first two ticks
                b.Execute(k);
                // pass every tick to tracker
                tt.newTick(k);

            }

            Assert.AreEqual(1, oc);
        }
Example #16
0
        /// <summary>
        /// pass arbitrary price to use for trail reference price
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="p"></param>
        public void newPoint(string symbol, decimal p)
        {
            // get index for symbol
            int idx = symidx(symbol);
            // setup parameters
            OffsetInfo trail = null;
            decimal refp = 0;
            // see if we trail this symbol
            if ((idx == NOSYM) && _trailbydefault)
            {
                // get parameters
                idx = _trail.Count;
                refp = p;
                trail = new OffsetInfo(_defaulttrail);
                // save them
                _symidx.Add(symbol, idx);
                _ref.Add(refp);
                _pendingfill.Add(false);
                // just in case user is modifying on seperate thread
                lock (_trail)
                {
                    _trail.Add(trail);
                }
                D("trail tracking: " + symbol + " " + trail.ToString());
            }
            else if ((idx == NOSYM) && !_trailbydefault)
                return;
            else
            {
                // get parameters
                refp = _ref[idx];
                // in case tracker started after trail stop should have been broken.
                if (refp == 0 && _pt[symbol].isValid)
                {
                    refp = _pt[symbol].AvgPrice;
                }
                // just in case user tries to modify on seperate thread
                lock (_trail)
                {
                    trail = _trail[idx];
                }
            }

            // see if we need to update ref price
            if ((refp == 0)
                || (_pt[symbol].isLong && (refp < p))
                || (_pt[symbol].isShort && (refp > p)))
            {
                // update
                refp = p;
                // save it
                _ref[idx] = refp;
            }

            // see if we broke our trail
            if (!_pendingfill[idx] && (trail.StopDist!=0) && (Math.Abs(refp - p) > trail.StopDist))
            {
                // notify
                D("hit trailing stop at: " + p.ToString("F2"));
                // mark pending order
                _pendingfill[idx] = true;
                // get order
                Order flat = new MarketOrderFlat(_pt[symbol], trail.StopPercent, trail.NormalizeSize, trail.MinimumLotSize);
                // get order id
                flat.id = _id.AssignId;
                // send flat order
                SendOrder(flat);
                // notify
                D("enforcing trail with: " + flat.ToString());
                if (HitOffset != null)
                    HitOffset(symbol, flat.id,p);
            }





        }
Example #17
0
 public static Order PositionStop(Position p, OffsetInfo offset)
 {
     return(PositionStop(p, offset.ProfitDist, offset.ProfitPercent));
 }
Example #18
0
        /// <summary>
        /// must pass ticks as received to this function, in order to have trailing stops executed at proper time.
        /// </summary>
        /// <param name="k"></param>
        public void GotTick(Tick k)
        {
            // see if we're turned on
            if (!isValid) return;
            // see if we can exit when trail is broken
            if (SendOrder == null) return;
            // see if we have anything to trail against
            if (_pt[k.symbol].isFlat) return;
            // only care about trades
            if (!k.isTrade) return;
            // get index for symbol
            int idx = symidx(k.symbol);
            // setup parameters
            OffsetInfo trail = null;
            decimal refp = 0;
            // see if we trail this symbol
            if ((idx == NOSYM) && _trailbydefault)
            {
                // get parameters
                idx = _trail.Count;
                refp = k.trade;
                trail = new OffsetInfo(_defaulttrail);
                // save them
                _symidx.Add(k.symbol, idx);
                _ref.Add(refp);
                // just in case user is modifying on seperate thread
                lock (_trail)
                {
                    _trail.Add(trail);
                }
            }
            else if ((idx == NOSYM) && !_trailbydefault)
                return;
            else
            {
                // get parameters
                refp = _ref[idx];
                // just in case user tries to modify on seperate thread
                lock (_trail)
                {
                    trail = _trail[idx];
                }
            }

            // see if we need to update ref price
            if ((refp == 0)
                || (_pt[k.symbol].isLong && (refp < k.trade))
                || (_pt[k.symbol].isShort && (refp > k.trade)))
            {
                // update
                refp = k.trade;
                // save it
                _ref[idx] = refp;
            }

            // see if we broke our trail
            if (Math.Abs(refp - k.trade) > trail.StopDist)
            {
                // send flat order
                SendOrder(new MarketOrderFlat(_pt[k.symbol], trail.StopPercent, trail.NormalizeSize, trail.MinimumLotSize));
            }





        }
Example #19
0
        /// <summary>
        /// must pass ticks as received to this function, in order to have trailing stops executed at proper time.
        /// </summary>
        /// <param name="k"></param>
        public void GotTick(Tick k)
        {
            // see if we're turned on
            if (!isValid)
            {
                return;
            }
            // see if we can exit when trail is broken
            if (SendOrder == null)
            {
                return;
            }
            // see if we have anything to trail against
            if (_pt[k.symbol].isFlat)
            {
                return;
            }
            // only care about trades
            if (!k.isTrade)
            {
                return;
            }
            // get index for symbol
            int idx = symidx(k.symbol);
            // setup parameters
            OffsetInfo trail = null;
            decimal    refp  = 0;

            // see if we trail this symbol
            if ((idx == NOSYM) && _trailbydefault)
            {
                // get parameters
                idx   = _trail.Count;
                refp  = k.trade;
                trail = new OffsetInfo(_defaulttrail);
                // save them
                _symidx.Add(k.symbol, idx);
                _ref.Add(refp);
                _pendingfill.Add(false);
                // just in case user is modifying on seperate thread
                lock (_trail)
                {
                    _trail.Add(trail);
                }
                D("trail tracking: " + k.symbol + " " + trail.ToString());
            }
            else if ((idx == NOSYM) && !_trailbydefault)
            {
                return;
            }
            else
            {
                // get parameters
                refp = _ref[idx];
                // just in case user tries to modify on seperate thread
                lock (_trail)
                {
                    trail = _trail[idx];
                }
            }

            // see if we need to update ref price
            if ((refp == 0) ||
                (_pt[k.symbol].isLong && (refp < k.trade)) ||
                (_pt[k.symbol].isShort && (refp > k.trade)))
            {
                // update
                refp = k.trade;
                // save it
                _ref[idx] = refp;
            }

            // see if we broke our trail
            if (!_pendingfill[idx] && (trail.StopDist != 0) && (Math.Abs(refp - k.trade) > trail.StopDist))
            {
                // notify
                D("hit trailing stop at: " + k.trade.ToString("n2"));
                // mark pending order
                _pendingfill[idx] = true;
                // get order
                Order flat = new MarketOrderFlat(_pt[k.symbol], trail.StopPercent, trail.NormalizeSize, trail.MinimumLotSize);
                // get order id
                flat.id = _id.AssignId;
                // send flat order
                SendOrder(flat);
                // notify
                D("enforcing trail with: " + flat.ToString());
            }
        }
Example #20
0
        /// <summary>
        /// pass arbitrary price to use for trail reference price
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="p"></param>
        public void newPoint(string symbol, decimal p)
        {
            // get index for symbol
            int idx = symidx(symbol);
            // setup parameters
            OffsetInfo trail = null;
            decimal    refp  = 0;

            // see if we trail this symbol
            if ((idx == NOSYM) && _trailbydefault)
            {
                // get parameters
                idx   = _trail.Count;
                refp  = p;
                trail = new OffsetInfo(_defaulttrail);
                // save them
                _symidx.Add(symbol, idx);
                _ref.Add(refp);
                _pendingfill.Add(false);
                // just in case user is modifying on seperate thread
                lock (_trail)
                {
                    _trail.Add(trail);
                }
                D("trail tracking: " + symbol + " " + trail.ToString());
            }
            else if ((idx == NOSYM) && !_trailbydefault)
            {
                return;
            }
            else
            {
                // get parameters
                refp = _ref[idx];
                // in case tracker started after trail stop should have been broken.
                if (refp == 0 && _pt[symbol].isValid)
                {
                    refp = _pt[symbol].AvgPrice;
                }
                // just in case user tries to modify on seperate thread
                lock (_trail)
                {
                    trail = _trail[idx];
                }
            }

            // see if we need to update ref price
            if ((refp == 0) ||
                (_pt[symbol].isLong && (refp < p)) ||
                (_pt[symbol].isShort && (refp > p)))
            {
                // update
                refp = p;
                // save it
                _ref[idx] = refp;
            }

            // see if we broke our trail
            if (!_pendingfill[idx] && (trail.StopDist != 0) && (Math.Abs(refp - p) > trail.StopDist))
            {
                // notify
                D("hit trailing stop at: " + p.ToString("F2"));
                // mark pending order
                _pendingfill[idx] = true;
                // get order
                Order flat = new MarketOrderFlat(_pt[symbol], trail.StopPercent, trail.NormalizeSize, trail.MinimumLotSize);
                // get order id
                flat.id = _id.AssignId;
                // send flat order
                SendOrder(flat);
                // notify
                D("enforcing trail with: " + flat.ToString());
                if (HitOffset != null)
                {
                    HitOffset(symbol, flat.id, p);
                }
            }
        }
Example #21
0
        /// <summary>
        /// pass arbitrary price to use for trail reference price
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="p"></param>
        public void newPoint(string symbol, decimal p)
        {
            // get index for symbol
            int idx = symidx(symbol);
            // setup parameters
            OffsetInfo trail = null;
            decimal refp = 0;
            // see if we trail this symbol
            if ((idx == NOSYM) && _trailbydefault)
            {
                // get parameters
                idx = _trail.Count;
                refp = p;
                trail = new OffsetInfo(_defaulttrail);
                // save them
                _symidx.Add(symbol, idx);
                _ref.Add(refp);
                _pendingfill.Add(false);
                firecount.addindex(symbol, 0);
                esize.addindex(symbol,pt[symbol].UnsignedSize);
                // just in case user is modifying on seperate thread
                lock (_trail)
                {
                    _trail.Add(trail);
                }
                D(symbol+" trail tracking modified: "+trail.ToString());
            }
            else if ((idx == NOSYM) && !_trailbydefault)
            {
                return;
            }
            else
            {
                // get parameters
                refp = _ref[idx];
                // in case tracker started after trail stop should have been broken.
                if (refp == 0 && _pt[symbol].isValid)
                {
                    refp = _pt[symbol].AvgPrice;
                }
                // just in case user tries to modify on seperate thread
                lock (_trail)
                {
                    trail = _trail[idx];
                }
            }

            // see if we need to update ref price
            if ((refp == 0)
                || (_pt[symbol].isLong && (refp < p))
                || (_pt[symbol].isShort && (refp > p)))
            {
                // update
                refp = p;
                // save it
                _ref[idx] = refp;
                // notify
                v(symbol + " new reference price: " + p);
            }

            // see if we broke our trail
            var testdist = Math.Abs(refp - p);
            var trailtest = testdist> trail.StopDist;
            if (!_pendingfill[idx] && (trail.StopDist!=0) && trailtest && (MaxFireCount>firecount[idx]))
            {
                // notify
                D(symbol+" hit trailing stop at: " + p.ToString("F2"));
                // mark pending order
                _pendingfill[idx] = true;
                // get order
                Order flat = new MarketOrderFlat(_pt[symbol], trail.StopPercent, trail.NormalizeSize, trail.MinimumLotSize);
                // get order id
                flat.id = _id.AssignId;
                // adjust expectation
                esize[idx] -= flat.UnsignedSize;
                // count fire
                firecount[idx]++;
                // send flat order
                SendOrder(flat);
                // notify
                D(symbol+" enforcing trail with: " + flat.ToString()+" esize: "+esize[idx]+" count: "+firecount[idx]);
                if (HitOffset != null)
                    HitOffset(symbol, flat.id,p);
            }
            else if (!_noverb)
            {
                if (_pendingfill[idx])
                    v(symbol + " waiting for trail fill.");
                else if (trail.StopDist == 0)
                    v(symbol + " trail has been disabled.");
                else if (!trailtest)
                {
                    v(symbol + " trail not hit, current dist: " + testdist + " trailamt: " + trail.StopDist);
                }
                else if (MaxFireCount > firecount[idx])
                {
                    v(symbol + " trail max fire reached at: " + firecount[idx] + " max: " + MaxFireCount);
                }
            }





        }
Example #22
0
 void cancel(OffsetInfo offset)
 {
     cancel(offset.ProfitId); cancel(offset.StopId);
 }
Example #23
0
        /// <summary>
        /// pass arbitrary price to use for trail reference price
        /// </summary>
        /// <param name="symbol"></param>
        /// <param name="p"></param>
        public void newPoint(string symbol, decimal p)
        {
            // get index for symbol
            int idx = symidx(symbol);
            // setup parameters
            OffsetInfo trail = null;
            decimal    refp  = 0;

            // see if we trail this symbol
            if ((idx == NOSYM) && _trailbydefault)
            {
                // get parameters
                idx   = _trail.Count;
                refp  = p;
                trail = new OffsetInfo(_defaulttrail);
                // save them
                _symidx.Add(symbol, idx);
                _ref.Add(refp);
                _pendingfill.Add(false);
                firecount.addindex(symbol, 0);
                esize.addindex(symbol, pt[symbol].UnsignedSize);
                // just in case user is modifying on seperate thread
                lock (_trail)
                {
                    _trail.Add(trail);
                }
                D(symbol + " trail tracking modified: " + trail.ToString());
            }
            else if ((idx == NOSYM) && !_trailbydefault)
            {
                return;
            }
            else
            {
                // get parameters
                refp = _ref[idx];
                // in case tracker started after trail stop should have been broken.
                if (refp == 0 && _pt[symbol].isValid)
                {
                    refp = _pt[symbol].AvgPrice;
                }
                // just in case user tries to modify on seperate thread
                lock (_trail)
                {
                    trail = _trail[idx];
                }
            }

            // see if we need to update ref price
            if ((refp == 0) ||
                (_pt[symbol].isLong && (refp < p)) ||
                (_pt[symbol].isShort && (refp > p)))
            {
                // update
                refp = p;
                // save it
                _ref[idx] = refp;
                // notify
                v(symbol + " new reference price: " + p);
            }

            // see if we broke our trail
            var testdist  = Math.Abs(refp - p);
            var trailtest = testdist > trail.StopDist;

            if (!_pendingfill[idx] && (trail.StopDist != 0) && trailtest && (MaxFireCount > firecount[idx]))
            {
                // notify
                D(symbol + " hit trailing stop at: " + p.ToString("F2"));
                // mark pending order
                _pendingfill[idx] = true;
                // get order
                Order flat = new MarketOrderFlat(_pt[symbol], trail.StopPercent, trail.NormalizeSize, trail.MinimumLotSize);
                // get order id
                flat.id = _id.AssignId;
                // adjust expectation
                esize[idx] -= flat.UnsignedSize;
                // count fire
                firecount[idx]++;
                // send flat order
                SendOrder(flat);
                // notify
                D(symbol + " enforcing trail with: " + flat.ToString() + " esize: " + esize[idx] + " count: " + firecount[idx]);
                if (HitOffset != null)
                {
                    HitOffset(symbol, flat.id, p);
                }
            }
            else if (!_noverb)
            {
                if (_pendingfill[idx])
                {
                    v(symbol + " waiting for trail fill.");
                }
                else if (trail.StopDist == 0)
                {
                    v(symbol + " trail has been disabled.");
                }
                else if (!trailtest)
                {
                    v(symbol + " trail not hit, current dist: " + testdist + " trailamt: " + trail.StopDist);
                }
                else if (MaxFireCount > firecount[idx])
                {
                    v(symbol + " trail max fire reached at: " + firecount[idx] + " max: " + MaxFireCount);
                }
            }
        }
Example #24
0
 /// <summary>
 /// copy an existing offset to this one
 /// </summary>
 /// <param name="copy"></param>
 public OffsetInfo(OffsetInfo copy) : this(copy.ProfitDist, copy.StopDist, copy.ProfitPercent, copy.StopPercent, copy.NormalizeSize, copy.MinimumLotSize)
 {
 }
Example #25
0
        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);

            // if we're up to date then quit
            if (off.isOffsetCurrent(_pt[sym]))
            {
                return;
            }
            // see if we have profit
            if (off.hasProfit)
            {
                // 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;
            }
            // see if we have stop
            if (off.hasStop)
            {
                // 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;
            }

            // wait till next tick if we sent cancel
            if (sentcancel)
            {
                return;
            }

            if (!off.hasProfit)
            {
                // since we have no stop, it's cancel can't be pending
                off.ProfitcancelPending = false;
                // get new profit
                Order profit = Calc.PositionProfit(_pt[sym], 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;
                    SendOffset(profit);
                    // notify
                    debug(string.Format("sent new profit: {0} {1}", profit.id, profit.ToString()));
                }
            }
            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(_pt[sym], 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;
                    SendOffset(stop);
                    // notify
                    debug(string.Format("sent new stop: {0} {1}", stop.id, stop.ToString()));
                }
            }
            // make sure new offset info is reflected
            SetOffset(sym, off);
        }
Example #26
0
 public static Order PositionStop(Position p, OffsetInfo offset) { return PositionStop(p, offset.ProfitDist, offset.ProfitPercent); }
Example #27
0
        /// <summary>
        /// must pass ticks as received to this function, in order to have trailing stops executed at proper time.
        /// </summary>
        /// <param name="k"></param>
        public void GotTick(Tick k)
        {
            // see if we're turned on
            if (!isValid) return;
            // see if we can exit when trail is broken
            if (SendOrder == null) return;
            // see if we have anything to trail against
            if (_pt[k.symbol].isFlat) return;
            // only care about trades
            if (!k.isTrade) return;
            // get index for symbol
            int idx = symidx(k.symbol);
            // setup parameters
            OffsetInfo trail = null;
            decimal refp = 0;
            // see if we trail this symbol
            if ((idx == NOSYM) && _trailbydefault)
            {
                // get parameters
                idx = _trail.Count;
                refp = k.trade;
                trail = new OffsetInfo(_defaulttrail);
                // save them
                _symidx.Add(k.symbol, idx);
                _ref.Add(refp);
                _pendingfill.Add(false);
                // just in case user is modifying on seperate thread
                lock (_trail)
                {
                    _trail.Add(trail);
                }
                D("trail tracking: " + k.symbol + " " + trail.ToString());
            }
            else if ((idx == NOSYM) && !_trailbydefault)
                return;
            else
            {
                // get parameters
                refp = _ref[idx];
                // just in case user tries to modify on seperate thread
                lock (_trail)
                {
                    trail = _trail[idx];
                }
            }

            // see if we need to update ref price
            if ((refp == 0)
                || (_pt[k.symbol].isLong && (refp < k.trade))
                || (_pt[k.symbol].isShort && (refp > k.trade)))
            {
                // update
                refp = k.trade;
                // save it
                _ref[idx] = refp;
            }

            // see if we broke our trail
            if (!_pendingfill[idx] && (trail.StopDist!=0) && (Math.Abs(refp - k.trade) > trail.StopDist))
            {
                // notify
                D("hit trailing stop at: " + k.trade.ToString("n2"));
                // mark pending order
                _pendingfill[idx] = true;
                // get order
                Order flat = new MarketOrderFlat(_pt[k.symbol], trail.StopPercent, trail.NormalizeSize, trail.MinimumLotSize);
                // get order id
                flat.id = _id.AssignId;
                // send flat order
                SendOrder(flat);
                // notify
                D("enforcing trail with: " + flat.ToString());
            }





        }