public void WarmUp(ITradingObject tradingObject, StockAnalysis.Share.Bar bar) { foreach (var component in _components) { component.WarmUp(tradingObject, bar); } }
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(); 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(); if (_numberOfValidTradingObjectsInThisPeriod != 0) { var order = _sorter.LatestOrders[tradingObject.Index]; var relativeStrength = (double)(_numberOfValidTradingObjectsInThisPeriod - order) / _numberOfValidTradingObjectsInThisPeriod * 100.0; if (relativeStrength > RelativeStrengthThreshold) { result.Comments = string.Format( "RelativeStrength: {0:0.000}%", relativeStrength); result.CanEnter = true; } } return(result); }
public override PositionSizingComponentResult EstimatePositionSize(ITradingObject tradingObject, double price, double stopLossGap, int totalNumberOfObjectsToBeEstimated) { var result = new PositionSizingComponentResult(); if (totalNumberOfObjectsToBeEstimated > MaxObjectNumberToBeEstimated) { return(result); } var currentEquity = Context.GetCurrentEquity(CurrentPeriod, EquityEvaluationMethod); int parts = GetParts(totalNumberOfObjectsToBeEstimated); double totalEquityUtilization = GetDynamicEquityUtilization(tradingObject); double boardIndexUtilization = _calculator.CalculateEquityUtilization(tradingObject); double finalUtilization = totalEquityUtilization * boardIndexUtilization; result.Comments = string.Format( "positionsize = currentEquity({0:0.000}) * equityUtilization({1:0.000}) / Parts ({2}) / price({3:0.000})", currentEquity, finalUtilization, parts, price); result.PositionSize = (int)(currentEquity * finalUtilization / parts / price); return(result); }
public void UpdateMetrics(ITradingObject tradingObject, Bar bar) { if (tradingObject == null) { throw new ArgumentNullException(); } if (bar.Time == Bar.InvalidTime) { return; } unchecked { int tradingObjectIndex = tradingObject.Index; for (int metricIndex = 0; metricIndex < _metrics.Count; ++metricIndex) { var currentMetricColumn = _metrics[metricIndex]; IRuntimeMetric metric = currentMetricColumn[tradingObjectIndex]; if (metric == null) { var metricCreator = _metricCreators[metricIndex]; var metricName = _metricNames[metricIndex]; metric = metricCreator(metricName); currentMetricColumn[tradingObjectIndex] = metric; } metric.Update(bar); } } }
public CloseInstruction( DateTime submissionTime, ITradingObject tradingObject, TradingPrice price = null) : base(submissionTime, tradingObject, TradingAction.CloseLong, price) { }
public void WarmUp(ITradingObject tradingObject, Bar bar) { foreach (var component in _components) { component.WarmUp(tradingObject, bar); } }
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 string GetInstantializedExpression(ITradingObject tradingObject) { return(string.Format("({0}) {1} ({2})", _expression1.GetInstantializedExpression(tradingObject), GetOperationString(), _expression2.GetInstantializedExpression(tradingObject))); }
public override PositionSizingComponentResult EstimatePositionSize(ITradingObject tradingObject, double price, double stopLossGap, int totalNumberOfObjectsToBeEstimated) { var result = new PositionSizingComponentResult(); if (totalNumberOfObjectsToBeEstimated > MaxObjectNumberToBeEstimated) { return(result); } var currentEquity = Context.GetCurrentEquity(CurrentPeriod, EquityEvaluationMethod); var maxParts = MaxPartsOfAdpativeAllocation == 0 ? MinPartsOfAdpativeAllocation : MaxPartsOfAdpativeAllocation; int parts = PartsOfEquity == 0 ? Math.Max(Math.Min(totalNumberOfObjectsToBeEstimated, maxParts), MinPartsOfAdpativeAllocation) : PartsOfEquity; double equityUtilization = GetDynamicEquityUtilization(tradingObject); result.Comments = string.Format( "positionsize = currentEquity({0:0.000}) * equityUtilization({1:0.000}) / Parts ({2}) / price({3:0.000})", currentEquity, equityUtilization, parts, price); result.PositionSize = (int)(currentEquity * equityUtilization / parts / price); 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 string GetInstantializedExpression(ITradingObject tradingObject) { StringBuilder builder = new StringBuilder(); if (_leftValueExtractor.IsConstant) { builder.Append(_leftExpression); } else { builder.AppendFormat("{0}({1:0.000})", _leftExpression, _leftValueExtractor.ExtractValue(tradingObject)); } builder.Append(_operatorString); if (_rightValueExtractor.IsConstant) { builder.Append(_rightExpression); } else { builder.AppendFormat("{0}({1:0.000})", _rightExpression, _rightValueExtractor.ExtractValue(tradingObject)); } return(builder.ToString()); }
private void CreateIntructionForBuying(ITradingObject tradingObject, double price, string comments) { double stopLossGap = _stopLoss.EstimateStopLossGap(tradingObject, price); if (stopLossGap >= 0.0) { throw new InvalidProgramException("the stop loss gap returned by the stop loss component is greater than zero"); } int volume = _positionSizing.EstimatePositionSize(tradingObject, price, stopLossGap); // adjust volume to ensure it fit the trading object's contraint volume -= volume % tradingObject.VolumePerBuyingUnit; if (volume > 0) { _instructionsInCurrentPeriod.Add( new Instruction() { Action = TradingAction.OpenLong, Comments = comments, SubmissionTime = _period, TradingObject = tradingObject, Volume = volume }); } }
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 bool IsTrue(ITradingObject tradingObject) { return(ComparisonOperatorHelper.IsTrue( _operator, _leftValueExtractor.ExtractValue(tradingObject), _rightValueExtractor.ExtractValue(tradingObject))); }
public override PositionSizingComponentResult EstimatePositionSize(ITradingObject tradingObject, double price, double stopLossGap, int totalNumberOfObjectsToBeEstimated) { var currentEquity = Context.GetCurrentEquity(CurrentPeriod, EquityEvaluationMethod); var result = new PositionSizingComponentResult(); if (Math.Abs(stopLossGap) < 1e-6) { result.Comments = "positionsize = 0 because stopLossGap is too small"; result.PositionSize = 0; } else { var size = (int)(currentEquity * PercentageOfEquityForEachRisk / 100.0 / Math.Abs(stopLossGap)); result.Comments = string.Format( "positionsize({3}) = CurrentEquity({0:0.000}) * PercentageOfEquityForEachRisk({1:0.000}) / 100.0 / Risk({2:0.000})", currentEquity, PercentageOfEquityForEachRisk, Math.Abs(stopLossGap), size); result.PositionSize = size; } 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(); 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(); 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) { return(new MarketExitingComponentResult() { Comments = string.Empty, ShouldExit = false }); }
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 MarketEnteringComponentResult CanEnter(ITradingObject tradingObject) { var result = new MarketEnteringComponentResult(); if (Context.RelationshipManager == null) { result.CanEnter = true; return(result); } var blocks = Context.RelationshipManager.GetBlocksForStock(tradingObject.Code); // if the stock's blocks has no intersect with blocks in config, we ignore the stock. var intersectedBlocks = _blockConfigMap.Keys.Intersect(blocks); if (!intersectedBlocks.Any()) { return(result); } foreach (var block in intersectedBlocks) { BlockConfig blockConfig = _blockConfigMap[block]; var upRateFromLowest = GetBlockUpRateFromLowest(block); if (upRateFromLowest < blockConfig.MinimumUpRate || upRateFromLowest > blockConfig.MaximumUpRate) { return(result); } } foreach (var block in blocks) { var indexRateOfChange = _blockToPriceIndexChangeRateMap[block].Value; if (indexRateOfChange > MininumRateOfChange) { result.Comments = string.Format( "Block {0} price index change rate {1:0.000}", block, indexRateOfChange); result.RelatedObject = new BlockUpRatesFromLowestForCode() { Code = tradingObject.Code, BlockUpRatesFromLowest = blocks.ToDictionary(b => b, b => GetBlockUpRateFromLowest(b)) }; result.CanEnter = true; } } return(result); }
private double GetDynamicEquityUtilization(ITradingObject tradingObject) { if (EquityUtilization == 0.0) { return(1.0); } return(_dynamicEquityUtilization); }
public bool Exists(ITradingObject tradingObject) { if (tradingObject == null) { throw new ArgumentNullException("tradingObject"); } return(_periods.ContainsKey(tradingObject.Index)); }
public void Remove(ITradingObject tradingObject) { if (tradingObject == null) { throw new ArgumentNullException("tradingObject"); } _periods.Remove(tradingObject.Index); _objects.Remove(tradingObject.Index); }
private double GetDynamicEquityUtilization(ITradingObject tradingObject) { if (EquityUtilization == 0.0) { return(1.0); } //return _calculator.CalculateEquityUtilization(tradingObject) * _dynamicEquityUtilization; return(_dynamicEquityUtilization); }
public void Count(Bar[] bars, ITradingObject tradingObject) { GenericRuntimeMetric movingAverage = new GenericRuntimeMetric(string.Format("MA[{0}]", _movingAveragePeriod)); GenericRuntimeMetric refbar = new GenericRuntimeMetric("REFBAR[1]"); for (int i = 0; i < bars.Length; ++i) { var bar = bars[i]; if (bar.Time == Bar.InvalidTime) { continue; } movingAverage.Update(bar); refbar.Update(bar); var lastBarLowest = refbar.Values[3]; var movingAverageValue = movingAverage.Values[0]; if (bar.ClosePrice < movingAverageValue * (100.0 - _minPercentageBelowMovingAverage) / 100.0 && // below average bar.OpenPrice < lastBarLowest * (100.0 - _minPercentageOfGapDown) / 100.0 && // gap down bar.ClosePrice > lastBarLowest * (100.0 + _minBouncePercentageOverLastLowestPrice) / 100.0 // bounce over last day ) { List <Bar> succBars = new List <Bar>(); succBars.Add(bar); for (int j = i + 1; j < bars.Length; ++j) { var currentBar = bars[j]; if (currentBar.Time == Bar.InvalidTime) { continue; } succBars.Add(currentBar); if (succBars.Count >= SampleBarSequenceLength) { break; } } if (succBars.Count > 0) { lock (_results) { _results.Add(succBars); } } } } }
public double[] GetMetricValues(ITradingObject tradingObject, int metricIndex) { IRuntimeMetric metric = GetMetric(tradingObject, metricIndex); if (metric == null) { return(null); } return(metric.Values); }
public bool IsTrue(ITradingObject tradingObject) { if (_expression2 == null) { return(Operate(_expression1.IsTrue(tradingObject))); } else { return(Operate(_expression1.IsTrue(tradingObject), _expression2.IsTrue(tradingObject))); } }