Login Page - Create Account

Support Board


Date/Time: Sat, 18 May 2024 18:02:54 +0000



[Programming Help] - trading system based on 2 signals

View Count: 1036

[2021-03-09 11:03:15]
User61576 - Posts: 418
I have 2 studies I used to place a signal on the chart. only if the 2 together have a signal in the same direction, I would like to enter a trade

how can I call an ASCIL function to check if there is a "Red arrow" & "Red circle" on the main chart to enter a short position?
any other thoughts?
[2021-03-09 16:31:03]
bradh - Posts: 859
In order to call an ACSIL function to do what you want, one can write a custom study function in ACSIL that reads the output subgraphs of the two studies and compares them to create a new order entry.

You can also do this with the Trading System Based on Alert Condition. The alert would use the logical AND to read both outputs and generate its own signal. More info here: Trading System Based on Alert Condition
[2021-03-09 16:45:44]
User61576 - Posts: 418
what is the name of the function to read the output subgraphs?

about the Trading System Based on Alert Condition, if I understand correctly, I need to define an alert per each and I can not use it as it is now (its acsil code based so looks to be complicated to create an alert)
[2021-03-09 17:19:51]
bradh - Posts: 859
what is the name of the function to read the output subgraphs?
Look here: Study/Chart Alerts And Scanning: To Enter an Alert Condition on a Study

With the Trading System Based on Alert Condition study you would create one for buy and one for sell. You don't need to understand the ACSIL code to use the study.
[2021-03-09 20:19:42]
User61576 - Posts: 418
i meant if there a acsil to call the subgraph from the chart, u gave a link to the alert study
[2021-03-09 23:51:46]
Flipper_2 - Posts: 57
There is an example of trading system that uses two study subgraphs in C:\SierraChart\ACS_Source\TradingSystem.cpp

Search for scsf_TradingSystemStudySubgraphCrossover
[2021-03-10 06:05:00]
User61576 - Posts: 418
I see it take a decision when a bar close,
how do I make it "run" after other studies completing their own calculation which is also based on bar close?
if this new calculation will be done before the other inherited signals which also calculated based on bar close, there will be no match (no crossover)
[2021-03-10 06:45:43]
Flipper_2 - Posts: 57
It will 'run' after the other studies because of this line,
sc.CalculationPrecedence = LOW_PREC_LEVEL;

But probably far far easier to post some code about what you have tried and what you want to do.
[2021-03-10 07:49:33]
User61576 - Posts: 418
I have 1 study code that generates a signal on chart
I have another study code that also generates a signal on chart

only if both (in the same bar) are marked on chart (so we have 2 signals together) - I would like to send an order

this part will call the studies I already have and get the signal from the chart (this is from the exmpale above)
  SCFloatArray StudyLine1;
  sc.GetStudyArrayUsingID(Input_Line1Ref.GetStudyID(), Input_Line1Ref.GetSubgraphIndex(), StudyLine1);

  SCFloatArray StudyLine2;
  sc.GetStudyArrayUsingID(Input_Line2Ref.GetStudyID(), Input_Line2Ref.GetSubgraphIndex(), StudyLine2);

the trigger for entry will be (from the example):
  if (sc.CrossOver(StudyLine1, StudyLine2) == CROSS_FROM_BOTTOM)

and this is what I am trying to find, how to compare StudyLine1, StudyLine2 that they are both "true" (so I have a signal on both of them) and I could not find anything https://www.sierrachart.com/index.php?page=doc/ACSIL_Members_Functions.html

thanks for helping out!
[2021-03-10 07:58:56]
Flipper_2 - Posts: 57


s_SCNewOrder Order;
Order.OrderQuantity = 1;
Order.OrderType = SCT_ORDERTYPE_MARKET;


If (StudyLine1[sc.Index] == 1 && StudyLine2[sc.Index] == 1) // assuming that 1 is the signal
{
sc.BuyEntry(Order);
}

[2021-03-10 08:13:41]
Flipper_2 - Posts: 57
Actually thinking about this you probably wouldn't have the signal as an int as they are floats arrays in subgraphs so a full example where say a buy signal is greater than 0 and a sell signal is less than 0 the complete code using that suggested scsf_TradingSystemStudySubgraphCrossover code as a framework




