Support Board
Date/Time: Wed, 05 Mar 2025 04:23:05 +0000
[Programming Help] - create a custom C++ class that manages trade/logic
View Count: 1588
[2022-01-07 21:21:22] |
User133994 - Posts: 80 |
To whom it may concern, Great product--again. Thanks. I am trying to create a simple C++ class to manage trades, trading logic, etc. Basically to keep all "trade" related items/functions together, etc. However, this all must be done on an "indicator"--thus the class needs to be usable from the indicator--and be persistant. Here is what I tried (an excerpt), which finally did compile: class pSellOrder {
//p is for persistent--doesn't matter which sc.Index is used--this will always refer to the "existing" sell order //not hiding any internal variables at this point...just keeping them together..will grow this class as needed //NOTE: have to use a *pointer* to access sc functions see this discussion for more //sc. structure passed by reference as default value to all functions UPDATE: this caused problems public: //constructor to gain access to sc...I hope pSellOrder(SCStudyInterfaceRef sc):p_sc(&sc) {} int& ParentInternalOrderIDstop = p_sc->GetPersistentInt(11); int& Target1OrderIDstop = p_sc->GetPersistentInt(1); int& Stop1OrderIDstop = p_sc->GetPersistentInt(2); int& Target2OrderIDstop = p_sc->GetPersistentInt(3); int& Stop2OrderIDstop = p_sc->GetPersistentInt(4); int& Target3OrderIDstop = p_sc->GetPersistentInt(5); int& Stop3OrderIDstop = p_sc->GetPersistentInt(6); int& Target4OrderIDstop = p_sc->GetPersistentInt(7); int& Stop4OrderIDstop = p_sc->GetPersistentInt(8); //---------------------- int& ParentInternalOrderIDstop_entrybar = p_sc->GetPersistentInt(28); int& ParentInternalOrderIDstop_entrybar_writeonce = p_sc->GetPersistentInt(29); float& ParentInternalOrderIDstop_price = p_sc->GetPersistentFloat(2); int active () { return (1); } private: s_sc* p_sc; }; So I use pSellOrder pSO(sc);
in the indicator that is attached to my chart; and I set things like this: if (pSO.ParentInternalOrderIDstop != 0)
{ s_SCTradeOrder TradeOrderData; int Result = sc.GetOrderByOrderID(pSO.ParentInternalOrderIDstop, TradeOrderData); } However, I am obviously not doing it correctly because when I attach the indicator to the chart I receive this error: Warning: This Custom DLL study may cause Sierra Chart to be unstable until you remove the study from the chart and restart Sierra Chart. | 2022-01-07 14:13:09.921 *
Warning: The Custom DLL study "jjcUBTradingSysPB.scsf_jjc_TradingUB_PB" has just caused a CPU exception. | 2022-01-07 14:13:16.957 * This is likely from my use of p_sc...I am not confident that I have figured out how to access the "sc" object from my custom class. Please help. I searched and searched and there are no user-customized example classes in ACSIL that access the sc object with all of it's information on a custom study. If I missed it, please point me to a working example. Yes, there are a hundred way to do things--I know I've read much--I am just wanting to know how to use my custom built C++ class (with persistant variables) to use in a custom indicator--which requires access to the sc object inside the class. I could try it another way and I might have to...but for now, would you be able to help me figure this out? Thanks in advance! |
[2022-01-08 01:35:06] |
User133994 - Posts: 80 |
FYI... The code... class pSellOrder {...}
is defined inside the jjcUBTradingSysPB.cpp above this line: SCSFExport scsf_jjc_TradingUB_PB_entries(SCStudyInterfaceRef sc)
{...} and pSO is instantiated inside the scsf_jjc_TradingUB_PB_entries study code. Hope that provides the context needed. Date Time Of Last Edit: 2022-01-08 01:36:25
|
[2022-01-08 09:46:02] |
User99735 - Posts: 234 |
Think all local variables including class objects etc are lost after each tick. So you need to allocate memory to pSellOrder pSO(sc) using sc.StorageBlock.
|
[2022-01-08 14:23:19] |
norvik_ - Posts: 106 |
It is better have a single persistent pointer to the class instance. All data defined inside class will be persist
|
[2022-01-08 14:28:51] |
User99735 - Posts: 234 |
OK, please share the code where the pointer (preferably full code) is made persistent.
|
[2022-01-08 15:41:38] |
norvik_ - Posts: 106 |
struct some_struct
{ some_struct() = defalt; some_struct(SCStudyInterfaceRef sc) void some_func(const SCDateTimeMS& when); private: std::unordered_map<SCDateTimeMS, s_SCTradeOrder> something; } const std::int32_t some_struct_pkey = 1; SCSFExport scsf_some_study(SCStudyInterfaceRef sc) { some_struct* ss = reinterpret_cast<some_struct*>(sc.GetPersistentPointer(some_struct_pkey)); if (ss == nullptr) sc.SetPersistentPointer(some_struct_pkey, new some_struct(sc)); if (sc.SetDefaults) { // Do something... } // Do something... if(sc.LastCallToFunction) delete ss; } It is documented on this site. |
[2022-01-08 18:15:41] |
Bet_More_Tim - Posts: 21 |
This might be of interest, idk, but here is an example template of using a controller class persistent pointer to manage study class instance, a static factory, which manages the lifecycle of an acsil study (c++ design pattern implemented with assistance thanks to a very helpful SC user!) Basically the same as above, but you can have multiple studies being controlled https://github.com/TimJones7/SierraChart_ACSIL_Template *btw this is a good starting point to build off, I'm still working on touching it up and adding comments and such I'm not 100% sure, (still learning myself) but if class vars are made static, won't they remain in memory for the duration of the program and not just when the function that 'created' them (aka acsil entryway) goes out of scope? Date Time Of Last Edit: 2022-01-08 18:18:14
|
[2022-01-09 02:42:48] |
User133994 - Posts: 80 |
All--thanks so much for your help. I'd rather not have to deal with StorageBlocks. I really didn't think to look for persistent pointers--found this example (WAY TOO COMPLEX) : \ACS_Source\RequestValuesFromServerAndDraw.cpp ;and, I saw the very limited documentation on the website. Really grateful for norvik_ 's simple example--excellent. Looks like I'll have to use new and delete--as long as norvik's example is sufficient. Bet_More_Tim--I downloaded your code--very amazing endeavour--again, too complex for my approach--but I definitely like the c++ classes. |
[2022-01-09 02:57:07] |
User133994 - Posts: 80 |
Can I do this now: struct some_struct
{ some_struct() = default; some_struct(SCStudyInterfaceRef sc) void some_func(const SCDateTimeMS& when); void record_ID(int a){ Target2OrderIDstop = a;}; void example_using_sc_inside(){sc.SupportTradingScaleIn = true;}; private: std::unordered_map<SCDateTimeMS, s_SCTradeOrder> something; int Target2OrderIDstop; } const std::int32_t some_struct_pkey = 1; SCSFExport scsf_some_study(SCStudyInterfaceRef sc) { some_struct* ss = reinterpret_cast<some_struct*>(sc.GetPersistentPointer(some_struct_pkey)); if (ss == nullptr) sc.SetPersistentPointer(some_struct_pkey, new some_struct(sc)); if (sc.SetDefaults) { // Do something... } //sent order in... // now record attached order id ss->record_ID(12356173); ss->example_using_sc_inside(); // Do something... if(sc.LastCallToFunction) delete ss; } So, is the syntax for my record_ID function correct? Can I safely assume that the value of Target2OrderIDstop persists across calls to the study? Therefore, it appears I don't need to use sc.GetPersistentInt(11) anymore--since the class (struct) is persistent, right? What about the example_using_sc_inside() function--just trying to use the "sc" object that was passed via the constructor--is that correct? Or do I need to add a member to the struct that gets assigned the sc, object? (please reply with example code if possible) Again, many thanks! |
[2022-01-09 10:03:29] |
User99735 - Posts: 234 |
it appears I don't need to use sc.GetPersistentInt(11) anymore--since the class (struct) is persistent, right? The class is persistent, but the pointer to the class is not persistent. sc.SetPersistentPointer(some_struct_pkey, new some_struct(sc)); This line can be moved to the sc.SetDefaults block, without null check, to ensure that the structure is always initialized at startup. |
[2022-01-09 10:51:03] |
User431178 - Posts: 604 |
sc.SetPersistentPointer(some_struct_pkey, new some_struct(sc));
This line can be moved to the sc.SetDefaults block, without null check, to ensure that the structure is always initialized at startup. I'm not going to wade into the rest of this thread, but this is bad advice, as it will leak memory. SetDefaults block also runs when opening the add custom study window, meaning that you will create objects and never destroy them. Date Time Of Last Edit: 2022-01-09 10:51:25
|
[2022-01-11 03:23:32] |
User133994 - Posts: 80 |
I'll answer my own questions: Yes, I can do what I wrote above...with a couple notes: note 1: in order to use sc object...I must pass it in each time... thus some_struct(SCStudyInterfaceRef sc)
Anyone know how to make a private member point to SCStudyInterfaceRef sc? That would be ideal and sc wouldn't need to be an input to every single function that uses it. void example_using_sc_inside(SCStudyInterfaceRef sc){sc.SupportTradingScaleIn = true;}; note 2: Don't have this study loaded on a chart when you recompile it--Sierra Chart crashes immediately without warning (likely due to using new/delete, maybe something else) note 3: to make use the new struct object in the scsf_some_study study, here are some example uses: ss->record_ID(12356173); ss->localID = 3843028; // if you had a public member of data type int called localID int studyspaceID = ss->localID; // could also create a "get" function and keep localID private ss->example_using_sc_inside(sc); note 4: add a semicolon after the struct definition struct some_struct { . . . }; Also, REMOVE this line: std::unordered_map<SCDateTimeMS, s_SCTradeOrder> something;
it causes compiler issues--and I don't need a hash right now anyway.I am sure I missed some things or didn't do it optimally, however, I can vouch that the above works as advertised. Please do share any improvements, corrections, or other. So glad it is working...wow. Excellent foundation to begin on. Thanks all |
To post a message in this thread, you need to log in with your Sierra Chart account: