Support Board
Date/Time: Wed, 27 Nov 2024 02:44:20 +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
|
kiwi14.cpp - Attached On 2014-06-30 05:45:46 UTC - Size: 15.89 KB - 676 views kiwi14.dll - Attached On 2014-06-30 05:46:31 UTC - Size: 160.5 KB - 638 views |