SCSFExport scsf_TradingSystemStudySubgraph(SCStudyInterfaceRef sc)
{
  SCInputRef Input_Line1Ref = sc.Input[0];
  SCInputRef Input_Line2Ref = sc.Input[1];
  SCInputRef Input_Enabled = sc.Input[2];
  SCInputRef Input_SendTradeOrdersToTradeService = sc.Input[3];
  SCInputRef Input_MaximumPositionAllowed = sc.Input[4];
  SCInputRef Input_ActionOnCrossoverWhenInPosition = sc.Input[5];
  SCInputRef Input_EvaluateOnBarCloseOnly = sc.Input[6];

  SCSubgraphRef Subgraph_BuyEntry = sc.Subgraph[0];
  SCSubgraphRef Subgraph_SellEntry = sc.Subgraph[1];

  if (sc.SetDefaults)
  {

    // Set the configuration and defaults

    sc.GraphName = "Trading System - Study Subgraph";


    sc.AutoLoop = 1; // true
    sc.GraphRegion = 0;
    sc.CalculationPrecedence = LOW_PREC_LEVEL;

    Input_Line1Ref.Name = "Line1";
    Input_Line1Ref.SetStudySubgraphValues(1, 0);

    Input_Line2Ref.Name = "Line2";
    Input_Line2Ref.SetStudySubgraphValues(1, 0);

    Input_Enabled.Name = "Enabled";
    Input_Enabled.SetYesNo(false);

    Input_SendTradeOrdersToTradeService.Name = "Send Trade Orders to Trade Service";
    Input_SendTradeOrdersToTradeService.SetYesNo(false);

    Input_MaximumPositionAllowed.Name = "Maximum Position Allowed";
    Input_MaximumPositionAllowed.SetInt(1);

    Input_ActionOnCrossoverWhenInPosition.Name = "Action on Crossover When in Position";
    Input_ActionOnCrossoverWhenInPosition.SetCustomInputStrings("No Action;Exit on Crossover;Reverse on Crossover");
    Input_ActionOnCrossoverWhenInPosition.SetCustomInputIndex(0);

    Input_EvaluateOnBarCloseOnly.Name = "Evaluate on Bar Close Only";
    Input_EvaluateOnBarCloseOnly.SetYesNo(true);


    Subgraph_BuyEntry.Name = "Buy";
    Subgraph_BuyEntry.DrawStyle = DRAWSTYLE_POINT_ON_HIGH;
    Subgraph_BuyEntry.LineWidth = 4;

    Subgraph_SellEntry.Name = "Sell";
    Subgraph_SellEntry.DrawStyle = DRAWSTYLE_POINT_ON_LOW;
    Subgraph_SellEntry.LineWidth = 4;

    sc.AllowMultipleEntriesInSameDirection = false;
    sc.SupportReversals = false;

    sc.AllowOppositeEntryWithOpposingPositionOrOrders = false;

    sc.SupportAttachedOrdersForTrading = false;
    sc.UseGUIAttachedOrderSetting = true;
    sc.CancelAllOrdersOnEntriesAndReversals = true;
    sc.AllowEntryWithWorkingOrders = false;
    sc.CancelAllWorkingOrdersOnExit = true;

    // Only 1 trade for each Order Action type is allowed per bar.
    sc.AllowOnlyOneTradePerBar = true;

    //This should be set to true when a trading study uses trading functions.
    sc.MaintainTradeStatisticsAndTradesData = true;

    return;
  }

  sc.MaximumPositionAllowed = Input_MaximumPositionAllowed.GetInt();
  sc.SendOrdersToTradeService = Input_SendTradeOrdersToTradeService.GetYesNo();

  if (!Input_Enabled.GetYesNo())
    return;

  // only process at the close of the bar. If it has not closed do not do anything
  if (Input_EvaluateOnBarCloseOnly.GetYesNo()
    && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_NOT_CLOSED)
  {
    return;
  }

  // using the Input_Line1Ref and Input_Line2Ref input variables, retrieve the subgraph arrays
  SCFloatArray StudyLine1;
  sc.GetStudyArrayUsingID(Input_Line1Ref.GetStudyID(), Input_Line1Ref.GetSubgraphIndex(), StudyLine1);

  SCFloatArray StudyLine2;
  sc.GetStudyArrayUsingID(Input_Line2Ref.GetStudyID(), Input_Line2Ref.GetSubgraphIndex(), StudyLine2);



  sc.SupportReversals = false;

  if (StudyLine1[sc.Index] > 0 && StudyLine2[sc.Index] > 0)
  {
    // mark the crossover on the chart
    Subgraph_BuyEntry[sc.Index] = 1;

    if (!sc.IsFullRecalculation && !sc.DownloadingHistoricalData)
    {
        s_SCNewOrder NewOrder;
        NewOrder.OrderQuantity = 0;
        NewOrder.OrderType = SCT_ORDERTYPE_MARKET;
        NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED;
        int Result = (int)sc.BuyEntry(NewOrder);//Buy order
if (Result < 0)
          sc.AddMessageToLog(sc.GetTradingErrorTextMessage(Result), false);

    }
  }

  if (StudyLine1[sc.Index] < 0 && StudyLine2[sc.Index] < 0)
  {
    // mark the crossover on the chart
    Subgraph_SellEntry[sc.Index] = 1;

    if (!sc.IsFullRecalculation && !sc.DownloadingHistoricalData)
    {

      s_SCNewOrder NewOrder;
      NewOrder.OrderQuantity = 0;
      NewOrder.OrderType = SCT_ORDERTYPE_MARKET;
      NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED;
      int Result = (int)sc.SellEntry(NewOrder);//Sell order
      if (Result < 0)
        sc.AddMessageToLog(sc.GetTradingErrorTextMessage(Result), false);
  
    }
  }
}

