Support Board
Date/Time: Thu, 26 Dec 2024 19:07:37 +0000
Post From: Orderflowanalytics-style reversal bars.
[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); //} } |