public override Trade NewStoploss(Position position, DateTime AsOf) { position.Security.SetSwingPointsAndTrends(BarCount, BarSize); if (position.ExecutedTrades.Count > 1) { throw new UnknownErrorException(); } // First prior swingpoint is first prior that is REALIZED at the time of signal, so we have to look at least BarCount bars back PriceBar firstPriorSwingPoint = null; switch (BarSize) { case PriceBarSize.Daily: firstPriorSwingPoint = position.Security.GetPriceBar(Calendar.PriorTradingDay(AsOf, BarCount), BarSize); break; case PriceBarSize.Weekly: firstPriorSwingPoint = position.Security.GetPriceBar(Calendar.PriorTradingWeekStart(AsOf, BarCount), BarSize); break; case PriceBarSize.Monthly: firstPriorSwingPoint = position.Security.GetPriceBar(Calendar.PriorTradingMonthStart(AsOf, BarCount), BarSize); break; case PriceBarSize.Quarterly: firstPriorSwingPoint = position.Security.GetPriceBar(Calendar.PriorTradingMonthStart(AsOf, BarCount), BarSize); break; default: break; } decimal stopPrice = -1m; decimal expExecutionPx = position.Security.GetPriceBar(AsOf, BarSize).Close; switch (position.PositionDirection) { case PositionDirection.ShortPosition: // First prior swingpoint high while ((firstPriorSwingPoint.GetSwingPointType(BarCount) & SwingPointType.SwingPointHigh) == 0) { firstPriorSwingPoint = firstPriorSwingPoint.PriorBar; } stopPrice = firstPriorSwingPoint.High + .01m; break; case PositionDirection.LongPosition: // First prior swingpoint low while ((firstPriorSwingPoint.GetSwingPointType(BarCount) & SwingPointType.SwingPointLow) == 0) { firstPriorSwingPoint = firstPriorSwingPoint.PriorBar; } stopPrice = firstPriorSwingPoint.Low - .01m; break; } // If the last valid swingpoint is on the wrong side of our trade (above exp trade price for a long, below a short), use an ATR atop switch (position.PositionDirection) { case PositionDirection.LongPosition: if (stopPrice >= expExecutionPx) { BackupStoploss.Stoploss_ATR_Multiple = this.Stoploss_ATR_Multiple; BackupStoploss.Stoploss_ATR_Period = this.Stoploss_ATR_Period; return(BackupStoploss.NewStoploss(position, AsOf)); } break; case PositionDirection.ShortPosition: if (stopPrice <= expExecutionPx) { BackupStoploss.Stoploss_ATR_Multiple = this.Stoploss_ATR_Multiple; BackupStoploss.Stoploss_ATR_Period = this.Stoploss_ATR_Period; return(BackupStoploss.NewStoploss(position, AsOf)); } break; } if (stopPrice <= 0) { stopPrice = 0.01m; } var stop = new Trade( position.Security, (TradeActionBuySell)(-position.PositionDirection.ToInt()), Math.Abs(position.Size(AsOf)), TradeType.Stop, 0, stopPrice) { TradeDate = AsOf }; return(stop); }
public override decimal UpdatePositionStoplossPrice(Position position, Trade currentStop, DateTime AsOf) { position.Security.SetSwingPointsAndTrends(BarCount, BarSize); // First prior swingpoint is first prior that is REALIZED at the time of signal, so we have to look at least BarCount bars back PriceBar firstPriorSwingPoint = null; switch (BarSize) { case PriceBarSize.Daily: firstPriorSwingPoint = position.Security.GetPriceBar(Calendar.PriorTradingDay(AsOf, BarCount), BarSize); break; case PriceBarSize.Weekly: firstPriorSwingPoint = position.Security.GetPriceBar(Calendar.PriorTradingWeekStart(AsOf, BarCount), BarSize); break; case PriceBarSize.Monthly: firstPriorSwingPoint = position.Security.GetPriceBar(Calendar.PriorTradingMonthStart(AsOf, BarCount), BarSize); break; case PriceBarSize.Quarterly: firstPriorSwingPoint = position.Security.GetPriceBar(Calendar.PriorTradingMonthStart(AsOf, BarCount), BarSize); break; default: break; } decimal stopPrice = -1m; decimal lastPx = position.Security.GetPriceBar(AsOf, PriceBarSize.Daily).Close; switch (position.PositionDirection) { case PositionDirection.ShortPosition: // First prior swingpoint high while ((firstPriorSwingPoint.GetSwingPointType(BarCount) & SwingPointType.SwingPointHigh) == 0) { firstPriorSwingPoint = firstPriorSwingPoint.PriorBar; } stopPrice = firstPriorSwingPoint.High + .01m; break; case PositionDirection.LongPosition: // First prior swingpoint low while ((firstPriorSwingPoint.GetSwingPointType(BarCount) & SwingPointType.SwingPointLow) == 0) { firstPriorSwingPoint = firstPriorSwingPoint.PriorBar; } stopPrice = firstPriorSwingPoint.Low - .01m; break; } // If the last valid swingpoint is on the wrong side of our trade (above exp trade price for a long, below a short), use an ATR atop switch (position.PositionDirection) { case PositionDirection.LongPosition: if (stopPrice >= position.Security.GetPriceBar(AsOf, PriceBarSize.Daily).Close) { BackupStoploss.Stoploss_ATR_Multiple = this.Stoploss_ATR_Multiple; BackupStoploss.Stoploss_ATR_Period = this.Stoploss_ATR_Period; return(BackupStoploss.UpdatePositionStoplossPrice(position, currentStop, AsOf)); } break; case PositionDirection.ShortPosition: if (stopPrice >= position.Security.GetPriceBar(AsOf, PriceBarSize.Daily).Close) { BackupStoploss.Stoploss_ATR_Multiple = this.Stoploss_ATR_Multiple; BackupStoploss.Stoploss_ATR_Period = this.Stoploss_ATR_Period; return(BackupStoploss.UpdatePositionStoplossPrice(position, currentStop, AsOf)); } break; } if (stopPrice <= 0) { stopPrice = 0.01m; } // Calculate the adjusted base stop if we are using a creeping stop decimal adjustedBaseStop = currentStop.StopPrice; if (Stoploss_Creep_Percent > 0) { switch (position.PositionDirection) { case PositionDirection.LongPosition: // Increase base stop adjustedBaseStop *= (1 + Stoploss_Creep_Percent); break; case PositionDirection.ShortPosition: // Decrease base stop adjustedBaseStop *= (1 - Stoploss_Creep_Percent); break; } } switch (position.PositionDirection) { case PositionDirection.LongPosition: return(Math.Max(stopPrice, adjustedBaseStop)); case PositionDirection.ShortPosition: return(Math.Min(stopPrice, adjustedBaseStop)); default: throw new UnknownErrorException(); } }
public override int NewPositionSize(Portfolio portfolio, Signal IndicatedTrade, DateTime AsOf, decimal initialRiskPercent) { IndicatedTrade.Security.SetSwingPointsAndTrends(BarCount, BarSize); decimal riskDollarsTotal = portfolio.EquityWithLoanValue(AsOf, TimeOfDay.MarketEndOfDay) * initialRiskPercent; // First prior swingpoint is first prior that is REALIZED at the time of signal, so we have to look at least BarCount bars back PriceBar firstPriorSwingPoint = null; switch (BarSize) { case PriceBarSize.Daily: firstPriorSwingPoint = IndicatedTrade.Security.GetPriceBar(Calendar.PriorTradingDay(AsOf, BarCount), BarSize); break; case PriceBarSize.Weekly: firstPriorSwingPoint = IndicatedTrade.Security.GetPriceBar(Calendar.PriorTradingWeekStart(AsOf, BarCount), BarSize); break; case PriceBarSize.Monthly: firstPriorSwingPoint = IndicatedTrade.Security.GetPriceBar(Calendar.PriorTradingMonthStart(AsOf, BarCount), BarSize); break; case PriceBarSize.Quarterly: firstPriorSwingPoint = IndicatedTrade.Security.GetPriceBar(Calendar.PriorTradingMonthStart(AsOf, BarCount), BarSize); break; default: break; } decimal stopPrice = -1m; decimal expExecutionPx = IndicatedTrade.Security.GetPriceBar(AsOf, BarSize).Close; switch (IndicatedTrade.SignalAction) { case SignalAction.Sell: // First prior swingpoint high while ((firstPriorSwingPoint.GetSwingPointType(BarCount) & SwingPointType.SwingPointHigh) == 0) { firstPriorSwingPoint = firstPriorSwingPoint.PriorBar; } stopPrice = firstPriorSwingPoint.High + .01m; break; case SignalAction.Buy: // First prior swingpoint low while ((firstPriorSwingPoint.GetSwingPointType(BarCount) & SwingPointType.SwingPointLow) == 0) { firstPriorSwingPoint = firstPriorSwingPoint.PriorBar; } stopPrice = firstPriorSwingPoint.Low - .01m; break; } // If the last valid swingpoint is on the wrong side of our trade (above exp trade price for a long, below a short), use an ATR atop switch (IndicatedTrade.SignalAction) { case SignalAction.Sell: if (stopPrice >= expExecutionPx) { BackupStoploss.Stoploss_ATR_Multiple = this.Stoploss_ATR_Multiple; BackupStoploss.Stoploss_ATR_Period = this.Stoploss_ATR_Period; return(BackupStoploss.NewPositionSize(portfolio, IndicatedTrade, AsOf, initialRiskPercent)); } break; case SignalAction.Buy: if (stopPrice <= expExecutionPx) { BackupStoploss.Stoploss_ATR_Multiple = this.Stoploss_ATR_Multiple; BackupStoploss.Stoploss_ATR_Period = this.Stoploss_ATR_Period; return(BackupStoploss.NewPositionSize(portfolio, IndicatedTrade, AsOf, initialRiskPercent)); } break; } decimal initialBuffer = expExecutionPx * initialRiskPercent; decimal riskDollarsPerShare = Math.Abs(IndicatedTrade.Security.GetPriceBar(AsOf, BarSize).Close - stopPrice); if (riskDollarsPerShare < initialBuffer) { riskDollarsPerShare = initialBuffer; } int positionSize = Convert.ToInt32(Math.Round((riskDollarsTotal / riskDollarsPerShare), 0)); return(positionSize); }