Date Time Of Last Edit: 2021-03-10 08:14:19
[2021-03-10 08:14:00]
User61576 - Posts: 418
==1
= there is a signal?
pls check attached screenshot, this is the source of the signal
can it be
== true
?
imageScreenshot_6.jpg / V - Attached On 2021-03-10 08:11:55 UTC - Size: 109.04 KB - 176 views
[2021-03-10 08:16:22]
Flipper_2 - Posts: 57
No what is the actual value in the subgraph? It will have to be a numeric value in a subgraph
[2021-03-10 08:22:26]
User61576 - Posts: 418
I have no idea, it's generating arrows for long/short
is it 1 for drawing an arrow on the chart (
BuyEntrySubgraph.DrawStyle = DRAWSTYLE_ARROWUP;
)?

I guess that it will be the same for drawing an arrow for the short side
[2021-03-10 08:33:05]
Flipper_2 - Posts: 57
Use the "Chart Values For Tools" window to see what values are in the subgraphs
image2021-03-10 19_30_39-Sierra Chart 2234 Forum_Example CQG Web.png / V - Attached On 2021-03-10 08:32:54 UTC - Size: 46.65 KB - 166 views
[2021-03-10 11:30:46]
User61576 - Posts: 418
you can see here (attached) that the signal (red down arrow) has no value
any other suggestion?
imageScreenshot_7.jpg / V - Attached On 2021-03-10 11:29:43 UTC - Size: 72.06 KB - 179 views
[2021-03-10 11:42:10]
Flipper_2 - Posts: 57
Do you have the code for that study? You need to find the logic for that arrow and see why/how the value is stored/produced and import that subgraph
[2021-03-10 13:09:52]
User61576 - Posts: 418
i have the code for 1 study and for the 2nd study (what i uploaded earlier with the red arrow) as well
pls note that my 2nd study is the same code you loaded before for the scsf_TradingSystemStudySubgraph and I added to it
    Subgraph_SellEntry[sc.Index] = sc.High[sc.Index] + ddOffsetInput.GetFloat();
how do I add it a value?
[2021-03-10 20:30:56]
Flipper_2 - Posts: 57
Ok that's nowhere near enough to show me where that true condition comes from. Somewhere in those two studys will be arrays, very likely SCSubgraphRef, that hold the signal. Certainly there is a condition that makes that above line true with something like an "if()" statement. You may need to add another subgraph in as a signal but really it hard to know what the study you want to import is doing if there is next to no info.
Date Time Of Last Edit: 2021-03-10 20:31:04
[2021-03-11 07:15:07]
User61576 - Posts: 418
Here is the code, though the if condition is simple and it's based on the original scsf_TradingSystemStudySubgraphCrossover
I understand I need to add to that signal on the chart a value, how should it be done?

thanks!


#include <string>
#include "sierrachart.h"
#include <math.h>
#include <iostream>
#include <fstream>
using namespace std;
SCDLLName("test")


