Login Page - Create Account

Support Board


Date/Time: Fri, 10 May 2024 03:22:44 +0000



Post From: TrueLive 2014 for SC V1149 Onwards

[2014-06-30 05:43:44]
Kiwi - Posts: 375
Thanks for that. To avoid the risk of getting it wrong I've just used a persistent variable to store "lasttime" that a bar was received. When you reload the data it picks up an earlier time which is more than 2 bars from the last bar of the reloaded data - this forces it to rebuild the chart so there is no possibility of a discontinutity.

The changes are on the lines including the integer lasttime.

If you don't change to this version you simply need to press insert to refresh the chart after you reload the data.


/*==========================================================================*/
SCSFExport scsf_TrueLive_2014(SCStudyInterfaceRef sc) {

SCFloatArray& O = sc.BaseDataIn[0], H = sc.BaseDataIn[1],
L = sc.BaseDataIn[2], C = sc.BaseDataIn[3],
V = sc.BaseDataIn[4], T = sc.BaseDataIn[5];
SCSubgraphRef oO = sc.Subgraph[0], oH = sc.Subgraph[1],
oL = sc.Subgraph[2], oC = sc.Subgraph[3],
oV = sc.Subgraph[4], oT = sc.Subgraph[5];
SCSubgraphRef o = sc.Subgraph[10], h = sc.Subgraph[11],
l = sc.Subgraph[12], c = sc.Subgraph[13],
v = sc.Subgraph[14], t = sc.Subgraph[15],
o2 = sc.Subgraph[22], o3 = sc.Subgraph[23],
o4 = sc.Subgraph[24], o5 = sc.Subgraph[25];

if (sc.SetDefaults) {
sc.GraphName = "TrueLive 2014";
sc.StudyDescription = "True Live using Custom Chart 2014 Release";
sc.Subgraph[0].Name = "Open";
sc.Subgraph[1].Name = "High";
sc.Subgraph[2].Name = "Low";
sc.Subgraph[3].Name = "Last";
sc.Subgraph[4].Name = "Volume";
sc.Subgraph[5].Name = "# of Trades";
sc.Subgraph[6].Name = "HL";
sc.Subgraph[7].Name = "HLC";
sc.Subgraph[8].Name = "OHLC";
o2.Name="o2"; o3.Name="o3";
o4.Name="o4"; o5.Name="o5";
sc.GraphRegion = 0; // First region
sc.GraphDrawType = GDT_CANDLESTICK;
sc.DisplayAsMainPriceGraph=1;
sc.IsCustomChart = 1;
sc.UpdateAlways=1;
sc.DrawZeros=0;
return;
}
// sc.FreeDLL = 1;

int as = sc.ArraySize-1;
int ap = as - 1;
int& seqno = sc.PersistVars->i1;
int& tnsno = sc.PersistVars->i2;
int& lasttime = sc.PersistVars->i10;
SCTimeAndSalesArray TSArray;
sc.GetTimeAndSales(TSArray);
int ts = TSArray.GetArraySize() - 1;

// lasttime is used to detect that data has been reloaded so
  // the chart needs to be refreshed
  if (sc.UpdateStartIndex == 0 || sc.BaseDateTimeIn[as].GetTime() >
     lasttime + sc.SecondsPerBar + sc.SecondsPerBar) {
int os = 0; // os stores the position of the out array
tnsno = seqno = 0;
if (ts >= 0)
seqno = TSArray[ts].Sequence;
sc.ResizeArrays(0);
for ( ; os < sc.ArraySize; os++) {
sc.AddElements(1);
sc.DateTimeOut[os] = sc.BaseDateTimeIn[os];
oO[os] = O[os];
oH[os] = H[os];
oL[os] = L[os];
oC[os] = C[os];
oV[os] = V[os];
oT[os] = T[os];
sc.Subgraph[SC_HL][os] = (oH[os] + oL[os]) / 2;
sc.Subgraph[SC_HLC][os] = (oH[os] + oL[os] + oC[os]) / 3;
sc.Subgraph[SC_OHLC][os] = (oH[os] + oL[os] + oC[os] + oO[os]) / 4;
lasttime = sc.DateTimeOut[os].GetTime();
}
}

// First deal with underlying data
int os = sc.OutArraySize-1;
lasttime = sc.BaseDateTimeIn[as].GetTime();
// add an extra bar if the underlying is later than the output bar
if( sc.BaseDateTimeIn[as] > sc.DateTimeOut[os] ) {
// only add element if there isn't a spurious t&s element present
if(tnsno == 0) os++;
sc.AddElements(1);
sc.DateTimeOut[os] = sc.BaseDateTimeIn[as];
oO[os] = oH[os] = oL[os] = oC[os] = O[as];
}
int op = os - 1;
if (sc.DateTimeOut[os] == sc.BaseDateTimeIn[as]) {
// Only apply 5 second data if its changed (ie dont reset live changes)
if(c[os] != C[as] || v[os] != V[as] || h[os] != H[as] || l[os] != L[as])
{
tnsno = 0;
h[os] = H[as]; l[os] = L[as];
c[os] = C[as]; v[os] = V[as];
// update this bar
oO[os] = O[as]; oH[os] = H[as];
oL[os] = L[as]; // oC[os] = C[as];
oV[os] = V[as]; oT[os] = T[as];
// match prior bar to 5 second data
oO[op] = O[ap]; oH[op] = H[ap];
oL[op] = L[ap]; oC[op] = C[ap];
oV[op] = V[ap]; oT[op] = T[ap];
}
}
else if (sc.DateTimeOut[op] == sc.BaseDateTimeIn[as]) {
// must be in first 5 seconds of new bar so
// update prior bar with 5 second data
oO[op] = O[as];
oH[op] = max(H[as], oH[op]);
oL[op] = min(L[as], oL[op]);
if (sc.CurrentSystemDateTime.GetTime() >
sc.BaseDateTimeIn[as].GetTime() + sc.SecondsPerBar + 15) {
oC[op] = C[as];
}
oV[op] = V[as]; oT[op] = T[as];
}

// then look at live data
if (ts >= 0 && TSArray[ts].Sequence > seqno) {
int tp = ts;
int adjt = sc.TimeScaleAdjustment.GetTime();
double adj = sc.TimeScaleAdjustment;
while (TSArray[tp].Sequence > seqno) {tp--;}
// iterate through each time & sales value
for ( ; tp <= ts; tp++) {
// if its a new bar start one
if (tnsno == 0 && TSArray[tp].DateTime.GetTime() + adjt >=
sc.DateTimeOut[os].GetTime() + sc.SecondsPerBar) {
tnsno = 1; // flag that a time&sales bar has been created
os++;
sc.AddElements(1);
sc.DateTimeOut[os].SetDate(sc.DateTimeOut[as].GetDate());
sc.DateTimeOut[os].SetTime(sc.DateTimeOut[as].GetTime() +
sc.SecondsPerBar);
// note that for new session this bar time is wrong
// and it will be cancelled as spurious so the new bar
// will be formed when the first 5 sec bar arrives
oO[os] = oH[os] = oL[os] = oC[os] = TSArray[tp].Price;
oV[os] = TSArray[tp].Volume;
}
// else update high low and close for this bar
else if (TSArray[tp].DateTime.GetTime() + adjt >=
sc.DateTimeOut[os].GetTime() &&
TSArray[tp].DateTime.GetTime() + adjt <
sc.DateTimeOut[os].GetTime() + sc.SecondsPerBar) {
oH[os] = max(TSArray[tp].Price, oH[os]);
if (TSArray[tp].Price > 0 && oL[os] > 0)
oL[os] = min(TSArray[tp].Price, oL[os]);
else
oL[os] = max(TSArray[tp].Price, oL[os]);
oC[os] = TSArray[tp].Price;
}
}
seqno = TSArray[ts].Sequence;
}
// Check for spurious time & sales based bars (> 10 seconds with no 5sec)
if(tnsno != 0) {
// spurious if no 5 second confirmation within 15 seconds
if(sc.CurrentSystemDateTime.GetDate() > sc.DateTimeOut[os].GetDate() ||
sc.CurrentSystemDateTime.GetTime() > sc.DateTimeOut[os].GetTime()
+ 15) {
sc.AddElements(-1);
tnsno = 0;
}
}

sc.Subgraph[SC_HL][os] = (oH[os] + oL[os]) / 2;
sc.Subgraph[SC_HLC][os] = (oH[os] + oL[os] + oC[os]) / 3;
sc.Subgraph[SC_OHLC][os] = (oH[os] + oL[os] + oC[os] + oO[os]) / 4;
sc.Subgraph[SC_HL][op] = (oH[op] + oL[op]) / 2;
sc.Subgraph[SC_HLC][op] = (oH[op] + oL[op] + oC[op]) / 3;
sc.Subgraph[SC_OHLC][op] = (oH[op] + oL[op] + oC[op] + oO[op]) / 4;
}

Date Time Of Last Edit: 2014-06-30 05:47:08
attachmentkiwi14.cpp - Attached On 2014-06-30 05:45:46 UTC - Size: 15.89 KB - 530 views
attachmentkiwi14.dll - Attached On 2014-06-30 05:46:31 UTC - Size: 160.5 KB - 484 views