Support Board
Date/Time: Thu, 26 Dec 2024 05:40:15 +0000
Orderflowanalytics-style reversal bars.
View Count: 32095
[2013-09-13 23:45:49] |
marcovth - Posts: 61 |
Hello ... I have been watching this particular Orderflowanalytics video which gives a clue about the type of custom made reversal bars they are using. www.screencast.com/users/OFANinjaLibrary/folders/OFAFREE/media/53c943cc-beaf-4e2f-825c-ee68cb011578 He speaks about at least an 8 tick directional move (I assume 8+ ticks from Low to High or High to low) and then a 4 tick reversal before a new bar is printed. Of course they can change these settings. I have been testing all the bars in SC (including the reversal bar and PnF bars) but non of them look the same. The closest bar type I have seen is Better Renko, written by "aslan"? Since there is no private message system, I will ask all of you: Is there some one who can help me to modify the Better Renko code so that you can set the directional move distance and reversal size? I have tried to change some of the code, but it all became messed up. Thanks in advance. // // BetterRenko // // written by aslan // // 20101215 - initial version for SC // 20110111 - fixed OHLC averages, removed showWicks to allow other bar types // #include "sierrachart.h" SCDLLName("BetterRenko") inline void br_MoveLimits(SCStudyGraphRef sc, float high, float low, float brickSize, int revMult, float& renkoHigh, float& renkoLow) { if (sc.FormattedEvaluate(high, sc.ValueFormat, GREATER_EQUAL_OPERATOR, renkoHigh, sc.ValueFormat)) { do { renkoHigh += brickSize; renkoLow = renkoHigh - ((revMult+1) * brickSize); } while (sc.FormattedEvaluate(high, sc.ValueFormat, GREATER_OPERATOR, renkoHigh, sc.ValueFormat)); // stops if price in range, including edge } else { do { renkoLow -= brickSize; renkoHigh = renkoLow + ((revMult+1) * brickSize); } while (sc.FormattedEvaluate(low, sc.ValueFormat, LESS_OPERATOR, renkoLow, sc.ValueFormat)); } } inline void br_CheckBarComplete(SCStudyGraphRef sc, float high, float low, float brickSize, int revMult, float& renkoHigh, float& renkoLow, int& barComplete) { if (sc.FormattedEvaluate(high, sc.ValueFormat, EQUAL_OPERATOR, renkoHigh, sc.ValueFormat) || sc.FormattedEvaluate(low, sc.ValueFormat, EQUAL_OPERATOR, renkoLow, sc.ValueFormat)) { barComplete = true; br_MoveLimits(sc, high, low, brickSize, revMult, renkoHigh, renkoLow); // will move limits once since equal } else barComplete = false; } inline bool br_RangeExceeded(SCStudyGraphRef sc, float high, float low, float& renkoHigh, float& renkoLow) { return sc.FormattedEvaluate(high, sc.ValueFormat, GREATER_OPERATOR, renkoHigh, sc.ValueFormat) || sc.FormattedEvaluate(low, sc.ValueFormat, LESS_OPERATOR, renkoLow, sc.ValueFormat); } // macros for bar creation/updates, handles tick or bar inputs #define UPDATE_OPENS() \ /* set renkoOpen based on brick size and price action */\ if (Close[o] > Open[o]) \ RenkoOpen[o] = max(Close[o] - brickSize, Low[o]); \ else \ RenkoOpen[o] = min(Close[o] + brickSize, High[o]); \ \ /* adjust open to show RenkoOpen instead of real open */\ if (showRealOpen.GetYesNo() == 0) \ { \ float temp = Open[o]; \ Open[o] = RenkoOpen[o]; \ RenkoOpen[o] = temp; \ } \ #define ADD_BAR() \ sc.AddElements(1); \ o++; \ sc.DateTimeOut[o] = sc.BaseDateTimeIn[i]; \ Open[o] = iOpen[i]; \ High[o] = iHigh[i]; \ Low[o] = iLow[i]; \ Close[o] = iClose[i]; \ Volume[o] = iVolume[i]; \ Ticks[o] = iTicks[i]; \ sc.CalculateOHLCAverages(o); \ BidVol[o] = iBidVol[i]; \ AskVol[o] = iAskVol[i]; \ UpTickVol[o] = iUpTickVol[i]; \ DownTickVol[o] = iDownTickVol[i]; \ BidTrades[o] = iBidTrades[i]; \ AskTrades[o] = iAskTrades[i]; \ RenkoOpen[o] = iOpen[i] #define UPDATE_BAR() \ if (iHigh[i] > High[o]) High[o] = iHigh[i]; \ if (iLow[i] < Low[o]) Low[o] = iLow[i]; \ Close[o] = iClose[i]; \ Volume[o] += iVolume[i]; \ Ticks[o] += iTicks[i]; \ sc.CalculateOHLCAverages(o); \ BidVol[o] += iBidVol[i]; \ AskVol[o] += iAskVol[i]; \ UpTickVol[o] += iUpTickVol[i]; \ DownTickVol[o] += iDownTickVol[i]; \ BidTrades[o] += iBidTrades[i]; \ AskTrades[o] += iAskTrades[i]; \ RenkoOpen[o] = iClose[i] SCSFExport scsf_BetterRenko(SCStudyGraphRef sc) { // input refs SCInputRef brickSizeTicks = sc.Input[0]; SCInputRef alignToBrickSize = sc.Input[1]; SCInputRef showRealOpen = sc.Input[2]; SCInputRef reverseMultiplier = sc.Input[3]; // input bar refs SCFloatArrayRef iOpen = sc.BaseDataIn[0]; SCFloatArrayRef iHigh = sc.BaseDataIn[1]; SCFloatArrayRef iLow = sc.BaseDataIn[2]; SCFloatArrayRef iClose = sc.BaseDataIn[3]; SCFloatArrayRef iVolume = sc.BaseDataIn[4]; SCFloatArrayRef iTicks = sc.BaseDataIn[5]; SCFloatArrayRef iBidVol = sc.BaseDataIn[9]; SCFloatArrayRef iAskVol = sc.BaseDataIn[10]; SCFloatArrayRef iUpTickVol = sc.BaseDataIn[11]; SCFloatArrayRef iDownTickVol = sc.BaseDataIn[12]; SCFloatArrayRef iBidTrades = sc.BaseDataIn[13]; SCFloatArrayRef iAskTrades = sc.BaseDataIn[14]; // ouput bar refs SCSubgraphRef Open = sc.Subgraph[0]; SCSubgraphRef High = sc.Subgraph[1]; SCSubgraphRef Low = sc.Subgraph[2]; SCSubgraphRef Close = sc.Subgraph[3]; SCSubgraphRef Volume = sc.Subgraph[4]; SCSubgraphRef Ticks = sc.Subgraph[5]; SCSubgraphRef OHLCAvg = sc.Subgraph[6]; SCSubgraphRef HLCAvg = sc.Subgraph[7]; SCSubgraphRef HLAvg = sc.Subgraph[8]; SCSubgraphRef BidVol = sc.Subgraph[9]; SCSubgraphRef AskVol = sc.Subgraph[10]; SCSubgraphRef UpTickVol = sc.Subgraph[11]; SCSubgraphRef DownTickVol = sc.Subgraph[12]; SCSubgraphRef BidTrades = sc.Subgraph[13]; SCSubgraphRef AskTrades = sc.Subgraph[14]; SCSubgraphRef RenkoOpen = sc.Subgraph[15]; // Renko Open or True Open based on input value // Set configuration variables if (sc.SetDefaults) { // Set the defaults sc.GraphName = "BetterRenko"; sc.StudyDescription = "BetterRenko custom chart."; sc.IsCustomChart = 1; sc.DisplayAsMainPriceGraph = 1; sc.GraphRegion = 0; sc.StandardChartHeader = 1; sc.DrawZeros = 0; sc.GraphDrawType = GDT_CANDLESTICK; sc.AutoLoop = 0; sc.FreeDLL = 1; sc.ValueFormat = sc.BaseGraphValueFormat; // Inputs brickSizeTicks.Name = "Brick size (ticks):"; brickSizeTicks.SetInt(4); alignToBrickSize.Name = "Align to brick size:"; alignToBrickSize.SetYesNo(1); showRealOpen.Name = "Show real Open (vs Renko Open):"; showRealOpen.SetYesNo(0); reverseMultiplier.Name = "Reverse multiplier (number of bricks):"; reverseMultiplier.SetInt(2); reverseMultiplier.SetIntLimits(1, 20); // Subgraphs Open.Name = "Open"; Open.DrawStyle = DRAWSTYLE_LINE; Open.PrimaryColor = RGB(0,200,0); High.Name = "High"; High.DrawStyle = DRAWSTYLE_LINE; High.PrimaryColor = RGB(0,0,0); Low.Name = "Low"; Low.DrawStyle = DRAWSTYLE_LINE; Low.PrimaryColor = RGB(200,0,0); Close.Name = "Close"; Close.DrawStyle = DRAWSTYLE_LINE; Close.PrimaryColor = RGB(0,0,0); Volume.Name = "Volume"; Volume.DrawStyle = DRAWSTYLE_IGNORE; Ticks.Name = "# of Trades"; Ticks.DrawStyle = DRAWSTYLE_IGNORE; OHLCAvg.Name = "OHLC Avg"; OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE; HLCAvg.Name = "HLC Avg"; HLCAvg.DrawStyle = DRAWSTYLE_IGNORE; HLAvg.Name = "HL Avg"; HLAvg.DrawStyle = DRAWSTYLE_IGNORE; BidVol.Name = "Bid Vol"; BidVol.DrawStyle = DRAWSTYLE_IGNORE; AskVol.Name = "Ask Vol"; AskVol.DrawStyle = DRAWSTYLE_IGNORE; UpTickVol.Name = "Up Tick Vol"; UpTickVol.DrawStyle = DRAWSTYLE_IGNORE; DownTickVol.Name = "Down Tick Vol"; DownTickVol.DrawStyle = DRAWSTYLE_IGNORE; BidTrades.Name = "Bid Trades"; BidTrades.DrawStyle = DRAWSTYLE_IGNORE; AskTrades.Name = "Ask Trades"; AskTrades.DrawStyle = DRAWSTYLE_IGNORE; RenkoOpen.Name = "Renko/True Open"; RenkoOpen.DrawStyle = DRAWSTYLE_IGNORE; return; } //try //{ long i = 0; // input index - underlying chart long o = 0; // output index - renko chart float cum = 0; // calc cumulative delta // refs to persistent vars float& brickSize = sc.PersistVars->f1; // brickSize in terms of price float& renkoHigh = sc.PersistVars->f2; // renkoHigh float& renkoLow = sc.PersistVars->f3; // renkoLow int& lastIndex = sc.PersistVars->i1; // lastIndex processed int& barComplete = sc.PersistVars->i2; // barComplete if (sc.UpdateStartIndex == 0) { // clear existing chart data sc.ResizeArrays(0); // init state i.e. persist vars brickSize = sc.RoundToTickSize(brickSizeTicks.GetInt() * sc.TickSize, sc.TickSize); lastIndex = -1; barComplete = false; sc.ValueFormat = sc.BaseGraphValueFormat; sc.GraphName.Format("BetterRenko %i", brickSizeTicks.GetInt()); RenkoOpen.Name = showRealOpen.GetYesNo() ? "True Open" : "Renko Open"; } // do data processing o = sc.OutArraySize - 1; for (int i = sc.UpdateStartIndex; i < sc.ArraySize; i++) { if (i == lastIndex) continue; // block handling the same tick multiple times // starting new bar at session boundary makes sure you have the same bars // reguardless of the first date that is loaded in the chart // Note: using date change instead of session boundary if (i == 0 || (sc.BaseDateTimeIn[i-1].GetDate() != sc.BaseDateTimeIn[i].GetDate())) { // create new bar if (i != 0) { UPDATE_OPENS(); } ADD_BAR(); float mod = !alignToBrickSize.GetYesNo() ? brickSize : sc.RoundToTickSize(fmod(Close[o], brickSize), sc.TickSize); float mid = sc.FormattedEvaluate(mod, sc.ValueFormat, EQUAL_OPERATOR, brickSize, sc.ValueFormat) ? Close[o] : Close[o] - mod; renkoHigh = mid + brickSize; renkoLow = mid - brickSize; barComplete = false; } else { if (barComplete) { // this tick creates a new bar UPDATE_OPENS(); ADD_BAR(); if (br_RangeExceeded(sc, High[o], Low[o], renkoHigh, renkoLow)) br_MoveLimits(sc, High[o], Low[o], brickSize, reverseMultiplier.GetInt(), renkoHigh, renkoLow); } else { if (br_RangeExceeded(sc, iHigh[i], iLow[i], renkoHigh, renkoLow)) { UPDATE_OPENS(); ADD_BAR(); br_MoveLimits(sc, High[o], Low[o], brickSize, reverseMultiplier.GetInt(), renkoHigh, renkoLow); } else { UPDATE_BAR(); } } br_CheckBarComplete(sc, High[o], Low[o], brickSize, reverseMultiplier.GetInt(), renkoHigh, renkoLow, barComplete); } lastIndex = i; } //} //catch (char *ErrMsg){ // sc.AddMessageToLog(ErrMsg, 1); //} } |
[2013-09-14 00:42:01] |
marcovth - Posts: 61 |
Here is a previous attempt I wrote, but something is missing. It seems to work, but it's messing up other studies that I add to the chart (which is not the case with the Better Renko or PnF studies. So if you can detect what's wrong, that would be helpful too. #include "sierrachart.h" SCDLLName("DirectionalReversalChart") SCSFExport scsf_CopyOfBaseGraph(SCStudyInterfaceRef sc){ SCSubgraphRef Open = sc.Subgraph[0]; SCSubgraphRef High = sc.Subgraph[1]; SCSubgraphRef Low = sc.Subgraph[2]; SCSubgraphRef Close = sc.Subgraph[3]; SCSubgraphRef Volume = sc.Subgraph[4]; SCSubgraphRef OpenInterest = sc.Subgraph[5]; SCSubgraphRef OHLCAvg = sc.Subgraph[6]; SCSubgraphRef HLCAvg = sc.Subgraph[7]; SCSubgraphRef HLAvg = sc.Subgraph[8]; SCSubgraphRef BidVol = sc.Subgraph[9]; SCSubgraphRef AskVol = sc.Subgraph[10]; if (sc.SetDefaults){ sc.GraphName = "Directional Reversal Chart"; sc.StudyDescription = ""; sc.IsCustomChart = 1; sc.GraphRegion = 0; sc.DrawZeros = 0; sc.GraphDrawType = GDT_CANDLESTICK; sc.StandardChartHeader = 1; sc.DisplayAsMainPriceGraph = 1; sc.ValueFormat = sc.BaseGraphValueFormat; Open.Name = "Open"; Open.DrawStyle = DRAWSTYLE_LINE; Open.PrimaryColor = RGB(0,200,0); High.Name = "High"; High.DrawStyle = DRAWSTYLE_LINE; High.PrimaryColor = RGB(0,0,0); Low.Name = "Low"; Low.DrawStyle = DRAWSTYLE_LINE; Low.PrimaryColor = RGB(200,0,0); Close.Name = "Close"; Close.DrawStyle = DRAWSTYLE_LINE; Close.PrimaryColor = RGB(0,0,0); Volume.Name = "Volume"; Volume.DrawStyle = DRAWSTYLE_IGNORE; OpenInterest.Name = "# of Trades / OI"; OpenInterest.DrawStyle = DRAWSTYLE_IGNORE; OHLCAvg.Name = "OHLC Avg"; OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE; HLCAvg.Name = "HLC Avg"; HLCAvg.DrawStyle = DRAWSTYLE_IGNORE; HLAvg.Name = "HL Avg"; HLAvg.DrawStyle = DRAWSTYLE_IGNORE; BidVol.Name = "Bid Vol"; BidVol.DrawStyle = DRAWSTYLE_IGNORE; AskVol.Name = "Ask Vol"; AskVol.DrawStyle = DRAWSTYLE_IGNORE; sc.FreeDLL = 1; sc.AutoLoop = 1; sc.MaintainVolumeAtPriceData = 1; return; } int i=sc.Index; SCString message; // If our start index is zero, then we want to clear our existing chart // data, if any, so we start clean to avoid any possible problems. This // is accomplished by using sc.ResizeArrays. if (sc.UpdateStartIndex == 0) sc.ResizeArrays(0); unsigned int AskVolume = 0; unsigned int BidVolume = 0; float Price=0; float prevPrice=0; float& DirectionalMove = sc.PersistVars->f1; //float& OpenBar = sc.PersistVars->f2; //float& HighBar = sc.PersistVars->f3; //float& LowBar = sc.PersistVars->f4; if( i==sc.ArraySize-2 || (i > sc.ArraySize-2) ){ // && sc.GetBarHasClosedStatus(i) == BHCS_BAR_HAS_CLOSED sc.ResizeArrays(0); //HighBar=0; //LowBar=0; //OpenBar=0; int prevIndex=0; int out=-1; //for (int n = sc.UpdateStartIndex; n < sc.ArraySize; n++){ for (int n = 0; n < sc.ArraySize; n++){ if(n==0){ //HighBar=sc.High[n]; //LowBar=sc.Low[n]; //OpenBar=sc.Open[n]; } else { float HighBar=sc.GetHighest(sc.High,n,n-prevIndex); float LowBar=sc.GetLowest(sc.Low,n,n-prevIndex); float OpenBar=sc.Open[prevIndex+1]; if(sc.High[n]>0 and sc.High[n]>HighBar)HighBar=sc.High[n]; if(sc.Low[n]>0 and sc.Low[n]<LowBar) LowBar=sc.Low[n]; bool PrintBar=false; if(sc.Close[n]>0 and (HighBar-LowBar)>(8.0f*sc.TickSize) ){ if( (HighBar-sc.Close[n])>=(4.0f*sc.TickSize) or (sc.Close[n]-LowBar)>=(4.0f*sc.TickSize) ){ // 8 tick directional move with 4 tick pullback PrintBar=true; } } if(PrintBar){ //if (sc.OutArraySize-1 < n) sc.AddElements(1); out++; High[out]=HighBar; Low[out]=LowBar; Open[out]=OpenBar; Close[out]=sc.Close[n]; //HighBar=sc.High[n]; //LowBar=sc.Low[n]; //OpenBar=sc.Close[n]; prevIndex=n; //message.Format("%f | %f | %f | %f",OpenBar,HighBar,LowBar,Price); //sc.AddMessageToLog(message, 1); sc.DateTimeOut[out] = sc.BaseDateTimeIn[n]; /*for (int SubGraph = 0; SubGraph <=10; SubGraph++){ sc.Subgraph[SubGraph][n] = sc.BaseDataIn[SubGraph][n]; //For testing coloring bars //sc.Subgraph[SubGraph].DataColor[i] = RGB(255,255,255); }*/ PrintBar=false; } } } } } |
[2014-01-12 08:51:42] |
User42019 - Posts: 6 |
Hi, Is there any follow up to your efforts? |
[2014-01-23 17:20:42] |
norvik_ - Posts: 106 |
I had modified code of P&F Bars from ASC_Source folder. It seems works correct. #include "C:\SierraChart\ACS_Source\sierrachart.h"
SCDLLName("OFAChart") SCSFExport scsf_OFAChart(SCStudyInterfaceRef sc) { SCSubgraphRef Open = sc.Subgraph[SC_OPEN]; SCSubgraphRef High = sc.Subgraph[SC_HIGH]; SCSubgraphRef Low = sc.Subgraph[SC_LOW]; SCSubgraphRef Last = sc.Subgraph[SC_LAST]; SCSubgraphRef Volume = sc.Subgraph[SC_VOLUME]; SCSubgraphRef NumTrades = sc.Subgraph[SC_NT]; SCSubgraphRef OHLCAvg = sc.Subgraph[SC_OHLC]; SCSubgraphRef HLCAvg = sc.Subgraph[SC_HLC]; SCSubgraphRef HLAvg = sc.Subgraph[SC_HL]; SCSubgraphRef BidVol = sc.Subgraph[SC_BIDVOL]; SCSubgraphRef AskVol = sc.Subgraph[SC_ASKVOL]; SCSubgraphRef UpTickVol = sc.Subgraph[SC_UPVOL]; SCSubgraphRef DownTickVol = sc.Subgraph[SC_DOWNVOL]; SCSubgraphRef BidTrades = sc.Subgraph[SC_BIDNT]; SCSubgraphRef AskTrades = sc.Subgraph[SC_ASKNT]; SCSubgraphRef BidAskDiffMax = sc.Subgraph[SC_ASKBID_DIFF_HIGH]; SCSubgraphRef BidAskDiffMin = sc.Subgraph[SC_ASKBID_DIFF_LOW]; SCSubgraphRef NumberOfBoxes = sc.Subgraph[PF_NUM_BOXES_ARRAY]; SCSubgraphRef DirectionArray = sc.Subgraph[PF_DIRECTION_ARRAY]; SCSubgraphRef TrueLast = sc.Subgraph[PF_TRUELAST_ARRAY]; const int ArrayCount = PF_TRUELAST_ARRAY + 1; SCInputRef InitialRangeTicks = sc.Input[0]; SCInputRef ReversalSize = sc.Input[1]; SCInputRef AllowOneBoxReversals = sc.Input[2]; SCInputRef NewBarAtStartOfDay = sc.Input[3]; SCInputRef IgnoreLastBarUntilComplete = sc.Input[4]; if (sc.SetDefaults) { sc.GraphName = "OFA Chart"; sc.GraphRegion = 0; sc.StandardChartHeader = 1; sc.IsCustomChart = 1; sc.GraphDrawType = GDT_CANDLESTICK; sc.DrawZeros = 0; sc.FreeDLL = 1; Open.Name = "Open"; Open.DrawStyle = DRAWSTYLE_LINE; Open.PrimaryColor = RGB(0,255,0); High.Name = "High"; High.DrawStyle = DRAWSTYLE_LINE; High.PrimaryColor = RGB(0,255,0); Low.Name = "Low"; Low.DrawStyle = DRAWSTYLE_LINE; Low.PrimaryColor = RGB(255,0,0); Last.Name = "Last"; Last.DrawStyle = DRAWSTYLE_LINE; Last.PrimaryColor = RGB(255,0,0); Volume.Name = "Volume"; Volume.DrawStyle = DRAWSTYLE_IGNORE; Volume.PrimaryColor = RGB(255,255,255); NumTrades.Name = "# of Trades / OI"; NumTrades.DrawStyle = DRAWSTYLE_IGNORE; NumTrades.PrimaryColor = RGB(255,255,255); OHLCAvg.Name = "OHLC Avg"; OHLCAvg.DrawStyle = DRAWSTYLE_IGNORE; OHLCAvg.PrimaryColor = RGB(255,255,255); HLCAvg.Name = "HLC Avg"; HLCAvg.DrawStyle = DRAWSTYLE_IGNORE; HLCAvg.PrimaryColor = RGB(255,255,255); HLAvg.Name = "HL Avg"; HLAvg.DrawStyle = DRAWSTYLE_IGNORE; HLAvg.PrimaryColor = RGB(255,255,255); BidVol.Name = "Bid Vol"; BidVol.DrawStyle = DRAWSTYLE_IGNORE; BidVol.PrimaryColor = RGB(255,255,255); AskVol.Name = "Ask Vol"; AskVol.DrawStyle = DRAWSTYLE_IGNORE; AskVol.PrimaryColor = RGB(255,255,255); NumberOfBoxes.Name = "Number of Boxes"; NumberOfBoxes.DrawStyle = DRAWSTYLE_IGNORE; NumberOfBoxes.PrimaryColor = RGB(0xFF,0x99,0x00); TrueLast.Name = "True Last"; TrueLast.DrawStyle = DRAWSTYLE_IGNORE; TrueLast.PrimaryColor = RGB(255,255,255); InitialRangeTicks.Name = "Target range (ticks):"; InitialRangeTicks.SetInt(6); ReversalSize.Name = "Reversal Size"; ReversalSize.SetFloat(3.0f); ReversalSize.SetFloatLimits(FLT_MIN, FLT_MAX); AllowOneBoxReversals.Name = "Allow One Box Reversals"; AllowOneBoxReversals.SetYesNo(1); NewBarAtStartOfDay.Name = "New Bar at Start of Day"; NewBarAtStartOfDay.SetYesNo(0); IgnoreLastBarUntilComplete.Name = "Ignore Last Bar Until Completed"; IgnoreLastBarUntilComplete.SetYesNo(0); return; } struct s_PFStorage { int PriorOutArraySize; float PriorOutData[ArrayCount]; float High; float Low; int Index; float targetRange; }; s_PFStorage* p_PFStorage = (s_PFStorage*)sc.StorageBlock; SCDateTime& NextSessionStart = sc.PersistVars->scdt1; int InputIndex = sc.UpdateStartIndex; int AvgStartIndex = 0; if (InputIndex == 0) { sc.ResizeArrays(0); AvgStartIndex = 0; // Clear the last state data memset(p_PFStorage, 0, sizeof(p_PFStorage)); p_PFStorage->Index = -1; p_PFStorage->targetRange = sc.RoundToTickSize(InitialRangeTicks.GetInt() * sc.TickSize, sc.TickSize); if (!sc.AddElements(1)) return; sc.DateTimeOut[0] = sc.BaseDateTimeIn[0]; Open[0] = sc.Open[0]; High[0] = sc.Close[0]; Low[0] = sc.Close[0]; Last[0] = sc.Close[0]; TrueLast[0] = sc.Close[0]; NextSessionStart = sc.GetTradingDayStartDateTimeOfBar(sc.BaseDateTimeIn[0]) + 1*DAYS; NumTrades.Name = "# of Trades"; sc.GraphName.Format("OFAChart %.6gx%g %s",ReversalSize.GetFloat(),sc.GetStudyNameFromChart(sc.ChartNumber, 0).GetChars()); } else if (!IgnoreLastBarUntilComplete.GetYesNo()) { AvgStartIndex = p_PFStorage->PriorOutArraySize - 1; // Restore array to size just before processing last input bar (sc.BaseDataIn) and restore state of last output bar. sc.ResizeArrays(p_PFStorage->PriorOutArraySize); for (int SubgraphIndex = 0; SubgraphIndex < ArrayCount; ++SubgraphIndex) { sc.Subgraph[SubgraphIndex][AvgStartIndex] = p_PFStorage->PriorOutData[SubgraphIndex]; } } int OutputIndex = sc.DateTimeOut.GetArraySize() - 1; if (InputIndex == 0) InputIndex = 1; for (; InputIndex < sc.ArraySize; ++InputIndex) { bool NewBar = false; if (IgnoreLastBarUntilComplete.GetYesNo() && sc.GetBarHasClosedStatus(InputIndex)== BHCS_BAR_HAS_NOT_CLOSED) return; if (NewBarAtStartOfDay.GetYesNo() != 0) { SCDateTime IndexDateTime = sc.BaseDateTimeIn[InputIndex]; if (IndexDateTime >= NextSessionStart) { sc.CalculateOHLCAverages(OutputIndex); if (!sc.AddElements(1)) return; NewBar = true; OutputIndex = sc.DateTimeOut.GetArraySize() - 1; sc.DateTimeOut[OutputIndex] = sc.BaseDateTimeIn[InputIndex]; Open[OutputIndex] = sc.Open[InputIndex]; High[OutputIndex] = sc.Close[InputIndex]; Low[OutputIndex] = sc.Close[InputIndex]; Last[OutputIndex] = sc.Close[InputIndex]; TrueLast[OutputIndex] = sc.Close[InputIndex]; NextSessionStart = sc.GetTradingDayStartDateTimeOfBar(IndexDateTime) + 1*DAYS; } } // Remember state of last P&F bar when reach last input bar because last // input bar can change due to updating, causing for example a new P&F bar // to be added when on a later update no new bar is added. if (!IgnoreLastBarUntilComplete.GetYesNo() && InputIndex == sc.ArraySize - 1) { p_PFStorage->PriorOutArraySize = OutputIndex + 1; for (int SubgraphIndex = 0; SubgraphIndex < ArrayCount; ++SubgraphIndex) { p_PFStorage->PriorOutData[SubgraphIndex] = sc.Subgraph[SubgraphIndex][OutputIndex]; } } // Determine our initial direction if not known if (DirectionArray[OutputIndex] == 0.0f) { if (Last[OutputIndex] > sc.Close[InputIndex]) DirectionArray[OutputIndex] = -1; // Down else if (Last[OutputIndex] < sc.Close[InputIndex]) DirectionArray[OutputIndex] = 1; // Up } if (DirectionArray[OutputIndex] == 0.0f) continue; // No direction bool UseHighFirst; int OpenToHighLow = sc.CompareOpenToHighLow(sc.Open[InputIndex],sc.High[InputIndex], sc.Low[InputIndex], sc.BaseGraphValueFormat); if(OpenToHighLow == 1) UseHighFirst = true; else if(OpenToHighLow == -1) UseHighFirst = false; else if (sc.FormattedEvaluate(sc.Open[InputIndex] , sc.BaseGraphValueFormat,GREATER_OPERATOR, sc.Close[InputIndex], sc.BaseGraphValueFormat)) UseHighFirst = true; else if (sc.FormattedEvaluate(sc.Open[InputIndex] , sc.BaseGraphValueFormat,LESS_OPERATOR, sc.Close[InputIndex], sc.BaseGraphValueFormat)) UseHighFirst = false; else if (DirectionArray[OutputIndex] == 1) // Up Bar UseHighFirst = true; else UseHighFirst = false; for (int PassNumber=0; PassNumber<2; PassNumber++) { if (DirectionArray[OutputIndex] == 1) { if ((UseHighFirst && PassNumber == 0 ) || (!UseHighFirst &&PassNumber ==1)) { if (sc.FormattedEvaluate(sc.High[InputIndex],sc.BaseGraphValueFormat, GREATER_EQUAL_OPERATOR, High[OutputIndex],sc.BaseGraphValueFormat)) { High[OutputIndex] = sc.High[InputIndex]; } } if ((PassNumber == 0) || (UseHighFirst && PassNumber == 1)) { float trueRange = High[OutputIndex] - Low[OutputIndex]; if ((sc.FormattedEvaluate(sc.Low[InputIndex],sc.BaseGraphValueFormat, LESS_EQUAL_OPERATOR, High[OutputIndex] - sc.TickSize *ReversalSize.GetFloat(), sc.BaseGraphValueFormat))&&(sc.FormattedEvaluate(trueRange, sc.ValueFormat, GREATER_OPERATOR, p_PFStorage->targetRange, sc.ValueFormat))) { Last[OutputIndex] = High[OutputIndex]; bool SetOpen = false; if (AllowOneBoxReversals.GetYesNo()) { // Calculate the number of boxes for the column NumberOfBoxes[OutputIndex] =(float)sc.Round(High[OutputIndex] - Low[OutputIndex]); sc.CalculateOHLCAverages(OutputIndex); if (!sc.AddElements(1)) return; NewBar = true; OutputIndex++; sc.DateTimeOut[OutputIndex] = sc.BaseDateTimeIn[InputIndex]; High[OutputIndex] = High[OutputIndex - 1]; SetOpen = true; } DirectionArray[OutputIndex] = -1; Low[OutputIndex] = sc.Low[InputIndex]; if (SetOpen) Open[OutputIndex] = Low[OutputIndex]; } } if (UseHighFirst) PassNumber++; } else// down column { if ((!UseHighFirst && PassNumber == 0) || (UseHighFirst && PassNumber ==1)) { if (sc.FormattedEvaluate(sc.Low[InputIndex] ,sc.BaseGraphValueFormat, LESS_EQUAL_OPERATOR, Low[OutputIndex] ,sc.BaseGraphValueFormat)) { Low[OutputIndex] = sc.Low[InputIndex]; } } if (PassNumber == 0 || (!UseHighFirst && PassNumber == 1)) { float trueRange = High[OutputIndex] - Low[OutputIndex]; if ((sc.FormattedEvaluate(sc.High[InputIndex] ,sc.BaseGraphValueFormat, GREATER_EQUAL_OPERATOR, Low[OutputIndex] + sc.TickSize *ReversalSize.GetFloat(), sc.BaseGraphValueFormat))&&(sc.FormattedEvaluate(trueRange, sc.ValueFormat, GREATER_OPERATOR, p_PFStorage->targetRange, sc.ValueFormat))) { Last[OutputIndex] = High[OutputIndex]; Last[OutputIndex] = Low[OutputIndex]; bool SetOpen = false; if (AllowOneBoxReversals.GetYesNo()) { // Calculate the number of boxes for the column NumberOfBoxes[OutputIndex] = High[OutputIndex] - Low[OutputIndex]; sc.CalculateOHLCAverages(OutputIndex); if (!sc.AddElements(1)) return; NewBar = true; OutputIndex++; sc.DateTimeOut[OutputIndex] =sc.BaseDateTimeIn[InputIndex]; Low[OutputIndex] = Low[OutputIndex - 1]; SetOpen = true; } DirectionArray[OutputIndex] = 1; High[OutputIndex] = sc.High[InputIndex]; if (SetOpen) Open[OutputIndex] = High[OutputIndex]; } } if (!UseHighFirst) PassNumber++; }//else down column } // PassNumber for loop TrueLast[OutputIndex] = sc.Close[InputIndex]; Last[OutputIndex] = sc.Close[InputIndex]; sc.CalculateOHLCAverages(OutputIndex); NumberOfBoxes[OutputIndex] = (float)sc.Round((High[OutputIndex] -Low[OutputIndex])/sc.TickSize); // Add in volume and open interest Volume[OutputIndex] += sc.Volume[InputIndex]; NumTrades[OutputIndex] += sc.OpenInterest[InputIndex]; float BidAskDiffHigh = 0; float BidAskDiffLow = 0; if (sc.BaseDataIn.GetArraySize() >= SC_ASKBID_DIFF_LOW+1) { BidAskDiffHigh = AskVol[OutputIndex] - BidVol[OutputIndex] +sc.BaseDataIn[SC_ASKBID_DIFF_HIGH][InputIndex]; BidAskDiffLow = AskVol[OutputIndex] - BidVol[OutputIndex] +sc.BaseDataIn[SC_ASKBID_DIFF_LOW][InputIndex]; } BidVol[OutputIndex] += sc.BidVolume[InputIndex]; AskVol[OutputIndex] += sc.AskVolume[InputIndex]; UpTickVol[OutputIndex] += sc.UpTickVolume[InputIndex]; DownTickVol[OutputIndex] += sc.DownTickVolume[InputIndex]; BidTrades[OutputIndex] += sc.NumberOfBidTrades[InputIndex]; AskTrades[OutputIndex] += sc.NumberOfAskTrades[InputIndex]; if (NewBar || BidAskDiffHigh > BidAskDiffMax[OutputIndex]) BidAskDiffMax[OutputIndex] = BidAskDiffHigh; if (NewBar || BidAskDiffLow < BidAskDiffMin[OutputIndex]) BidAskDiffMin[OutputIndex] = BidAskDiffLow; } } Date Time Of Last Edit: 2014-01-23 17:23:07
|
[2014-01-23 18:49:13] |
User42019 - Posts: 6 |
Thanks for your efforts. Seems like still something has to be adjusted to match the original OFA bars... Hopefully, you'll match... |
[2014-01-24 17:41:58] |
norvik - Posts: 22 |
Code in my previos post is not correct. Here is a new one, I hope without mistakes.
|
OFAChart.cpp - Attached On 2014-01-24 17:41:09 UTC - Size: 7.6 KB - 967 views |
[2014-01-25 08:13:21] |
User31732 - Posts: 32 |
norvik, thank you. Now it almost like original OFA bars, but close of some bars shouldn't be at the high or at the low.
|
ofa chart.jpg / V - Attached On 2014-01-25 08:10:59 UTC - Size: 193.76 KB - 2112 views ofa chart original.jpg / V - Attached On 2014-01-25 08:11:09 UTC - Size: 127.78 KB - 1919 views Attachment Deleted. |
[2014-01-27 15:27:52] |
norvik - Posts: 22 |
Now it almost like original OFA bars, but close of some bars shouldn't be at the high or at the low.
I made one improvement, now "reversal" condition works only after the "exceeded" case occurred. View is exactly like original bars.. |
OFARealChart.cpp - Attached On 2014-01-27 15:27:39 UTC - Size: 8.06 KB - 890 views |
[2014-01-27 15:48:49] |
User67150 - Posts: 3 |
norvik, could you post dll? SC can not compile this cpp. Date Time Of Last Edit: 2014-01-27 15:54:59
|
[2014-01-27 16:08:15] |
norvik - Posts: 22 |
Sorry, I am using VS. Here is compiled dll.
|
OFARealChart.dll - Attached On 2014-01-27 16:08:06 UTC - Size: 89 KB - 926 views |
[2014-01-27 16:29:55] |
User67150 - Posts: 3 |
norvik, thanks, you are almost there, but still there are wrong bars in your version. didn't want to discourage you, hope you'll make it right. Date Time Of Last Edit: 2014-01-27 16:32:55
|
[2014-01-27 17:37:03] |
User31732 - Posts: 32 |
User67150, try for 6/4 OFA 5/4 parameters. I'm sure it's exactly like OFA bars. Norvik, many thanks! |
[2014-01-27 20:46:31] |
ejtrader - Posts: 688 |
Interesting bar type. Can anyone comment whether these bars have "true" Open/Close values - that are likely to be same during replay? Thanks |
[2014-01-28 05:43:04] |
norvik - Posts: 22 |
but still there are wrong bars in your version.
I made this custom chart using the only public information from OFA webpage.May be something is missed, Inglish is not my native language. Also I think that their description possible is not complete, it is proprietary algo. |
[2014-01-28 07:08:28] |
User67150 - Posts: 3 |
User67150, try for 6/4 OFA 5/4 parameters. I'm sure it's exactly like OFA bars.
I tried various combinations, still not the same if compare with OFA. If you have exactly the same - could you post the screen? |
[2014-02-04 04:47:38] |
Profile Trader - Posts: 176 |
OFA 6/4 Bars require that the price goes up 6 ticks consecutively and then pull back 4 ticks to start a new bar. So if it goes up 3 and then back one the count is started over for the 6 consecutive ticks. the 6 can be in either direction but has to uptick or downtick without reversing at all once the 6 ticks have been hit. After that happens a new bar is printed when 4 opposite directional ticks has happened. These would be done on reversal bars.
|
[2014-02-05 16:07:18] |
Profile Trader - Posts: 176 |
Those that know how to program for SC is this something that SC is capable of doing with the Number Bar study? I put together a excel spreadsheet each night that has levels like pivots, highs, lows, value areas etc. is there a way to import a excel spreadsheet into SC and have that place lines and label those lines what is in the spreadsheet? Thanks for your insight. Doug |
[2014-08-03 21:44:35] |
Moti - Posts: 63 |
Hello Norvik, I will like to thank you for the code of OFA bar. Profile trader describe the movement of bar: " "OFA 6/4 Bars require that the price goes up 6 ticks consecutively and then pull back 4 ticks to start a new bar. So if it goes up 3 and then back one the count is started over for the 6 consecutive ticks. the 6 can be in either direction but has to uptick or downtick without reversing at all once the 6 ticks have been hit. After that happens a new bar is printed when 4 opposite directional ticks has happened. These would be done on reversal bars."" Norvik, Please advice if your code work like the description ? If Not would you like that I will translate the description above to Russian ? Moti |
[2015-08-22 00:00:25] |
ejtrader - Posts: 688 |
Marcovith - For some reason the cpp file provided doesn't provide the same chart as the dll. Would you please check and post the cpp file one more time? Thanks |
[2015-08-24 21:22:05] |
norvik_ - Posts: 106 |
ejtrader, sorry, if you ask about the dll i formely posted here, i really can not exactly say on wich variant of code it was based. last version i have in attachment
|
OFARealChart.cpp - Attached On 2015-08-24 21:21:51 UTC - Size: 8.06 KB - 774 views |
[2015-08-24 21:45:16] |
ejtrader - Posts: 688 |
Thanks Norvik. Appreciate it. Just that this doesn't match up the dll from post #10. Did you use the same cpp file for compiling that dll? the cpp file doesn't compile by default ( there are few syntax errors ). After correcting them - the chart doesn't match up the dll. I would try to see if there are any other missing portions for this. thanks as per the image - left side is based on the dll file right side - based on the corrected cpp file. screencast.com/t/a4Lw4EiIv9BT |
[2015-08-25 20:43:04] |
norvik_ - Posts: 106 |
Interesting. I will try to remember how I create it.
|
[2015-08-25 20:51:50] |
ejtrader - Posts: 688 |
Thanks Norvik. Attached is the cpp file to make it compilable( few syntax errors are addressed from the cpp file you have provided). Just that this doesn't provide the same output as the dll file you have uploaded. Thanks Date Time Of Last Edit: 2015-08-25 20:52:29
|
OFABars.cpp - Attached On 2015-08-25 20:51:09 UTC - Size: 9.08 KB - 756 views |
[2015-08-25 22:59:43] |
norvik_ - Posts: 106 |
Attached file is compiled without errors on VS 2010. Result is on a screenshort.
|
OFARealChart.cpp - Attached On 2015-08-25 22:59:10 UTC - Size: 7.94 KB - 742 views |
[2015-08-26 01:03:24] |
ejtrader - Posts: 688 |
Thanks Norvik. This cpp file works fine as expected :)
|
To post a message in this thread, you need to log in with your Sierra Chart account: