public void Update(StockAnalysis.Share.Bar bar) { double price = BarPriceSelector.Select(bar, _priceSelector); _highest.Update(price); double newHighest = _highest.Value; bool oldBreakout = Breakout; Breakout = Math.Abs(newHighest - price) < 1e-6; CurrentHighest = newHighest; if (Breakout) { // rebreakout is always breakout if (oldBreakout) { // continuous breakout is not rebreakout Rebreakout = false; _intervalSinceLastBreakout = 0; } else { // possible a rebreakout. if (_intervalSinceLastBreakout > 0 && _intervalSinceLastBreakout <= _maxInterval && _intervalSinceLastBreakout >= _minInterval) { Rebreakout = true; IntervalSinceLastBreakout = _intervalSinceLastBreakout; _intervalSinceLastBreakout = 0; } else { Rebreakout = false; _intervalSinceLastBreakout = 0; } } } else { // rebreakout is always breakout Rebreakout = false; if (oldBreakout) { _intervalSinceLastBreakout = 1; } else { if (_intervalSinceLastBreakout > 0) { _intervalSinceLastBreakout++; } } } }
public override MarketExitingComponentResult ShouldExit(ITradingObject tradingObject) { var result = new MarketExitingComponentResult(); if (Context.ExistsPosition(tradingObject.Code)) { var position = Context.GetPositionDetails(tradingObject.Code).First(); if (position.LastedPeriodCount >= MinKeepPeriods) { var bar = Context.GetBarOfTradingObjectForCurrentPeriod(tradingObject); var price = BarPriceSelector.Select(bar, PriceSelector); if (position.BuyPrice < price) { result.Comments = string.Format("Bailout: buy price {0:0.000}, current price {1:0.000}", position.BuyPrice, price); result.ShouldExit = true; } } } return(result); }
private void UpdateState(Bar bar) { double price = BarPriceSelector.Select(bar, _priceSelector); _highest.Update(price); double highestPrice = _highest.Value; bool breakout = Math.Abs(highestPrice - price) < 1e-6; switch (_state) { case PriceState.Initial: if (breakout) { _state = PriceState.Breakout; LatestBreakoutPrice = highestPrice; LowestPriceAfterBreakout = 0.0; _intervalBetweenLastBreakoutAndRerising = 0; } break; case PriceState.Breakout: if (breakout) { LatestBreakoutPrice = highestPrice; } else { _state = PriceState.Degrading; LowestPriceAfterBreakout = bar.ClosePrice; _intervalBetweenLastBreakoutAndRerising = 1; } break; case PriceState.Degrading: if (bar.ClosePrice <= LowestPriceAfterBreakout) { LowestPriceAfterBreakout = bar.ClosePrice; _intervalBetweenLastBreakoutAndRerising++; } else { if (_intervalBetweenLastBreakoutAndRerising >= _minInterval && _intervalBetweenLastBreakoutAndRerising <= _maxInterval) { _state = PriceState.Rising; } else { ResetState(); } } break; case PriceState.Rising: ResetState(); break; } }