SCSFExport scsf_TradingSystemStudySubgraphCrossover(SCStudyInterfaceRef sc)
{
  SCInputRef Input_Line1Ref = sc.Input[0];
  SCInputRef Input_Line2Ref = sc.Input[1];
  SCInputRef Input_Line3Ref = sc.Input[2];
  SCInputRef Input_Enabled = sc.Input[3];
  SCInputRef Input_SendTradeOrdersToTradeService = sc.Input[4];
  SCInputRef Input_MaximumPositionAllowed = sc.Input[5];
  SCInputRef Input_EvaluateOnBarCloseOnly = sc.Input[7];
  SCInputRef Min_Ratchet = sc.Input[8];
  SCInputRef Max_Ratchet = sc.Input[9];
  SCInputRef ddOffsetInput = sc.Input[10];

  SCSubgraphRef Subgraph_BuyEntry = sc.Subgraph[0];
  SCSubgraphRef Subgraph_SellEntry = sc.Subgraph[1];

  if (sc.SetDefaults)
  {

    // Set the configuration and defaults

    sc.GraphName = "test";

    sc.StudyDescription = "A trading system that enters a new position \
      based";

    sc.AutoLoop = 1; // true
    sc.GraphRegion = 1;
    sc.CalculationPrecedence = LOW_PREC_LEVEL;

    Input_Line1Ref.Name = "Max";
    Input_Line1Ref.SetStudySubgraphValues(1, 0);

    Input_Line2Ref.Name = "Min";
    Input_Line2Ref.SetStudySubgraphValues(1, 0);

    Input_Line3Ref.Name = "Final";
    Input_Line3Ref.SetStudySubgraphValues(1, 0);

    Input_Enabled.Name = "Enabled";
    Input_Enabled.SetYesNo(true);

    Input_SendTradeOrdersToTradeService.Name = "Send Trade Orders to Trade Service";
    Input_SendTradeOrdersToTradeService.SetYesNo(false);

    Input_MaximumPositionAllowed.Name = "Maximum Position Allowed";
    Input_MaximumPositionAllowed.SetInt(0);

    Input_EvaluateOnBarCloseOnly.Name = "Evaluate on Bar Close Only";
    Input_EvaluateOnBarCloseOnly.SetYesNo(true);
    
    Subgraph_BuyEntry.Name = "Buy";
    Subgraph_BuyEntry.DrawStyle = DRAWSTYLE_CIRCLE_HOLLOW;
    Subgraph_BuyEntry.PrimaryColor = RGB(0, 255, 0);
    Subgraph_BuyEntry.LineWidth = 7;
    Subgraph_BuyEntry.DrawZeros = false;

    Subgraph_SellEntry.Name = "Sell";
    Subgraph_SellEntry.DrawStyle = DRAWSTYLE_CIRCLE_HOLLOW;
    Subgraph_SellEntry.PrimaryColor = RGB(255, 0, 0);
    Subgraph_SellEntry.LineWidth = 7;
    Subgraph_SellEntry.DrawZeros = false;

    Min_Ratchet.Name = "Minimal Counter Pick";
    Min_Ratchet.SetInt(-100);
    Min_Ratchet.SetIntLimits(-10000, -1);

    Max_Ratchet.Name = "Maximal Counter Pick";
    Max_Ratchet.SetInt(100);
    Max_Ratchet.SetIntLimits(1, 1000);

    ddOffsetInput.Name = "Display Signal Offset";
    ddOffsetInput.SetFloat(.02);
    ddOffsetInput.SetFloatLimits(.00001f, 1000);

    sc.AllowMultipleEntriesInSameDirection = false;
    sc.SupportReversals = false;

    sc.AllowOppositeEntryWithOpposingPositionOrOrders = false;

    sc.SupportAttachedOrdersForTrading = false;
    sc.UseGUIAttachedOrderSetting = true;
    sc.CancelAllOrdersOnEntriesAndReversals = true;
    sc.AllowEntryWithWorkingOrders = false;
    sc.CancelAllWorkingOrdersOnExit = true;

    // Only 1 trade for each Order Action type is allowed per bar.
    sc.AllowOnlyOneTradePerBar = true;

    //This should be set to true when a trading study uses trading functions.
    sc.MaintainTradeStatisticsAndTradesData = true;

    sc.FreeDLL = 1;      //need to change to 0 in production

    return;
  }

  sc.MaximumPositionAllowed = Input_MaximumPositionAllowed.GetInt();
  sc.SendOrdersToTradeService = Input_SendTradeOrdersToTradeService.GetYesNo();

  if (!Input_Enabled.GetYesNo())
    return;

  // only process at the close of the bar. If it has not closed do not do anything
  if (Input_EvaluateOnBarCloseOnly.GetYesNo()
    && sc.GetBarHasClosedStatus() == BHCS_BAR_HAS_NOT_CLOSED)
  {
    return;
  }

  // using the Input_Line1Ref and Input_Line2Ref input variables, retrieve the subgraph arrays
  SCFloatArray StudyLine1; //Max
  sc.GetStudyArrayUsingID(Input_Line1Ref.GetStudyID(), Input_Line1Ref.GetSubgraphIndex(), StudyLine1);
  
  SCFloatArray StudyLine2; //Min
  sc.GetStudyArrayUsingID(Input_Line2Ref.GetStudyID(), Input_Line2Ref.GetSubgraphIndex(), StudyLine2);

  SCFloatArray StudyLine3;//Close
  sc.GetStudyArrayUsingID(Input_Line3Ref.GetStudyID(), Input_Line3Ref.GetSubgraphIndex(), StudyLine3);
  
  //simplifing the caclculations
  float Max = StudyLine1[sc.Index];
  float Min = StudyLine2[sc.Index];
  float Close = StudyLine3[sc.Index];
  
  s_SCPositionData PositionData;

  if (!sc.IsFullRecalculation)
    sc.GetTradePosition(PositionData);

  // code below is where we check for crossovers and take action accordingly

  sc.SupportReversals = false;

  //long entry condition
  if (
    (StudyLine2[sc.Index] < (Min_Ratchet.GetInt()))
    
    )
  {
    // mark the crossover on the chart
    Subgraph_BuyEntry[sc.Index] = sc.Low[sc.Index] - ddOffsetInput.GetFloat();//from DD

    if (!sc.IsFullRecalculation && !sc.DownloadingHistoricalData)// i am not d.l. historical data and i am not in full recalc
    {
      if (Input_SendTradeOrdersToTradeService.GetYesNo() == true)
      {
        s_SCNewOrder NewOrder;
          NewOrder.OrderQuantity = 1;
          NewOrder.OrderType = SCT_ORDERTYPE_MARKET;
          NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED;
          int Result = (int)sc.SellExit(NewOrder);//Buy order
          if (Result < 0)
            sc.AddMessageToLog(sc.GetTradingErrorTextMessage(Result), false);
      }
    }
  }

  //short entry condition
  if (
    (StudyLine1[sc.Index] >= (Max_Ratchet.GetInt()))
    
    )
  {
    // mark the crossover on the chart
    Subgraph_SellEntry[sc.Index] = sc.High[sc.Index] + ddOffsetInput.GetFloat();//from DD

    if (!sc.IsFullRecalculation && !sc.DownloadingHistoricalData)// i am not d.l. historical data and i am not in full recalc
    {
      if (Input_SendTradeOrdersToTradeService.GetYesNo() == true)
      {
        s_SCNewOrder NewOrder;
          NewOrder.OrderQuantity = 1;
          NewOrder.OrderType = SCT_ORDERTYPE_MARKET;
          NewOrder.TimeInForce = SCT_TIF_GOOD_TILL_CANCELED;
          int Result = (int)sc.SellExit(NewOrder);//Buy order
          if (Result < 0)
            sc.AddMessageToLog(sc.GetTradingErrorTextMessage(Result), false);

      }
    }
  }
}

