public double CalculateEquityUtilization(ITradingObject tradingObject) { var boardIndexTradingObject = _context.GetBoardIndexTradingObject(tradingObject); if (boardIndexTradingObject == null) { return(1.0); } var ma10values = _ma10.GetMetricValues(boardIndexTradingObject); if (ma10values == null) { // the board index value is not ready yet, back off to main board index boardIndexTradingObject = _context.GetBoardIndexTradingObject(StockBoard.MainBoard); } var closeValue = _close.GetMetricValues(boardIndexTradingObject)[0]; var ma5Value = _ma5.GetMetricValues(boardIndexTradingObject)[0]; var ma10Value = _ma10.GetMetricValues(boardIndexTradingObject)[0]; var ma20Value = _ma20.GetMetricValues(boardIndexTradingObject)[0]; var ma60Value = _ma60.GetMetricValues(boardIndexTradingObject)[0]; if (ma5Value < ma20Value) { // descending trends if (closeValue < ma5Value) { return(0.0); } else if (closeValue >= ma5Value && closeValue < ma20Value) { return(0.15); } else if (closeValue >= ma20Value) { return(0.3); } } else { // ascending trends if (closeValue >= ma5Value) { return(1.0); } else if (closeValue >= ma20Value && closeValue < ma5Value) { return(0.7); } else if (closeValue < ma20Value) { return(0.5); } } return(0.0); }
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 MarketEnteringComponentResult CanEnter(ITradingObject tradingObject) { var result = new MarketEnteringComponentResult(); var longSlope = _longMetricProxy.GetMetricValues(tradingObject)[0]; var longDegree = Math.Atan(longSlope) * 180.0 / Math.PI; var middleSlope = _middleMetricProxy.GetMetricValues(tradingObject)[0]; var middleDegree = Math.Atan(middleSlope) * 180.0 / Math.PI; var shortSlope = _shortMetricProxy.GetMetricValues(tradingObject)[0]; var shortDegree = Math.Atan(shortSlope) * 180.0 / Math.PI; if (longDegree > LongDegreeThreshold && middleDegree > MiddleDegreeThreshold && shortDegree > ShortDegreeThreshold) { result.Comments = string.Format( "LR Degree: L{0:0.000}, M{1:0.000}, S{2:0.000}", longDegree, middleDegree, shortDegree); result.CanEnter = 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) { 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 MarketEnteringComponentResult CanEnter(ITradingObject tradingObject) { var result = new MarketEnteringComponentResult(); var previousDayBarValues = _previousDayBar.GetMetricValues(tradingObject); var todayBar = Context.GetBarOfTradingObjectForCurrentPeriod(tradingObject); double movingAverage = _movingAverage == null ? 1000000.00 : _movingAverage.GetMetricValues(tradingObject)[0]; var previousDayBarLowest = previousDayBarValues[3]; var previousDayBarClose = previousDayBarValues[0]; if (previousDayBarClose < movingAverage * (100.0 - MinPercentageBelowMovingAverage) / 100.0 && // below average todayBar.OpenPrice < previousDayBarLowest * (100.0 - MinPercentageOfGapDown) / 100.0 && // gap down todayBar.HighestPrice > previousDayBarLowest // bounce over last day lowest ) { result.Comments = string.Format( "MA[{0}]={1:0.000} Highest:{2:0.000} Open:{3:0.000} LastLowest:{4:0.000}", MovingAveragePeriod, movingAverage, todayBar.HighestPrice, todayBar.OpenPrice, previousDayBarLowest); result.CanEnter = true; result.Price = new TradingPrice(TradingPricePeriod.CurrentPeriod, TradingPriceOption.CustomPrice, previousDayBarLowest); } 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 BuyPriceFilteringComponentResult IsPriceAcceptable(ITradingObject tradingObject, double price) { var result = new BuyPriceFilteringComponentResult(price); var baseValue = _metricProxy.GetMetricValues(tradingObject)[0]; var upLimit = baseValue * PriceUpLimitPercentage / 100.0; var downLimit = baseValue * PriceDownLimitPercentage / 100.0; if (price < downLimit || price > upLimit) { result.Comments = string.Format( "Price {0:0.000} out of [{1:0.000}%..{2:0.000}%] of metric[{3}]:{4:0.000}", price, PriceDownLimitPercentage, PriceUpLimitPercentage, RawMetric, baseValue); if (price > upLimit && IsUpLimitPriceAcceptable) { result.AcceptablePrice = upLimit; result.IsPriceAcceptable = true; } else { result.IsPriceAcceptable = false; result.AcceptablePrice = double.NaN; } } return(result); }
public override MarketEnteringComponentResult CanEnter(ITradingObject tradingObject) { var result = new MarketEnteringComponentResult(); var bar = Context.GetBarOfTradingObjectForCurrentPeriod(tradingObject); var upShadowPercentage = Math.Abs(bar.LowestPrice - bar.HighestPrice) < 1e-6 ? 0.0 : (bar.HighestPrice - bar.ClosePrice) / (bar.HighestPrice - bar.LowestPrice) * 100.0; var priceChangePercentage = _priceChangeMetricProxy.GetMetricValues(tradingObject)[0]; var volumeChangePercentage = _volumeChangeMetricProxy.GetMetricValues(tradingObject)[0]; if (priceChangePercentage >= MinPriceChangePercentage && priceChangePercentage <= MaxPriceChangePercentage && volumeChangePercentage >= MinVolumeChangePercentage && volumeChangePercentage <= MaxVolumeChangePercentage && upShadowPercentage <= MaxPercentageOfUpShadow) { result.Comments = string.Format( "ROC[1]={0:0.000}% VC[{1}]={2:0.000}% UpShadow={3:0.00}%", priceChangePercentage, VolumeLookbackWindow, volumeChangePercentage, upShadowPercentage); result.CanEnter = 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) { 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 double CalculateEquityUtilization(ITradingObject tradingObject) { var boardIndexTradingObject = _context.GetBoardIndexTradingObject(tradingObject); if (boardIndexTradingObject == null) { return(1.0); } var maValues = _ma.GetMetricValues(boardIndexTradingObject); if (maValues == null) { // the board index value is not ready yet, back off to main board index boardIndexTradingObject = _context.GetBoardIndexTradingObject(StockBoard.MainBoard); } var closeValue = _close.GetMetricValues(boardIndexTradingObject)[0]; var maValue = _ma.GetMetricValues(boardIndexTradingObject)[0]; var percentage = closeValue / maValue; double utilization; //if (percentage > 1.1) //{ // utilization = 1.0 - (percentage - 1.1) * 2.0; //} //else if (percentage < 0.9) //{ // utilization = 1.0; //} //else //{ // utilization = 0.7; //} utilization = 1.0; return(Math.Max(Math.Min(utilization, 1.0), 0.1)); //var utilization = NormalDistribution(1.0, 0.1, percentage) / _normalDistribution0; //return Math.Max(utilization, 0.1); }
private IEnumerable <Instruction> SortInstructions(IEnumerable <Instruction> instructions, InstructionSortMode mode, RuntimeMetricProxy metricProxy) { switch (mode) { case InstructionSortMode.NoSorting: return(instructions); case InstructionSortMode.Randomize: var randomizedInstructions = instructions.OrderBy(instruction => _random.Next()); return(randomizedInstructions); case InstructionSortMode.SortByCodeAscending: return(instructions.OrderBy(instruction => instruction.TradingObject.Code)); case InstructionSortMode.SortByCodeDescending: return(instructions.OrderBy(instruction => instruction.TradingObject.Code).Reverse()); case InstructionSortMode.SortByInstructionIdAscending: return(instructions.OrderBy(instruction => instruction.Id)); case InstructionSortMode.SortByInstructionIdDescending: return(instructions.OrderBy(instruction => instruction.Id).Reverse()); case InstructionSortMode.SortByVolumeAscending: return(instructions.OrderBy(instruction => instruction.Volume)); case InstructionSortMode.SortByVolumeDescending: return(instructions.OrderBy(instruction => - instruction.Volume)); case InstructionSortMode.SortByMetricAscending: return(instructions.OrderBy( instruction => metricProxy.GetMetricValues(instruction.TradingObject)[0])); case InstructionSortMode.SortByMetricDescending: return(instructions.OrderBy( instruction => - metricProxy.GetMetricValues(instruction.TradingObject)[0])); default: throw new NotSupportedException(string.Format("unsupported instruction sort mode {0}", mode)); } }
protected override double CalculateStopLossPrice(ITradingObject tradingObject, double currentPrice, out string comments) { var value = _proxy.GetMetricValues(tradingObject)[0]; var stoploss = value; comments = string.Format( "Stoploss({1:0.000}) ~= {0}:{1:0.000}", Metric, stoploss); return(stoploss); }
public double ExtractValue(ITradingObject tradingObject) { if (_isConstant) { return(_constant); } else { var values = _proxy.GetMetricValues(tradingObject); return(values == null ? double.NaN : values[0]); } }
protected override double CalculateStopLossPrice(ITradingObject tradingObject, double currentPrice, out string comments) { var values = _metricProxy.GetMetricValues(tradingObject); var sar = values[0]; comments = string.Format( "stoploss = Min(Price({0:0.000}) * MaxPercentageOfPrice({1:0.000}) / 100.0, SAR({2:0.000}))", currentPrice, MaxPercentageOfPrice, sar); return(Math.Min(currentPrice * MaxPercentageOfPrice / 100.0, sar)); }
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); }
protected override double CalculateStopLossPrice(ITradingObject tradingObject, double currentPrice, out string comments) { var values = _atrMetricProxy.GetMetricValues(tradingObject); var atr = values[0]; var stoploss = currentPrice - atr * AtrStopLossFactor; comments = string.Format( "stoploss({3:0.000}) = price({2:0.000}) - ATR({0:0.000}) * AtrStopLossFactor({1:0.000})", atr, AtrStopLossFactor, currentPrice, stoploss); return(stoploss); }
public override StopLossComponentResult EstimateStopLossGap(ITradingObject tradingObject, double assumedPrice) { var value = _proxy.GetMetricValues(tradingObject)[0] * Scale; var stopLossGap = Math.Min(0.0, value - assumedPrice); var comments = string.Format( "StoplossGap({3:0.000}) ~= {0}:{1:0.000} - {2:0.000}", Metric, value, assumedPrice, stopLossGap); return(new StopLossComponentResult() { Comments = comments, StopLossGap = stopLossGap }); }
public override StopLossComponentResult EstimateStopLossGap(ITradingObject tradingObject, double assumedPrice) { var atrValues = _atrMetricProxy.GetMetricValues(tradingObject); var atr = atrValues[0]; var stoplossGap = -atr * AtrStopLossFactor; var comments = string.Format( "stoplossgap({2:0.000}) = ATR({0:0.000}) * AtrStopLossFactor({1:0.000})", atr, AtrStopLossFactor, stoplossGap); return(new StopLossComponentResult() { Comments = comments, StopLossGap = stoplossGap }); }
public override MarketEnteringComponentResult CanEnter(ITradingObject tradingObject) { var result = new MarketEnteringComponentResult(); var previousDayBarValues = _previousDayBar.GetMetricValues(tradingObject); var todayBar = Context.GetBarOfTradingObjectForCurrentPeriod(tradingObject); double movingAverage = _movingAverage == null ? 1000000.00 : _movingAverage.GetMetricValues(tradingObject)[0]; var previousDayBarLowest = previousDayBarValues[3]; var lowest = _lowest == null ? 0.0 : _lowest.GetMetricValues(tradingObject)[0]; bool isLowest = _lowest == null ? true : lowest == todayBar.LowestPrice; var upShadowPercentage = Math.Abs(todayBar.HighestPrice - todayBar.LowestPrice) < 1e-6 ? 100.0 : (todayBar.HighestPrice - todayBar.ClosePrice) / (todayBar.HighestPrice - todayBar.LowestPrice) * 100.0; var downShadowPercentage = Math.Abs(todayBar.HighestPrice - todayBar.LowestPrice) < 1e-6 ? 0.0 : (todayBar.OpenPrice - todayBar.LowestPrice) / (todayBar.HighestPrice - todayBar.LowestPrice) * 100.0; if (todayBar.ClosePrice < movingAverage * (100.0 - MinPercentageBelowMovingAverage) / 100.0 && // below average todayBar.OpenPrice < previousDayBarLowest * (100.0 - MinPercentageOfGapDown) / 100.0 && // gap down todayBar.ClosePrice > previousDayBarLowest * (100.0 + MinBouncePercentageOverLastLowestPrice) / 100.0 && // bounce over last day isLowest && // is lowest in recent bars upShadowPercentage <= MaxUpShadowPercentage && downShadowPercentage <= MaxDownShadowPercentage ) { result.Comments = string.Format( "MA[{0}]={1:0.000} Close:{2:0.000} Open:{3:0.000} LastLowest:{4:0.000} UpShadow%:{5:0.000}% DownShadow%:{6:0.000}%", MovingAveragePeriod, movingAverage, todayBar.ClosePrice, todayBar.OpenPrice, previousDayBarLowest, upShadowPercentage, downShadowPercentage); result.CanEnter = true; } return(result); }
protected override double CalculateStopLossPrice(ITradingObject tradingObject, double currentPrice, out string comments) { comments = string.Empty; if (Context.ExistsPosition(tradingObject.Code)) { var currentBar = Context.GetBarOfTradingObjectForCurrentPeriod(tradingObject); var position = Context.GetPositionDetails(tradingObject.Code).First(); if (position.LastedPeriodCount > 0) { var previousBar = _previousBarProxy.GetMetricValues(tradingObject); var previousClosePrice = previousBar[0]; var previousOpenPrice = previousBar[1]; if (previousOpenPrice > previousClosePrice) { if (position.LastedPeriodCount == 1) { comments = string.Format("Loss: previous open price {0:0.000}, prev close price {1:0.000}", previousOpenPrice, previousClosePrice); return(currentBar.OpenPrice); } //else if (position.LastedPeriodCount > 1) //{ // var twoDaysPreviousBar = _twoDaysPreviousBarProxy.GetMetricValues(tradingObject); // if (previousClosePrice < Math.Min(twoDaysPreviousBar[1], twoDaysPreviousBar[0])) // { // comments = string.Format("Loss: previous open price {0:0.000}, prev close price {1:0.000}", previousOpenPrice, previousClosePrice); // return currentBar.OpenPrice; // } //} } } } return(0.0); }
public override PositionSizingComponentResult EstimatePositionSize(ITradingObject tradingObject, double price, double stopLossGap, int totalNumberOfObjectsToBeEstimated) { var values = _atrMetricProxy.GetMetricValues(tradingObject); var volatility = values[0]; var currentEquity = Context.GetCurrentEquity(CurrentPeriod, EquityEvaluationMethod); var size = (int)(currentEquity * PercentageOfEquityForEachPositionVolatility / 100.0 / volatility); var comments = string.Format( "positionsize({3}) = CurrentEquity({0:0.000}) * PercentageOfEquityForEachPositionVolatility({1:0.000}) / 100.0 / Volatility({2:0.000})", currentEquity, PercentageOfEquityForEachPositionVolatility, volatility, size); return(new PositionSizingComponentResult() { Comments = comments, PositionSize = size }); }
private double GetBuyPriceLimit(ITradingObject tradingObject) { return(_metricProxy.GetMetricValues(tradingObject)[0]); }