public override MarketExitingComponentResult ShouldExit(ITradingObject tradingObject) { var result = new MarketExitingComponentResult(); var code = tradingObject.Code; if (Context.ExistsPosition(code)) { int periodCount = Context.GetPositionDetails(code).Last().LastedPeriodCount; if (periodCount >= HoldingPeriods) { var todayBar = Context.GetBarOfTradingObjectForCurrentPeriod(tradingObject); var previousBar = _referenceBar.GetMetricValues(tradingObject); var previousOpen = previousBar[1]; var previousClose = previousBar[0]; if (todayBar.OpenPrice < previousClose || todayBar.ClosePrice < previousClose || todayBar.ClosePrice < todayBar.OpenPrice) { result.Comments = string.Format( "hold for {0} periods and no jump up and rise. today open {1:0.000}, today close {2:0.000} previous close {3:0.000}", HoldingPeriods, todayBar.OpenPrice, todayBar.ClosePrice, previousClose); result.ShouldExit = true; } } } return(result); }
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 == 1) { var yesterdayBar = _yesterdayBarProxy.GetMetricValues(tradingObject); var yesterDayClosePrice = yesterdayBar[0]; var yesterDayOpenPrice = yesterdayBar[1]; var todayBar = Context.GetBarOfTradingObjectForCurrentPeriod(tradingObject); if (todayBar.ClosePrice < todayBar.OpenPrice && yesterDayClosePrice < yesterDayOpenPrice) { var lossPercentage = (todayBar.ClosePrice - yesterDayOpenPrice) / yesterDayOpenPrice * 100.0; if (lossPercentage < -MinLossPercentage) { result.Comments = string.Format("Continue 2 days loss: today close price {0:0.000}, yesterday open price {1:0.000}", todayBar.ClosePrice, yesterDayOpenPrice); result.Price = new TradingPrice(ExitingPeriod, ExitingPriceOption, ExitingCustomPrice); result.ShouldExit = true; } } } } return(result); }
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 == 1) { var firstDayBar = _firstDayBarProxy.GetMetricValues(tradingObject); var theDayBeforeFirstDayBar = _theDayBeforeFirstDayBarProxy.GetMetricValues(tradingObject); var firstDayClosePrice = firstDayBar[0]; var theDayBeforeFirstDayClosePrice = theDayBeforeFirstDayBar[0]; var lossPercentage = (firstDayClosePrice - position.BuyPrice) / position.BuyPrice * 100.0; var lossPercentageToPreviousDay = (firstDayClosePrice - theDayBeforeFirstDayClosePrice) / theDayBeforeFirstDayClosePrice * 100.0; if (lossPercentage < -MinLossPercentage || lossPercentageToPreviousDay < -MinLossPercentageToPreviousDayClose) { result.Comments = string.Format("Loss: buy price {0:0.000}, close price {1:0.000}, prev close price {2:0.000}", position.BuyPrice, firstDayClosePrice, theDayBeforeFirstDayClosePrice); result.Price = new TradingPrice(ExitingPeriod, ExitingPriceOption, ExitingCustomPrice); result.ShouldExit = true; } } } return(result); }
public override MarketExitingComponentResult ShouldExit(ITradingObject tradingObject) { var result = new MarketExitingComponentResult(); var code = tradingObject.Code; if (Context.ExistsPosition(code)) { Bar todayBar = Context.GetBarOfTradingObjectForCurrentPeriod(tradingObject); if (_codesSwitchedToSingleMovingAverageMarketExiting.Contains(code)) { double movingAverage = _movingAverageMetricProxy.GetMetricValues(tradingObject)[0]; if (todayBar.ClosePrice < movingAverage) { result.ShouldExit = true; result.Comments = string.Format( "Close price {0:0.000} < MA[{1}]({2:0.000})", todayBar.ClosePrice, MovingAveragePeriods, movingAverage); result.Price = new TradingPrice( TradingPricePeriod.CurrentPeriod, TradingPriceOption.ClosePrice, 0.0); } } else { int periodCount = Context.GetPositionDetails(code).Last().LastedPeriodCount; if (periodCount >= HoldingPeriods) { var highestIndex = _highestMetricProxy.GetMetricValues(tradingObject)[1]; if (periodCount == HoldingPeriods && (int)highestIndex == HighestLookbackPeriods - 1 && todayBar.ClosePrice >= todayBar.OpenPrice) { // today is the highest price, switch to moving average exiting. _codesSwitchedToSingleMovingAverageMarketExiting.Add(code); } else { result.Comments = string.Format("hold for {0} periods", HoldingPeriods); result.ShouldExit = true; } } } } else { _codesSwitchedToSingleMovingAverageMarketExiting.Remove(code); } return(result); }
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 == 1) { var firstDayBar = _firstDayBarProxy.GetMetricValues(tradingObject); var firstDayClosePrice = firstDayBar[0]; var firstDayOpenPrice = firstDayBar[1]; var firstDayMinPrice = Math.Min(firstDayOpenPrice, firstDayClosePrice); var secondDayBar = Context.GetBarOfTradingObjectForCurrentPeriod(tradingObject); var lossPercentage = (secondDayBar.ClosePrice - secondDayBar.OpenPrice) / secondDayBar.OpenPrice * 100.0; var lossPercentageOpenToFirstDayMin = (secondDayBar.OpenPrice - firstDayMinPrice) / firstDayMinPrice * 100.0; var lossPercentageCloseToFirstDayMin = (secondDayBar.ClosePrice - firstDayMinPrice) / firstDayMinPrice * 100.0; if (lossPercentageOpenToFirstDayMin < -MinLossPercentageOpenToFirstDayMin) { result.Comments = string.Format("2nd day loss: today open price {0:0.000}, first day min price {1:0.000}", secondDayBar.OpenPrice, firstDayMinPrice); result.Price = new TradingPrice(TradingPricePeriod.CurrentPeriod, TradingPriceOption.OpenPrice, 0.0); result.ShouldExit = true; } else if (lossPercentage < -MinLossPercentage) { result.Comments = string.Format("2nd day loss: today open price {0:0.000}, close price {1:0.000}", secondDayBar.OpenPrice, secondDayBar.ClosePrice); result.Price = new TradingPrice(ExitingPeriod, ExitingPriceOption, ExitingCustomPrice); result.ShouldExit = true; } else if (lossPercentageCloseToFirstDayMin < -MinLossPercentageCloseToFirstDayMin) { result.Comments = string.Format("2nd day loss: today close price {0:0.000}, first day min price {1:0.000}", secondDayBar.ClosePrice, firstDayMinPrice); result.Price = new TradingPrice(ExitingPeriod, ExitingPriceOption, ExitingCustomPrice); result.ShouldExit = true; } } } return(result); }
public override MarketExitingComponentResult ShouldExit(ITradingObject tradingObject) { MarketExitingComponentResult result = new MarketExitingComponentResult(); if (!Context.ExistsPosition(tradingObject.Code)) { return(result); } Position position = Context.GetPositionDetails(tradingObject.Code).First(); if (position.LastedPeriodCount < GrowthCalculationWindow - 1) { return(result); } ITradingObject boardIndexObject = Context.GetBoardIndexTradingObject(tradingObject); var growth = _growthProxy.GetMetricValues(tradingObject)[0]; var values = _growthProxy.GetMetricValues(boardIndexObject); if (values == null) { values = _growthProxy.GetMetricValues(Context.GetBoardIndexTradingObject(StockBoard.MainBoard)); } var boardIndexGrowth = values[0]; if (growth < boardIndexGrowth) { result.ShouldExit = true; result.Comments = string.Format("Growth {0:0.0000} < board index growth {1:0.0000}", growth, boardIndexGrowth); if (position.LastedPeriodCount < Context.GetPositionFrozenDays()) { result.Price = new TradingPrice(TradingPricePeriod.NextPeriod, TradingPriceOption.OpenPrice, 0.0); } else { result.Price = new TradingPrice(TradingPricePeriod.CurrentPeriod, TradingPriceOption.ClosePrice, 0.0); } } return(result); }
public override MarketExitingComponentResult ShouldExit(ITradingObject tradingObject) { var result = new MarketExitingComponentResult(); if (_holdingPeriods.Length != 0) { int period; if (_codesShouldExit.TryGetValue(tradingObject.Index, out period)) { _codesShouldExit.Remove(tradingObject.Index); result.Comments = string.Format("hold for {0} periods, but no profit", period); result.ShouldExit = true; } } return(result); }
public override MarketExitingComponentResult ShouldExit(ITradingObject tradingObject) { var result = new MarketExitingComponentResult(); if (!_trendDetector.HasTrend(tradingObject)) { for (int i = 0; i < _trendDetector.PeriodsCount; ++i) { result.Comments += string.Format( "MA[{0}]:{1:0.000} ", _trendDetector.GetPeriod(i), _trendDetector.GetMovingAverage(tradingObject, i)); } result.ShouldExit = true; } return(result); }
public override MarketExitingComponentResult ShouldExit(ITradingObject tradingObject) { var result = new MarketExitingComponentResult(); var code = tradingObject.Code; if (Context.ExistsPosition(code)) { int periodCount = Context.GetPositionDetails(code).Last().LastedPeriodCount; if (periodCount >= HoldingPeriods) { result.Comments = string.Format("hold for {0} periods", HoldingPeriods); result.ShouldExit = true; } } return(result); }
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); }