[2021-03-11 07:47:46]
Flipper_2 - Posts: 57
Hey? You are trying to import a subgraph from a/few studies and saying that there is no numerical values in them. I'm asking for the code for the studies you are importing/referencing from to see what values are calculated.
[2021-03-11 08:14:24]
Flipper_2 - Posts: 57
You can see what values are in the referenced sub graph by putting this code below the GetStudyArrayUsingID

SCString teststring;
teststring.Format("StudyLine1: %0.2f, Bar -1: %0.2f, Bar -2: %0.2f", StudyLine1[sc.Index], StudyLine1[sc.Index - 1], StudyLine1[sc.Index - 2]);
sc.AddMessageToLog(teststring, 0);

[2021-03-11 08:52:32]
User61576 - Posts: 418
this is study #2 (scsf_TradingSystemStudySubgraphCrossover)
if #2 and #1 are both long I want the aggregator study to execute a long trade. the aggregator study is also scsf_TradingSystemStudySubgraphCrossover
i am using scsf_TradingSystemStudySubgraphCrossover as #2 for making a decision based on macd crossover and also if there is a crossover (#2) and signal from #1, then go long
I don't need the value of the inherited values, this ones I know
I need to find the value of drawing of the signal on the chart

another option I think about is creating a value which will be given a 1/-1 value upon long/short
[2021-03-11 09:03:34]
Flipper_2 - Posts: 57
we are going in circles here. i'll leave you to it.
[2021-03-11 09:08:24]
User907968 - Posts: 804
you can see here (attached) that the signal (red down arrow) has no value
any other suggestion?

You need to use the 'Chart Values for Tools' window, called 'Tool Values Window' in the menu. In your screenshot you are using the 'Chart Values Window', which reference the last bar displayed in the chart, not where the crosshair is - i.e. what's shown in you screenshot is not the data pertaining to the correct bar.

If the arrow is drawn on the chart by a subgraph, then it will certainly have a value.

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

Login

Login Page - Create Account