Login Page - Create Account

Support Board


Date/Time: Thu, 02 May 2024 14:14:04 +0000



[Programming Help] - ACSIL and closing existing order when a condition is met

View Count: 1269

[2020-07-26 05:23:59]
User622324 - Posts: 4
In a nut shell: I have an Algo that goes long/short depending on a few criteria. For the sake of this question, I have a few conditions that enable me to enter a long position. Since this is trend following, rather and having a specific take profit and stop loss, my system should remain long UNTIL some criteria is met (i.e. the "STRONG_LONG" becomes "STRONG_SHORT" etc).

In the below, I am able to enter positions (and have just tried plotting entries/exits without the actual orders and just using arrows) and that seems to work correctly. My question is around I am unable to "close" the positions and for this I was using `sc.FlattenAndCancelAllOrders()`. I had tried following an example in `TradingSystems.cpp` but had no luck.

The pseudo logic I wanted to follow was:
- If Position open, are we long?
- If we are long and we see a STRONG_SHORT, close

and also

- If Position open, are we short?
- If we are short and see a STRONG_LONG, close


In a nut shell, the bottom code under `s_SCTradeOrder ExistingOrder` is what I'm not sure if that's the proper way of doing it.


  // Use persistent variables to remember attached order IDs so they can be modified or canceled.
  int &Target1OrderID = sc.GetPersistentInt(1);
  int &Stop1OrderID = sc.GetPersistentInt(2);
  int &r_InternalOrderID = sc.GetPersistentInt(3);

  s_SCNewOrder NewOrder;
  NewOrder.OrderQuantity = 1;
  NewOrder.OrderType = SCT_ORDERTYPE_MARKET;
  NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED;

  // NewOrder.AttachedOrderTarget1Type = SCT_ORDERTYPE_LIMIT;
  // NewOrder.Target1Offset = Input_TargetTicks.GetInt() * sc.TickSize; // 8 ticks
  // NewOrder.AttachedOrderStop1Type = SCT_ORDERTYPE_STOP;
  // NewOrder.Stop1Offset = Input_StopTicks.GetInt() * sc.TickSize; // 8 tick stop

  if (IsStrong && concavityState == JN::CONCAV_STATE::STRONG_LONG)
  {
    int Result = (int)sc.BuyOrder(NewOrder);
    if (Result > 0)
    {
      Subgraph_BuyEntry[sc.Index] = sc.Close[sc.Index] - Input_OffsetArrowDisplay.GetFloat();
      // Remember the order IDs for subsequent modification and cancellation
      Target1OrderID = NewOrder.Target1InternalOrderID;
      Stop1OrderID = NewOrder.Stop1InternalOrderID;
      r_InternalOrderID = NewOrder.InternalOrderID;
    }
    else
    {
      //Only report error if at the last bar
      if (sc.Index == sc.ArraySize - 1)
      {
        //Add error message to the Sierra Chart Message Log for interpretation
        sc.AddMessageToLog(sc.GetTradingErrorTextMessage(Result), 1);
      }
    }
    // Subgraph_BuyEntry[sc.Index] = sc.Close[sc.Index] - Input_OffsetArrowDisplay.GetFloat();
  }
  else if (IsStrong && concavityState == JN::CONCAV_STATE::STRONG_SHORT)
  {
    // Subgraph_SellEntry[sc.Index] = sc.Close[sc.Index] + Input_OffsetArrowDisplay.GetFloat();
    int Result = (int)sc.SellOrder(NewOrder);
    if (Result > 0)
    {
      //If there has been a successful order entry, then draw an arrow
      // Apply offset so the arrows don't draw on candles
      Subgraph_SellEntry[sc.Index] = sc.Close[sc.Index] + Input_OffsetArrowDisplay.GetFloat();
      // Remember the order IDs for subsequent modification and cancellation
      Target1OrderID = NewOrder.Target1InternalOrderID;
      Stop1OrderID = NewOrder.Stop1InternalOrderID;
      r_InternalOrderID = NewOrder.InternalOrderID;
    }
    else
    {
      //Only report error if at the last bar
      if (sc.Index == sc.ArraySize - 1)
      {
        //Add error message to the Sierra Chart Message Log for interpretation
        sc.AddMessageToLog(sc.GetTradingErrorTextMessage(Result), 1);
      }
    }
  }

  // Get the existing target order, and you basically want this code to run
  // when we're long and we now get a STRONG SHORT signal or when we're
  // short and we get a strong long signal
  // So IF we have an open /working position AND we meet the above critera
  // Let's just close it.
  s_SCTradeOrder ExistingOrder;
  if (sc.GetOrderByOrderID(r_InternalOrderID, ExistingOrder))
  {
    if (IsWorkingOrderStatus(ExistingOrder.OrderStatusCode))
    {
      sc.AddMessageToLog("Open order has been found!", 1);
      if (ExistingOrder.BuySell == BSE_BUY && concavityState == JN::CONCAV_STATE::STRONG_SHORT)
      {
        sc.AddMessageToLog("Closing long due to STRONG SHORT state and current open long!", 1);
        sc.FlattenAndCancelAllOrders();
      }
      else if (ExistingOrder.BuySell == BSE_SELL && concavityState == JN::CONCAV_STATE::STRONG_LONG)
      {
        sc.FlattenAndCancelAllOrders();
        sc.AddMessageToLog("Closing short due to STRONG LONG state and current open short!", 1);
      }
    }
  }

Date Time Of Last Edit: 2020-07-26 05:25:45
[2020-07-26 14:49:28]
bradh - Posts: 854
It does not need to be that complex. You want to enable support for reversals, which is off by default.

Look here: Automated Trading Management: SupportReversals

sc.SupportReversals = EnableReversals.GetYesNo();

[2020-07-26 17:46:09]
User622324 - Posts: 4
Hey Bradh,

Well so there are ultimately 3 states: long/short/flat

I there are times when I want to be able to just be long then close when a calculation meets a criteria. At this point it doesn’t mean I’d want to be short, hence the logic to “flatten and cancel all”.
[2020-07-26 17:51:44]
bradh - Posts: 854
When in a long trade, a reversal entry (sell signal) will cause the long trade to flatten and the short entry. If you want to test for a different exit criteria, you can do that too, before you check for the reversal.

To post a message in this thread, you need to log in with your Sierra Chart account:

Login

Login Page - Create Account