/// <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()); } }
/// <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()); } }
/// <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); } } }
/// <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); } } }
/// <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); } } }
/// <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); } }