Support Board
Date/Time: Wed, 27 Nov 2024 00:43:09 +0000
[User Discussion] - Getting Timely and Accurate IB Data (Interactive Brokers) with version 1148+
View Count: 1554
[2014-06-20 02:13:18] |
Kiwi - Posts: 375 |
With version 1148 it seems that the ability to receive both live and TD (5 second) data from IB has been removed. This seems to result in a choice of either: - live data which misses bar highs and lows from time to time (100ms snapshots of price); or - 5 second data which is 5 seconds late so the current bar can be 5 or 10 ticks behind price also the new bar doesn't start for 5 seconds so automated systems might be challenged In 1131 I can collect 5 second data on one chart and live data on another and then a DLL function combines them onto one of the charts that displays current price, forms a new bar immediately on the first transaction after the old one, and is corrected for any missing data when the next 5 second bar arrives. Have I misinterpretted your objective or set this up incorrectly? I guess I see this as a fairly serious loss of functionality unless I making a mistake in setting up 1148. Date Time Of Last Edit: 2014-06-20 02:18:46
|
[2014-06-20 02:23:22] |
Sierra Chart Engineering - Posts: 104368 |
You can use two copies of Sierra Chart. One can use IB True Real-time data and another one not. By sharing data between instances, you should be able to accomplish what you require: https://www.sierrachart.com/index.php?l=doc/MultipleServices.html You should also be able to implement some kind of solution even in a single instance by using the True real-time data option and accessing the IB standard data feed through the Time and Sales array: https://www.sierrachart.com/index.php?l=doc/doc_ACSIL_Members_Functions.html#scGetTimeAndSales And combining them together. The support for -TD symbols was removed because the implementation was very complex and hard to understand and we were always subscribing to true real-time data, even though the user was not using the option. Once this was removed, the code was greatly cleaned up and this should have been done long ago. It just did not make sense with the way this was all designed. Sierra Chart Support - Engineering Level Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy: https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service: Sierra Chart Teton Futures Order Routing Date Time Of Last Edit: 2014-06-20 03:08:27
|
[2014-06-20 02:48:31] |
Kiwi - Posts: 375 |
OK. Thanks. That makes sense - I hadn't gone mad. Two instances gets pretty ugly (too much to expect a new SC customer to manage I think) so I think the second would be the better approach. I guess kiwi14.dll and a new truelive are coming soon. I'll have to have a look at the time and sales array. The trickiest thing is that it needs to form new bars as soon after the close time for the last bar as a new transaction price becomes available. If I can get it right then it should also be a lot tidier than the current true live approach - just set SC to use 5 second data and run the dll to fix the charts in real time. Date Time Of Last Edit: 2014-06-20 02:50:39
|
[2014-06-20 03:50:18] |
Sierra Chart Engineering - Posts: 104368 |
(too much to expect a new SC customer to manage I think) It is not likely new users would be using your set up. Most likely they are using our integrated data feeds now. At least we think so.
Sierra Chart Support - Engineering Level Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy: https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service: Sierra Chart Teton Futures Order Routing Date Time Of Last Edit: 2014-06-20 03:51:18
|
[2014-06-20 04:21:50] |
Kiwi - Posts: 375 |
Are you providing integrated feeds for the Asian and European exchanges now? I always assume HSI will be hard to come by. |
[2014-06-21 23:36:22] |
Kiwi - Posts: 375 |
First version (ignore inputs and commented out code which relate to my personal requirements): /*==========================================================================*/ 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 oo = sc.Subgraph[10], oh = sc.Subgraph[11], ol = sc.Subgraph[12], oc = sc.Subgraph[13], ov = sc.Subgraph[14], ot = sc.Subgraph[15], o2 = sc.Subgraph[22], o3 = sc.Subgraph[23], o4 = sc.Subgraph[24], o5 = sc.Subgraph[25], o6 = sc.Subgraph[26], o7 = sc.Subgraph[27]; if (sc.SetDefaults) { sc.GraphName = "TrueLive"; 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"; oO.Name="oO"; oH.Name="oH"; oL.Name="oL"; oC.Name="oC"; oV.Name="oV"; oT.Name="oT"; o2.Name="o2"; o3.Name="o3"; o4.Name="o4"; o5.Name="o5"; o6.Name="o6"; o7.Name="o7"; sc.Input[4].Name = "Fixed Scale (Set Value)"; sc.Input[4].SetFloat(180); sc.Input[5].Name = "Scale Increment"; sc.Input[5].SetFloat(5); sc.Input[6].Name = "Offset LO change direcLIon"; sc.Input[6].SetFloat(1.5); sc.Input[7].Name = "Use Centred (vs Const Range)"; sc.Input[7].ValueType=YESNO_VALUE; sc.Input[8].Name = "Show Inside Bars"; sc.Input[8].ValueType=YESNO_VALUE; 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& ChartNumber = sc.PersistVars->i3; int& lastVis = sc.PersistVars->i4; float& offset = sc.Input[6].FloatValue; float& ActiveToolIndex = sc.PersistVars->f1; double& CurrentBarTime = sc.PersistVars->d1; int i, j, as = sc.ArraySize-1; int ap = as - 1; int& seqno = sc.PersistVars->i1; if (sc.UpdateStartIndex == 0) { int os = 0; // os stores the position of the out array seqno = 0; 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; } } // First deal with underlying data int os = sc.OutArraySize-1; // add an extra bar if the underlying is later than the output bar if( sc.BaseDateTimeIn[as] > sc.DateTimeOut[os] ) { 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]) { // update this bar oO[os] = O[as]; oH[os] = max(H[as], oH[os]); oL[os] = min(L[as], oL[os]); 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]); oC[op] = C[as]; oV[op] = V[as]; oT[op] = T[as]; } // then look at live data SCTimeAndSalesArray TSArray; sc.GetTimeAndSales(TSArray); int ts = TSArray.GetArraySize() - 1; o4[os] = 0; o2[os] = TSArray[ts].Sequence - seqno; o3[os] = TSArray[ts].Sequence; if (ts >= 0 && TSArray[ts].Sequence > seqno) { int tp = ts, adjt = sc.TimeScaleAdjustment.GetTime(); double adj = sc.TimeScaleAdjustment; while (TSArray[tp].Sequence > seqno) {tp--;} // tp++; // iterate through each time & sales value o5[os] = TSArray[tp].DateTime.GetTime() + adjt; o6[os] = sc.DateTimeOut[os].GetTime() + sc.SecondsPerBar; for ( ; tp <= ts; tp++) { if (TSArray[tp].DateTime.GetTime() + adjt >= sc.DateTimeOut[os].GetTime() + sc.SecondsPerBar) { os++; sc.AddElements(1); sc.DateTimeOut[os] = TSArray[tp].DateTime + adj; oO[os] = oH[os] = oL[os] = oC[os] = TSArray[tp].Price; oV[os] = TSArray[tp].Volume; o7[os] += 1; } else if (TSArray[tp].DateTime.GetTime() + adjt >= sc.DateTimeOut[os].GetTime()) { 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; oV[os] += TSArray[tp].Volume; } } seqno = TSArray[ts].Sequence; } 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; // // Swing Colour Marking // if(sc.UpdateStartIndex < sc.OutArraySize) // i = sc.UpdateStartIndex-1; // else // i = sc.OutArraySize-1; // for ( ; i <= os; i++) { // int updown=(int)sc.Subgraph[15][i-1]; // if(updown==0) updown=1; // float lowesLHigh=sc.Subgraph[17][i-1]; // float highesLLow=sc.Subgraph[18][i-1]; // float& h = sc.Subgraph[1][i]; // float& l = sc.Subgraph[2][i]; // // if(updown== 1) { if(l>highesLLow) highesLLow=l; } // else { if(h<lowesLHigh) lowesLHigh=h; } // // if(h>lowesLHigh+offset && l>=sc.Subgraph[2][i-1]-offset) { // updown=1; highesLLow=l; lowesLHigh=h; // } // else if(l<highesLLow-offset && h<=sc.Subgraph[1][i-1]+offset) { // updown=-1;lowesLHigh=h; highesLLow=l; // } // // if(((L[i] > L[i-1] && H[i] <= H[i-1]) || // (L[i] >= L[i-1] && H[i] < H[i-1])) && sc.Input[8].BooleanValue) { // oO.DataColor[i] = oH.DataColor[i] = sc.Subgraph[7].PrimaryColor; // oL.DataColor[i] = oC.DataColor[i] = sc.Subgraph[7].PrimaryColor; // } else if(updown==1) { // oO.DataColor[i] = oH.DataColor[i] = sc.Subgraph[6].PrimaryColor; // oL.DataColor[i] = oC.DataColor[i] = sc.Subgraph[6].PrimaryColor; // } else if(updown==-1) { // oO.DataColor[i] = oH.DataColor[i] = sc.Subgraph[6].SecondaryColor; // oL.DataColor[i] = oC.DataColor[i] = sc.Subgraph[6].SecondaryColor; // } // // sc.Subgraph[15][i]=updown; // sc.Subgraph[17][i]=lowesLHigh; // sc.Subgraph[18][i]=highesLLow; // } // // // Scale adjustments driven by LogariLHmic trigger // if(sc.ActiveToolIndex!=0) ActiveToolIndex=sc.ActiveToolIndex; // if(sc.ScaleType == SCALE_LOGARITHMIC || sc.UpdateStartIndex == 0) { // if(ActiveToolIndex <= sc.IndexOfLastVisibleBar && ActiveToolIndex > as-50) // lastVis=as; // else lastVis=sc.IndexOfLastVisibleBar; // // float mid=sc.Subgraph[3][lastVis-1], high=sc.Subgraph[1][lastVis], // low=sc.Subgraph[2][lastVis], userrange=sc.Input[4].FloatValue; // for(j=1;j<100;j++) { // if(high<sc.Subgraph[1][lastVis-j]) high=sc.Subgraph[1][lastVis-j]; // if(low>sc.Subgraph[2][lastVis-j]) low=sc.Subgraph[2][lastVis-j]; // } // // if((high-low)<=userrange) mid=(high+low)/2; // else if((mid-userrange/2)<low) mid=low+userrange/2-2; // else if((mid+userrange/2)>high) mid=high-userrange/2+2; // sc.ScaleRangeTop=mid+userrange/2; // sc.ScaleRangeBottom=mid-userrange/2; // // sc.Subgraph[9][as] = sc.ActiveToolIndex; // sc.Subgraph[9][as-1] = sc.IndexOfLastVisibleBar; // sc.Subgraph[9][as-1]=lastVis; // // if(sc.ScaleType == SCALE_LOGARITHMIC) { if(sc.ScaleRangeType==SCALE_AUTO) { // if(sc.Input[5].FloatValue != 0) sc.ScaleIncrement = sc.Input[5].FloatValue; // if(sc.Input[4].BooleanValue) { // if(sc.Input[7].BooleanValue) { // sc.ScaleRangeType=SCALE_CONSTRANGECENTER; // sc.ScaleConstRange=sc.Input[4].GetFloat(); // } // else sc.ScaleRangeType=SCALE_USERDEFINED; // } // } else { // sc.ScaleIncrement = sc.Input[5].FloatValue; // sc.ScaleRangeType= sc.ScaleRangeType=SCALE_AUTO; // } // sc.ScaleType = SCALE_LINEAR; // } // } } Date Time Of Last Edit: 2014-06-21 23:42:57
|
[2014-06-22 01:53:03] |
Sierra Chart Engineering - Posts: 104368 |
Not Asian futures. But European futures and stocks through the following services: Sierra Chart Exchange Data Feed TeleTrader In the case of TeleTrader, mapping to IB symbols is not yet been done but can be implemented. The problem with Hong Kong futures, is that it is just too expensive. Like most exchanges they charge a lot. Sierra Chart Support - Engineering Level Your definitive source for support. Other responses are from users. Try to keep your questions brief and to the point. Be aware of support policy: https://www.sierrachart.com/index.php?l=PostingInformation.php#GeneralInformation For the most reliable, advanced, and zero cost futures order routing, *change* to the Teton service: Sierra Chart Teton Futures Order Routing Date Time Of Last Edit: 2014-06-22 01:53:24
|
[2014-06-23 03:58:39] |
Kiwi - Posts: 375 |
Thanks for the information. I've built a new TrueLive that uses T&S data to create a responsive but accurate chart (on time charts ONLY). It is considerably more efficient than the old style with no need for extra charts and with tidier code. So its an improvement all around! TrueLive 2014 for SC V1149 Onwards If you want to include it as part of the base platform at any stage, feel free. :-) John Date Time Of Last Edit: 2014-06-23 04:00:48
|
To post a message in this thread, you need to log in with your Sierra Chart account: