Login Page - Create Account

Support Board


Date/Time: Thu, 26 Dec 2024 14:27:51 +0000



[Programming Help] - ACSIL OrderStatusCode == SCT_OSC_OPEN not valid for manual market orders

View Count: 245

[2024-10-25 19:33:27]
User321619 - Posts: 26
Hello,

Currently, trying to write a custom study.

This condition if (order.OrderStatusCode == SCT_OSC_OPEN ) is true for manually placed buy limit and sell limit orders.

However, this condition is not true for manually placed *market* orders.

Basically, in this study, I would place orders manually and then exit based on certain conditions using study.

I have trimmed down the code here. As I mentioned, above condition does not return true for manually placed market orders. So activeOrderFound and orderDirection log messages are never printed for manual *market* orders.

What am I missing? Please suggest.

Also, while we are at it. Should I also check IsWorkingOrderStatus(order.OrderStatusCode) to make sure it is working/active order. And order.ParentInternalOrderID == 0, to make sure it is main order and not stop loss or take profit.


Thanks so much for looking in to this.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5



#include "sierrachart.h"

SCDLLName("Flatten Position Based on EMAs for Active Manual Orders")

SCSFExport scsf_FlattenManualOrderOnEMACross(SCStudyInterfaceRef sc)
{
// Define persistent arrays for EMA calculation
SCFloatArray EMA5, EMA8;
SCString logMessage;
  
if (sc.SetDefaults)
{
sc.GraphName = "Flatten Position on EMA Crossover for Manual Orders";

// Set this study to run on every tick
sc.AutoLoop = 0; // Disable AutoLoop
sc.UpdateAlways = 1; // Ensure function is evaluated on every tick

// Disable sending orders to trade service
sc.SendOrdersToTradeService = 0;

return;
}

// Only execute on new data to prevent repeated execution on the same tick
if (sc.Index < sc.ArraySize - 1)
return;

// Calculate EMAs only once per tick for efficiency
sc.ExponentialMovAvg(sc.BaseData[SC_LAST], EMA5, sc.Input[0].GetInt());
sc.ExponentialMovAvg(sc.BaseData[SC_LAST], EMA8, sc.Input[1].GetInt());

// Loop through orders to find an active manual parent order, limited to 100 orders for performance
s_SCTradeOrder order;
int activeOrderFound = 0;
int orderDirection = 0; // 1 for Buy, -1 for Sell

const int maxOrdersToCheck = 100;
int orderIndex = 0;

while (orderIndex < maxOrdersToCheck && sc.GetOrderByIndex(orderIndex, order) != 0)
{
// Check for an active, working, parent order (excluding stop or target orders)
   //&& IsWorkingOrderStatus(order.OrderStatusCode)
   //&& order.ParentInternalOrderID == 0
if (order.OrderStatusCode == SCT_OSC_OPEN )
{
activeOrderFound = 1;
   logMessage.Format("activeOrderFound:%d",activeOrderFound);
   sc.AddMessageToLog(logMessage,1);

   logMessage.Format("orderDirection:%d", order.BuySell);
   sc.AddMessageToLog(logMessage,1);
orderDirection = (order.BuySell == BSE_BUY) ? 1 : -1;
break; // Exit once an active parent order is found
}

orderIndex++;
}
}

Date Time Of Last Edit: 2024-10-26 07:03:58
[2024-10-26 06:57:01]
User321619 - Posts: 26
Additional AutoLoop question:

Do I need to use AutoLoop = 1 to calculate the EMA, because decision to sell will only depend on comparing last bar value and EMA. Previous bars are not used in decision making in the study. AutoLoop question is only for calculating EMA part in the study. Anywhere else we are only dealing with the last bar so keeping AutoLoop = 0 will be efficient as I understand.
What I have learned is keeping AutoLoop = 0 when you do not need calculations on previous bars is efficient. Here I just compare EMA to last bar values to make decision. Do I need AutoLoop = 1 just for calculating EMAs as shown in code?
Date Time Of Last Edit: 2024-10-26 07:06:14
[2024-10-26 09:23:34]
Marmany - Posts: 307
For info, keep autoloop = 1 for ema calc.
When working, your study will loose money if market is in consolidation phase.
You need to ensure market strongly trending, for example ema 20 angle greater than 70 degrees, before activating a trend based strategy.
[2024-10-26 09:24:23]
User431178 - Posts: 556

This condition if (order.OrderStatusCode == SCT_OSC_OPEN ) is true for manually placed buy limit and sell limit orders.
However, this condition is not true for manually placed *market* orders.

What happens when you execute a market order?
It is filled immediately at the next available price, therefore order status code would be SCT_OSC_FILLED.
SCT_OSC_OPEN means it is still modifiable.


If you are wanting to exit the position, why do you need to find the order?
You can easily find the position size and use that as the quantity for an oppsing order.



Do I need to use AutoLoop = 1 to calculate the EMA

In general no, but based on your actual code, yes.
To use Autoloop = 0, you would need to create loop for EMA calculation.





// Only execute on new data to prevent repeated execution on the same tick
if (sc.Index < sc.ArraySize - 1)
return;


// Calculate EMAs only once per tick for efficiency
sc.ExponentialMovAvg(sc.BaseData[SC_LAST], EMA5, sc.Input[0].GetInt());
sc.ExponentialMovAvg(sc.BaseData[SC_LAST], EMA8, sc.Input[1].GetInt());

This is problematic, your EMAs will not be calculated on chart recalculation, only running forwards (starting from the last bar at the time of recalculation).




const int maxOrdersToCheck = 100;

int orderIndex = 0;

while (orderIndex < maxOrdersToCheck && sc.GetOrderByIndex(orderIndex, order) != 0)

What happens if there are more than 100 orders in the memory?
If they are organized chronologically, 0 being the oldest, then the system will break when you exceed 100 orders.
[2024-10-27 22:33:24]
User321619 - Posts: 26
@User431178

Thanks so much for your detailed answer and touching all the questions I asked.

Your answer cleared up so many things for me.

I do have one more important question. And I was not able to find the answer after searching around.

Here, sc.BaseData[SC_LAST][sc.Index] will give the close price for last bar.
However, for the current bar, how can I get the value of price at any point, this can be anytime between open, high, low and close?

Again, many thanks for your answer. I wanted to try out things before I respond so it took some time.

Thanks
[2024-10-28 00:13:29]
User321619 - Posts: 26
Found answer to the question, for current latest price in the bar which is not fully formed.

sc.Close[] for the last bar in the chart contains the latest price as the bar is being built.

Thanks

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

Login

Login Page - Create Account