Announcement

Collapse

Looking for a User App or Add-On built by the NinjaTrader community?

Visit NinjaTrader EcoSystem and our free User App Share!

Have a question for the NinjaScript developer community? Open a new thread in our NinjaScript File Sharing Discussion Forum!
See more
See less

Partner 728x90

Collapse

Stops are not working on Backtest...only in Live mode

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Stops are not working on Backtest...only in Live mode

    Hello,
    I’ve been having issues with NinjaTrader filling a Stop order. For reference, I have included scree shots.
    Red: Original Stop Loss
    Greens: Each Profit Target
    Yellow: Modified Stop, Break Even (when Profit Target 1 hits)
    Black: Reduced Profit (When Profit Target 2 hits).

    In live mode, the above works perfectly. Each stop is modified and filled without a problem. However, when backtesting, it will not move the stop. I have looked everywhere for an error, but the code is fine. So, this makes testing and optimizing impossible as I cannot trust the results. I also cannot see anything on TraceOrders and it is set to true.

    The important code is below:


    private void SetStopProfit(double entryPrice)
    {
    double _stop = 0; ;

    if (_currentPosition == CurrentPos.Long)
    {
    _stop = RoundToTickSize(entryPrice - _atr[0] * StopLossMultipler);
    _profit = RoundToTickSize(entryPrice + (_atr[0] * ProfitTargetOne));
    _profit2 = RoundToTickSize(entryPrice + (_atr[0] * ProfitTargetTwo));
    _profit3 = RoundToTickSize(entryPrice + (_atr[0] * ProfitTargetThree));

    if (UseMultipleContracts)
    {
    _profitOrder1 = ExitLongLimit(0, true, (int)((double)ContractsShares * (double)(TP1Percentage / 100.0)), _profit, ProfitLong1, LongOrder);
    _profitOrder2 = ExitLongLimit(0, true, (int)((double)ContractsShares * (double)(TP2Percentage / 100.0)), _profit2, ProfitLong2, LongOrder);
    _profitOrder3 = ExitLongLimit(0, true, (int)((double)ContractsShares * (double)(TP3Percentage / 100.0)), _profit3, ProfitLong3, LongOrder);

    _stopOrder = ExitLongStopMarket(0, true, ContractsShares, _stop, StopLong, LongOrder);
    }
    else
    {
    _profitOrder1 = ExitLongLimit(0, true, ContractsShares, _profit, ProfitLong1, LongOrder);
    _stopOrder = ExitLongStopMarket(0, true, ContractsShares, _stop, StopLong, LongOrder);
    }
    }
    else if (_currentPosition == CurrentPos.Short)
    {
    _stop = RoundToTickSize((entryPrice + _atr[0] * StopLossMultipler));
    _profit = RoundToTickSize(entryPrice - (_atr[0] * ProfitTargetOne));
    _profit2 = RoundToTickSize(entryPrice - (_atr[0] * ProfitTargetTwo));
    _profit3 = RoundToTickSize(entryPrice - (_atr[0] * ProfitTargetThree));

    if (UseMultipleContracts)
    {
    _profitOrder1 = ExitShortLimit(0, true, (int)((double)ContractsShares * (double)(TP1Percentage / 100.0)), _profit, ProfitShort1, ShortOrder);
    _profitOrder2 = ExitShortLimit(0, true, (int)((double)ContractsShares * (double)(TP2Percentage / 100.0)), _profit2, ProfitShort2, ShortOrder);
    _profitOrder3 = ExitShortLimit(0, true, (int)((double)ContractsShares * (double)(TP3Percentage / 100.0)), _profit3, ProfitShort3, ShortOrder);

    _stopOrder = ExitShortStopMarket(0, true, ContractsShares, _stop, StopShort, ShortOrder);
    }
    else
    {
    _profitOrder1 = ExitShortLimit(0, true, ContractsShares, _profit, ProfitShort1, ShortOrder);
    _stopOrder = ExitShortStopMarket(0, true, ContractsShares, _stop, StopShort, ShortOrder);
    }
    }

    if (UseMultipleContracts)
    {
    Draw.Line(this, CurrentBar + "Profit 3", true, 1, _profit3, 0, _profit3, Brushes.Green, DashStyleHelper.Solid, 2);
    Draw.Line(this, CurrentBar + "Profit 2", true, 1, _profit2, 0, _profit2, Brushes.Green, DashStyleHelper.Solid, 2);
    }
    Draw.Line(this, CurrentBar + "Profit 1", true, 1, _profit, 0, _profit, Brushes.Green, DashStyleHelper.Solid, 2);
    Draw.Line(this, CurrentBar + "Stop", true, 1, _stop, 0, _stop, Brushes.Red, DashStyleHelper.Solid, 2);
    }

    private void BreakEven(Execution execution)
    {
    CancelOrder(_stopOrder);

    int sharesToClose = 0;

    if (execution.Order.Name == ProfitLong1)
    {
    sharesToClose = (int)((double)ContractsShares * (double)(TP2Percentage / 100.0)) + (int)((double)ContractsShares * (double)(TP3Percentage / 100.0));
    _stopOrder = ExitLongStopMarket(0, true, sharesToClose, RoundToTickSize(Position.AveragePrice), BreakEvenLong, LongOrder);
    Print("Break Even Long1 Set! " + sharesToClose);
    }
    if (execution.Order.Name == ProfitShort1)
    {
    sharesToClose = (int)((double)ContractsShares * (double)(TP2Percentage / 100.0)) + (int)((double)ContractsShares * (double)(TP3Percentage / 100.0));
    _stopOrder = ExitShortStopMarket(0, true, sharesToClose, RoundToTickSize(Position.AveragePrice), BreakEvenShort, ShortOrder);
    Print("Break Even Short1 Set! " + sharesToClose);
    }

    Draw.Line(this, CurrentBar + "BE 2", true, 1, RoundToTickSize(Position.AveragePrice), 0, Position.AveragePrice, Brushes.Yellow, DashStyleHelper.Solid, 2);
    Draw.Text(this, CurrentBar + "Text", sharesToClose.ToString(), 0, RoundToTickSize(Position.AveragePrice), Brushes.Black);
    }

    private void MoveBEtoTP1(Execution execution)
    {
    double newStop = 0;
    int sharesToClose = 0;
    CancelOrder(_stopOrder);

    if (execution.Order.Name == ProfitLong2)
    {
    newStop = _profit;
    sharesToClose = (int)((double)ContractsShares * (double)(TP3Percentage / 100.0));
    _stopOrder = ExitLongStopMarket(0, true, sharesToClose, newStop, ReducedProfitLong, LongOrder);
    Print("Half Profit Long Set!");
    }
    if (execution.Order.Name == ProfitShort2)
    {
    newStop = _profit;
    sharesToClose = (int)((double)ContractsShares * (double)(TP3Percentage / 100.0));
    _stopOrder = ExitShortStopMarket(0, true, sharesToClose, newStop, ReducedProfitShort, ShortOrder);
    Print("Half Profit Short Set!");
    }

    Draw.Line(this, CurrentBar + "Half Profit", true, 1, newStop, 0, newStop, Brushes.Black, DashStyleHelper.Solid, 2);
    Draw.Text(this, CurrentBar + "Text", sharesToClose.ToString(), 0, RoundToTickSize(Position.AveragePrice), Brushes.Black);
    }


    private void DefineExit()
    {
    if (ExitType == MyExitType.StopProfit)
    {

    }
    if (ExitType == MyExitType.Trail)
    {
    ResetTrail();
    }
    if (ExitType == MyExitType.StopReverse)
    {
    if (Position.MarketPosition == MarketPosition.Long && _enterShort)
    {
    ExitLong("Time Long");
    }

    if (Position.MarketPosition == MarketPosition.Short && _enterLong)
    {
    ExitShort("Time Short");
    }
    }
    }

    private void DefineEntry()
    {
    try
    {
    //These will hold custom conditions that need to be fulfilled
    bool BullCondition = false;
    bool BearCondition = false; ;
    //Create buy and sell conditions that are options set by the user
    var buyConditions = new List<Func<bool>>();
    var sellConditions = new List<Func<bool>>();

    //Market Hours
    buyConditions.Add(() => CheckTime());
    sellConditions.Add(() => CheckTime());

    buyConditions.Add(() => GreenBar());
    sellConditions.Add(() => RedBar());

    if (BollingerCrossUpper())
    {
    BullCondition = true;
    BearCondition = false;
    }

    if (BollingerCrossLower())
    {
    BullCondition = false;
    BearCondition = true;
    }

    _enterLong = buyConditions.All(x => x()) && BullCondition;
    _enterShort = sellConditions.All(x => x()) && BearCondition;
    }
    catch (Exception ex)
    {
    Print(ex.Message);
    }
    }

    private void EnterMarket()
    {
    if (Position.MarketPosition == MarketPosition.Flat)
    {
    _breakEvenSet = false;

    if (_enterLong)
    EnterLong(ContractsShares, LongOrder);
    else if (_enterShort)
    EnterShort(ContractsShares, ShortOrder);
    }
    else if (Position.MarketPosition != MarketPosition.Flat)
    {
    //BreakEven();
    }
    }

    #endregion

    #region Handle Orders

    private bool IsEntryOrderFilled(Execution exec)
    {
    return exec.Order.OrderState == OrderState.Filled && IsEntryOrder(exec.Order.Name);
    }

    private bool IsEntryOrder(string name)
    {
    return name == LongOrder || name == ShortOrder;
    }

    private void IdentifyDirection(Execution execution)
    {
    if (execution.Order.Name == LongOrder)
    _currentPosition = CurrentPos.Long;

    if (execution.Order.Name == ShortOrder)
    _currentPosition = CurrentPos.Short;
    }

    /// <summary>
    /// Check time to ensure it is trading during the startegy's trading hours
    /// </summary>
    /// <returns>true/false</returns>
    private bool CheckTime()
    {
    if (UseTimeFilter == false)
    return true;
    else
    {
    //Uses Computer's Local Time
    if ((ToTime(Time[0]) >= 94500 && ToTime(Time[0]) <= 154500))
    {
    return true;
    }
    else
    return false;
    }
    }

    private bool IsProfitTargetOneFilled(Execution execution)
    {
    return execution.Order.OrderState == OrderState.Filled && IsProTargetOneOrder(execution.Order.Name);
    }

    private bool IsProfitTargetTwoFilled(Execution execution)
    {
    return execution.Order.OrderState == OrderState.Filled && IsProTargetTwoOrder(execution.Order.Name);
    }

    private bool IsProTargetOneOrder(string orderName)
    {
    return orderName == ProfitLong1 || orderName == ProfitShort1;
    }

    private bool IsProTargetTwoOrder(string orderName)
    {
    return orderName == ProfitLong2 || orderName == ProfitShort2;
    }

    protected override void OnBarUpdate()
    {
    if (CurrentBar < 2)
    return;

    DefineEntry();

    if (Position.MarketPosition == MarketPosition.Flat)
    EnterMarket();

    if (Position.MarketPosition != MarketPosition.Flat)
    {
    DefineExit();
    }
    }

    protected override void OnExecutionUpdate(Execution execution, string executionId, double price, int quantity, MarketPosition marketPosition,
    string orderId, DateTime time)
    {

    if (IsEntryOrderFilled(execution))
    {
    profitOneHa**** = false;
    IdentifyDirection(execution);

    if (ExitType == MyExitType.StopProfit)
    {
    SetStopProfit(execution.Order.AverageFillPrice);
    }
    if (ExitType == MyExitType.PreviousSwing)
    {
    SetStopProfitSwing(execution.Order.AverageFillPric e);
    }
    if (ExitType == MyExitType.PreviousCandle)
    {
    SetStopProfitCandle(execution.Order.AverageFillPri ce);
    }
    if (ExitType == MyExitType.Trail)
    {
    InitializeTrail(execution.Order.AverageFillPrice);
    }
    }

    if (IsProfitTargetOneFilled(execution))
    {
    BreakEven(execution);
    }

    if (IsProfitTargetTwoFilled(execution))
    {
    profitOneHa**** = true;
    MoveBEtoTP1(execution);
    }
    }

    protected override void OnOrderTrace(DateTime timestamp, string message)
    {
    //var messageLower = message.ToLower();
    //var ignored = "ignored";

    //if (messageLower.Contains(ignored))
    PrintToSecondaryOutput(String.Format("{0} {1}", message, timestamp));
    }

    #endregion

    #region Helpers

    private double RoundToTickSize(double value)
    {
    return Instrument.MasterInstrument.RoundToTickSize(value) ;
    }

    private void PrintToSecondaryOutput(string info)
    {
    Output.Process(info, PrintTo.OutputTab2);
    }

    #endregion


    Click image for larger version

Name:	Backtest.png
Views:	113
Size:	97.2 KB
ID:	1278917

Latest Posts

Collapse

Topics Statistics Last Post
Started by burtoninlondon, Today, 12:38 AM
0 responses
5 views
0 likes
Last Post burtoninlondon  
Started by AaronKoRn, Yesterday, 09:49 PM
0 responses
12 views
0 likes
Last Post AaronKoRn  
Started by carnitron, Yesterday, 08:42 PM
0 responses
11 views
0 likes
Last Post carnitron  
Started by strategist007, Yesterday, 07:51 PM
0 responses
13 views
0 likes
Last Post strategist007  
Started by StockTrader88, 03-06-2021, 08:58 AM
44 responses
3,982 views
3 likes
Last Post jhudas88  
Working...
X