Support Board
Date/Time: Fri, 07 Feb 2025 23:04:24 +0000
Post From: Sock Renko
[2020-06-15 15:18:05] |
Ackin - Posts: 1865 |
/******************************************************
* A version of the renko chart study for Sierra Chart.* * By Sock 2009 * * windysock@gmail.com * ******************************************************/ SCSFExport scsf_SockRenkoChart(SCStudyInterfaceRef sc) { SCFloatArrayRef InOpen = sc.Open; SCFloatArrayRef InHigh = sc.High; SCFloatArrayRef InLow = sc.Low; SCFloatArrayRef InClose = sc.Close; SCFloatArrayRef InVolume = sc.Volume; SCSubgraphRef OutOpen = sc.Subgraph[RK_OPEN]; SCSubgraphRef OutHigh = sc.Subgraph[RK_HIGH]; SCSubgraphRef OutLow = sc.Subgraph[RK_LOW]; SCSubgraphRef OutClose = sc.Subgraph[RK_LAST]; SCSubgraphRef OutVolume = sc.Subgraph[RK_VOLUME]; SCSubgraphRef OutBoxSize = sc.Subgraph[RK_BOXSIZE]; SCSubgraphRef OutOCR = sc.Subgraph[RK_OCR]; SCSubgraphRef OutOC = sc.Subgraph[RK_OC]; SCSubgraphRef OutColorCount = sc.Subgraph[RK_COLORCNT]; SCSubgraphRef OutColor = sc.Subgraph[RK_COLOR]; SCSubgraphRef OutRenkoClose = sc.Subgraph[RK_RCLOSE]; SCSubgraphRef OutHL = sc.Subgraph[RK_HL]; SCSubgraphRef OutHLC = sc.Subgraph[RK_HLC]; SCSubgraphRef OutOHLC = sc.Subgraph[RK_OHLC]; // Set configuration variables if (sc.SetDefaults) { // Set the defaults sc.GraphName = "Sock Renko Chart"; sc.StudyDescription = "Renko chart study by Sock. Comments to windysock@gmail.com"; sc.IsCustomChart = 1; sc.GraphRegion = 0; sc.DrawZeros = 0; sc.GraphDrawType = GDT_CANDLESTICK_BODY_ONLY; sc.StandardChartHeader = 1; sc.AutoLoop = 0; sc.FreeDLL = 0; // Subgraphs OutOpen.Name = "Open"; OutOpen.PrimaryColor = COLOR_GREEN; OutHigh.Name = "High"; OutHigh.PrimaryColor = COLOR_GREEN; OutLow.Name = "Low"; OutLow.PrimaryColor = COLOR_RED; OutClose.Name = "Close"; OutClose.PrimaryColor = COLOR_RED; OutVolume.Name = "Volume"; OutRenkoClose.Name = "R-Renko Close"; OutBoxSize.Name = "Box Size"; OutOCR.Name = "OCR Avg"; OutOC.Name = "OC Avg"; OutColorCount.Name = "Same colour box count"; OutColor.Name = "Box colour"; OutHL.Name = "HL Avg"; OutHLC.Name = "HLC Avg"; OutOHLC.Name = "OHLC Avg"; // Inputs sc.Input[0].Name = "Fixed box size"; sc.Input[0].SetFloat(1.0f); sc.Input[1].Name = "Start chart on multiples of:"; sc.Input[1].SetFloat(1.0f); sc.Input[2].Name = "Display wicks & tails:"; sc.Input[2].SetYesNo(0); sc.Input[3].Name = "Set box size using ATR from another chart?:"; sc.Input[3].SetYesNo(0); sc.Input[4].Name = "ATR chart number:"; sc.Input[4].SetInt(0); sc.Input[5].Name = "ATR study number:"; sc.Input[5].SetInt(0); sc.Input[6].Name = "ATR subgraph number:"; sc.Input[6].SetInt(0); sc.Input[7].Name = "ATR multiplier:"; sc.Input[7].SetFloat(1.0f); sc.Input[8].Name = "Round ATR to nearest:"; sc.Input[8].SetFloat(1.0f); return; } try { long i = 0; // input index - underlying bar chart long o = 0; // output index - renko chart long OtherIndex = 0; // other chart study index if (sc.BaseGraphValueFormat > 6) { throw "Set Price Display Format to decimals, not fractions"; } int d = sc.BaseGraphValueFormat == 0 ? 1 : sc.BaseGraphValueFormat; // Decimal places - min = 1 sc.ValueFormat = sc.BaseGraphValueFormat; int Volume, m, n, PrevBoxColor, NewBoxColor; OperatorEnum cond; double limit, HighLimit, LowLimit; SCFloatArray OtherArray; // Input vars float BoxSize = sc.Input[0].GetFloat(); float ChartMulti = sc.Input[1].GetFloat(); sc.GraphDrawType = sc.Input[2].GetYesNo() ? GDT_CANDLESTICK:GDT_CANDLESTICK_BODY_ONLY; int UseDynamicBoxSize = sc.Input[3].GetYesNo(); int ChartNum = sc.Input[4].GetInt(); int StudyNum = sc.Input[5].GetInt(); int SubgraphNum = sc.Input[6].GetInt(); float StudyMulti = sc.Input[7].GetFloat(); float RoundTo = sc.Input[8].GetFloat(); // Initial load if (sc.UpdateStartIndex == 0) { sc.ResizeArrays(0); // Add 2 boxes, 1st is anchor box to start the chart, 2nd is the current box. sc.AddElements(2); sc.DateTimeOut[1] = sc.DateTimeOut[0] = sc.BaseDateTimeIn[0]; OutOpen[1] = OutOpen[0] = (sc.RoundToTickSize(InOpen[0], ChartMulti*10))+ChartMulti; // Start chart on input multiple OutHigh[1] = OutHigh[0] = OutOpen[0]; OutLow[1] = OutLow[0] = OutOpen[0]; OutClose[1] = OutClose[0] = OutOpen[0]; } o = sc.OutArraySize - 1; // Get array from other chart if using dynamic box sizing if (UseDynamicBoxSize) { sc.GetStudyArrayFromChart(ChartNum, StudyNum, SubgraphNum, OtherArray); if (OtherArray.GetArraySize() == 0) { throw "Error accessing ATR study on other chart, check inputs and retry"; } } // Draw the renko chart for (i = sc.UpdateStartIndex; i < sc.ArraySize; i++) { PrevBoxColor = OutClose[o-1] >= OutOpen[o-1] ? GREEN_BOX:RED_BOX; if (UseDynamicBoxSize) { OtherIndex = sc.GetNearestMatchForDateTimeIndex(ChartNum, i); if (OtherIndex == 0) { throw "Other chart start date/time must be before current chart start"; } BoxSize = OtherArray[OtherIndex]*StudyMulti; BoxSize = sc.RoundToTickSize(BoxSize, RoundTo); if (BoxSize <= 0.0) { throw "Invalid box size detected, check other chart settings and retry "; } } // Update current box with input bar data sc.DateTimeOut[o] = sc.BaseDateTimeIn[i]; OutOpen[o] = InClose[i]; OutClose[o] = InClose[i]; OutColor[o] = 0; OutHigh[o] = InHigh[i] > OutHigh[o] ? InHigh[i] : OutHigh[o]; if (OutLow[o] <= 0.0 || InLow[i] < OutLow[o]) { OutLow[o] = InLow[i]; } if (InClose[i] > OutClose[o-1] && InClose[i] > OutOpen[o-1]) { OutOpen[o] = PrevBoxColor==GREEN_BOX ? OutClose[o-1] : OutOpen[o-1]; OutColor[o] = GREEN_BOX; } else if (InClose[i] < OutClose[o-1] && InClose[i] < OutOpen[o-1]) { OutOpen[o] = PrevBoxColor==RED_BOX ? OutClose[o-1] : OutOpen[o-1]; OutColor[o] = RED_BOX; } OutVolume[o] += InVolume[i]; OutBoxSize[o] = BoxSize; OutRenkoClose[o] = InClose[i]; OutOCR[o] = (OutOpen[o]+OutClose[o]+OutRenkoClose[o])/3.0f; OutOC[o] = (OutOpen[o]+OutClose[o])/2.0f; OutHL[o] = (OutHigh[o]+OutLow[o])/2.0f; OutHLC[o] = (OutHigh[o]+OutLow[o]+OutClose[o])/3.0f; OutOHLC[o] = (OutOpen[o]+OutHigh[o]+OutLow[o]+OutClose[o])/4.0f; OutColorCount[o] = OutColor[o-1]==OutColor[o] ? OutColorCount[o-1]+1.0f:1.0f; // If the input bar has closed check if new renko box(es) can be added if (i < sc.ArraySize-1) { if (PrevBoxColor == GREEN_BOX) { HighLimit = OutClose[o-1] + BoxSize; LowLimit = OutOpen[o-1] - BoxSize; } else { HighLimit = OutOpen[o-1] + BoxSize; LowLimit = OutClose[o-1] - BoxSize; } NewBoxColor = 0; if (sc.FormattedEvaluate((double)InClose[i],d,GREATER_EQUAL_OPERATOR,HighLimit,d)) { NewBoxColor = GREEN_BOX; cond = GREATER_EQUAL_OPERATOR; limit = HighLimit; } else if (sc.FormattedEvaluate((double)InClose[i],d,LESS_EQUAL_OPERATOR,LowLimit,d)) { NewBoxColor = RED_BOX; cond = LESS_EQUAL_OPERATOR; limit = LowLimit; } if (NewBoxColor != 0) { n = 0; // init box count do { // keep adding boxes until limit reached if (NewBoxColor == GREEN_BOX) { OutClose[o+n] = (float)fround(OutOpen[o+n]+BoxSize, d); limit += BoxSize; } else { OutClose[o+n] = (float)fround(OutOpen[o+n]-BoxSize, d); limit -= BoxSize; } sc.DateTimeOut[o+n] = sc.DateTimeOut[o]; OutHigh[o+n] = OutHigh[o]; OutLow[o+n] = OutLow[o]; OutBoxSize[o+n] = BoxSize; OutRenkoClose[o+n] = InClose[i]; OutOCR[o+n] = (OutOpen[o+n]+OutClose[o+n]+OutRenkoClose[o+n])/3.0f; OutOC[o+n] = (OutOpen[o+n]+OutClose[o+n])/2.0f; OutHL[o+n] = (OutHigh[o+n]+OutLow[o+n])/2.0f; OutHLC[o+n] = (OutHigh[o+n]+OutLow[o+n]+OutClose[o+n])/3.0f; OutOHLC[o+n] = (OutOpen[o+n]+OutHigh[o+n]+OutLow[o+n]+OutClose[o+n])/4.0f; OutColor[o+n] = (float)NewBoxColor; OutColorCount[o+n] = OutColor[(o+n)-1]==OutColor[o+n] ? OutColorCount[(o+n)-1]+1.0f:1.0f; sc.AddElements(1); OutOpen[(o+n)+1] = OutClose[o+n]; // Set next open, on last iter this is open of new current box n++; // incr box count } while (sc.FormattedEvaluate((double)InClose[i],d, cond, limit,d)); Volume = int(OutVolume[o]/n); for (m = 0; m < n; m++) { OutVolume[o+m] = (float)Volume; } } // All done adding boxes, now set initial values for the new current box o = sc.OutArraySize - 1; OutClose[o] = OutOpen[o]; sc.DateTimeOut[o] = sc.BaseDateTimeIn[i]+sc.SecondsPerBar; } } return; } catch (char *ErrMsg){ sc.AddMessageToLog(ErrMsg, 1); } } |