maweno wrote:Hi Merchantprince!
I know the problem. That's no problem with the indicator, there is a
problem with the tick volume. The IT-Crew of FXCM know the problem,
but that doesn't get solved.
This indicator isn't properly used on the TSII ...
Problem at FXCM - display tick volume.
On the Metatrader there is no problem.
I think I've actually found the issue with this indicator.
Ok, first of all about the tick data...
When you 1st open a chart in MarketScope it backfills all the historic bars with data from the FXCM data server. Once the chart is open, your client receives all the latest tick data from the FXCM live server. Importantly, the historic data and the live data might not be exactly the same. I don't know exactly why - it's just the way FXCM manage their data. You can test it yourself. At the start of day open 2 charts of the same period. At the end of the day they should look the same. But, then refresh one of the charts (or re-open it with same data range). Look closely and you may see small differences - in price data as well as volume. The price differences are usually minuscule (maybe an open/close was was slightly different). The volume data tends to show bigger differences, although they are still small.
There also appears to be a bigger difference when comparing Friday's data and then re-opening the chart on Monday. I didn't investigate this myself, but it was reported somewhere on this forum or perhaps DailFX.
With this in mind, I tested BetVol_V2.lua looking for issues due to such problems. Whilst I did see some differences in tick volume data, there were not significant enough to cause the differently painted bars. So, I had a look at the indicator code itself, and found the issue there.
Basically, the BetVol_V2.lua indicator will analyse the live bar (i.e. before it is closed). If the computation happens to detect it as, for example, a ClimaxUp bar, then the bar is set to red. However, the bar is not closed yet. If that bar later changes to a normal bar, nothing was setting the bar colour back to the default grey colour! If the chart was re-loaded it computes correctly. It was only bars that were coloured from the "live" data which were later recalculated as "normal bars" that were wrong.
Whilst there is still the possibility of minor differences due to tick volume differences, I think this will be a very minor effect and possibly negligible.
Here's a chart showing the issue.
I modified the indicator, which is now V3. It is attached. Also the code is posted here.
- Code: Select all
-- Indicator profile initialization routine
-- Defines indicator profile properties and indicator parameters
-- TODO: Add minimal and maximal value of numeric parameters and default color of the streams
function Init()
indicator:name("Climax Volume Spread v2");
indicator:description("No description");
indicator:requiredSource(core.Bar);
indicator:type(core.Oscillator);
indicator:setTag("group", "GSL");
indicator.parameters:addInteger("N", "Average Period", "No description", 20);
indicator.parameters:addInteger("Back", "Analyse Period Back", "No description", 20);
indicator.parameters:addBoolean("TwoBars", "Use TwoBars", "No description", false);
--indicator.parameters:addInteger("BidAsk", "Bid or ASK", "No description", 2);
indicator.parameters:addColor("LowVol_color", "Color of LowVol_color", "Color of LowVol_color", core.rgb(255, 255, 0));
indicator.parameters:addColor("ClimaxUp_color", "Color of ClimaxUp", "Color of ClimaxUp", core.rgb(255, 0, 0));
indicator.parameters:addColor("ClimaxDn_color", "Color of ClimaxDn", "Color of ClimaxDn", core.rgb(255, 255, 255));
indicator.parameters:addColor("DensityUp_color", "Color of Churn", "Color of DensityUp", core.rgb(0, 255, 0));
indicator.parameters:addColor("DensityDn_color", "Color of ClimaxChurn", "Color of DensityDn", core.rgb(255, 0, 128));
indicator.parameters:addColor("VolumeBar_color", "Color of VolumeBar", "Color of VolumeBar", core.rgb(128, 128, 128));
indicator.parameters:addColor("SMAline_color", "Color of SMAline", "Color of SMAline", core.rgb(255, 0, 0));
end
-- Indicator instance initialization routine
-- Processes indicator parameters and creates output streams
-- TODO: Refine the first period calculation for each of the output streams.
-- TODO: Calculate all constants, create instances all subsequent indicators and load all required libraries
-- Parameters block
local N;
local Back;
local first;
local source = nil;
-- Streams block
local ClimaxUp = nil;
local ClimaxDn = nil;
local DensityUp = nil;
local DensityDn = nil;
local VolumeBar = nil;
local SMAline = nil;
-- Routine
function Prepare(nameOnly)
N = instance.parameters.N;
Back = instance.parameters.Back;
source = instance.source;
first = source:first() + N + Back -1;
local name = profile:id() .. "(" .. source:name() .. ", " .. tostring(N) .. ", " .. tostring(Back) .. ")";
instance:name(name);
if (not (nameOnly)) then
Value1 = instance:addInternalStream(0,0);
Value2 = instance:addInternalStream(0,0);
Value3 = instance:addInternalStream(0,0);
Value4 = instance:addInternalStream(0,0);
Value5 = instance:addInternalStream(0,0);
Value6 = instance:addInternalStream(0,0);
Value7 = instance:addInternalStream(0,0);
Value8 = instance:addInternalStream(0,0);
Value9 = instance:addInternalStream(0,0);
Value10 = instance:addInternalStream(0,0);
Value11 = instance:addInternalStream(0,0);
Value12 = instance:addInternalStream(0,0);
Value13 = instance:addInternalStream(0,0);
Value14 = instance:addInternalStream(0,0);
Value15 = instance:addInternalStream(0,0);
Value16 = instance:addInternalStream(0,0);
Value17 = instance:addInternalStream(0,0);
Value18 = instance:addInternalStream(0,0);
Value19 = instance:addInternalStream(0,0);
Value20 = instance:addInternalStream(0,0);
Value21 = instance:addInternalStream(0,0);
Value22 = instance:addInternalStream(0,0);
VolumeBar = instance:addStream("VolumeBar", core.Bar, name .. ".VolumeBar", "VolumeBar", instance.parameters.VolumeBar_color, first);
VolumeBar:setPrecision(0);
SMAline = instance:addStream("SMAline", core.Line, name .. ".SMAline", "SMAline", instance.parameters.SMAline_color, first);
SMAline:setPrecision(0);
end
end
-- Indicator calculation routine
-- TODO: Add your code for calculation output values
function Update(period)
local p = period;
local HIGH = source.high[period];
local LOW = source.low[period];
local OPEN = source.open[period];
local CLOSE = source.close[period];
local VOLUME = source.volume[period];
VolumeBar[period] = VOLUME;
SMAline[period] = 0;
if period < first then
Value1[p] = 0;
Value2[p] = 0;
Value3[p] = 0;
Value4[p] = 0;
Value5[p] = 0;
Value6[p] = 0;
Value7[p] = 0;
Value8[p] = 0;
Value9[p] = 0;
Value10[p] = 0;
Value11[p] = 0;
Value12[p] = 0;
Value13[p] = 0;
Value14[p] = 0;
Value15[p] = 0;
Value16[p] = 0;
Value17[p] = 0;
Value18[p] = 0;
Value19[p] = 0;
Value20[p] = 0;
Value21[p] = 0;
Value22[p] = 0;
end
if period >= first and source:hasData(period) then
SMAline[period] = mathex.avg(source.volume,period-N+1,period);
--if instance.parameters.BidAsk == 0 then
-- Range = HIGH-CLOSE;
--elseif instance.parameters.BidAsk == 1 then
-- Range = CLOSE-LOW;
--else
Range = HIGH-LOW;
--end
if CLOSE > OPEN then
Value1[p] = VOLUME*(Range/(2*Range + OPEN - CLOSE));
elseif CLOSE < OPEN then
Value1[p] = VOLUME*((Range + CLOSE-OPEN)/(2*Range + CLOSE-OPEN));
end
if CLOSE == OPEN then
Value1[p] = 0.5*VOLUME;
end
Value2[p] = VOLUME - Value1[p];
Value3[p] = Value1[p] + Value2[p];
Value4[p] = Value1[p] * Range;
Value5[p] = ( Value1[p]-Value2[p])*Range
Value6[p] = Value2[p]*Range;
Value7[p] = ( Value2[p]-Value1[p])*Range;
if Range ~= 0 then
Value8[p] = Value1[p]/Range;
Value9[p] = ( Value1[p]-Value2[p])/Range;
Value10[p] = Value2[p]/Range;
Value11[p] = ( Value2[p]-Value1[p])/Range;
Value12[p] = Value3[p]/Range;
end
Value13[p] = Value3[p] + Value3[p-1];
Value14[p] = (Value1[p]+Value1[p-1])*(mathex.max(source.high,p-2+1,p) - mathex.min(source.low,p-2+1,p));
Value15[p] = (Value1[p]+Value1[p-1] - Value2[p] - Value2[p-1]) * (mathex.max(source.high,p-2+1,p) - mathex.min(source.low,p-2+1,p));
Value16[p] = (Value2[p]+Value2[p-1])*(mathex.max(source.high,p-2+1,p) - mathex.min(source.low,p-2+1,p));
Value17[p] = (Value2[p]+Value2[p-1] - Value1[p] - Value1[p-1]) * (mathex.max(source.high,p-2+1,p) - mathex.min(source.low,p-2+1,p));
if mathex.max(source.high,p-2+1,p) ~= mathex.min(source.low,p-2+1,p) then
Value18[p] = (Value1[p] + Value1[p-1])/(mathex.max(source.high,p-2+1,p) - mathex.min(source.low,p-2+1,p));
end
Value19[p] = (Value1[p]+Value1[p-1] - Value2[p] - Value2[p-1]) / (mathex.max(source.high,p-2+1,p) - mathex.min(source.low,p-2+1,p));
Value20[p] = (Value2[p]+Value2[p-1]) / (mathex.max(source.high,p-2+1,p) - mathex.min(source.low,p-2+1,p));
Value21[p] = (Value2[p]+Value2[p-1] - Value1[p] - Value1[p-1]) / (mathex.max(source.high,p-2+1,p) - mathex.min(source.low,p-2+1,p));
Value22[p] = Value13[p]/(mathex.max(source.high,p-2+1,p) - mathex.min(source.low,p-2+1,p));
VolumeBar:setColor(period, instance.parameters.VolumeBar_color); -- Fix to ensure default bar colour is correct
if not instance.parameters.TwoBars then
--Con 1 or Con 11
if (Value3[p] == mathex.min(Value3,p-Back+1,p)) then -- Yellow -- TwoBars or (Vlaue13[p] == mathex.min(Value13,p-Back+1,p)) then
VolumeBar:setColor(period,instance.parameters.LowVol_color);
end
--Con 2 or Con 3 or Con 8 or Con 9 or Con 12 or Con 13 or Con 18 or con 19
if (Value4[p] == mathex.max(Value4,p-Back+1,p) and CLOSE > OPEN) or
(Value5[p] == mathex.max(Value5,p-Back+1,p) and CLOSE > OPEN) or
(Value10[p] == mathex.min(Value10,p-Back+1,p) and CLOSE > OPEN) or
(Value11[p] == mathex.min(Value11,p-Back+1,p) and CLOSE > OPEN) then --RED -- TwoBars or (Vlaue13[p] == mathex.min(Value13,p-Back+1,p)) then
VolumeBar:setColor(period,instance.parameters.ClimaxUp_color);
end
--Con 4 or Con 5 or Con 6 or Con 7 or Con 14 or Con 15 or Con 16 or con 17
if (Value6[p] == mathex.max(Value6,p-Back+1,p) and CLOSE < OPEN) or
(Value7[p] == mathex.max(Value7,p-Back+1,p) and CLOSE < OPEN) or
(Value8[p] == mathex.min(Value8,p-Back+1,p) and CLOSE < OPEN) or
(Value9[p] == mathex.min(Value9,p-Back+1,p) and CLOSE < OPEN) then -- White
VolumeBar:setColor(period,instance.parameters.ClimaxDn_color);
end
-- Churn Con 10
if Value12[p] == mathex.max(Value12,p-Back+1,p) then -- Green
VolumeBar:setColor(period,instance.parameters.DensityUp_color);
end
--ClimaxChurn
if (Value12[p] == mathex.max(Value12,p-Back+1,p) ) and
( (Value4[p] == mathex.max(Value4,p-Back+1,p) and CLOSE > OPEN) or
(Value5[p] == mathex.max(Value5,p-Back+1,p) and CLOSE > OPEN) or
(Value10[p] == mathex.min(Value10,p-Back+1,p) and CLOSE > OPEN) or
(Value11[p] == mathex.min(Value11,p-Back+1,p) and CLOSE > OPEN) or
(Value6[p] == mathex.max(Value6,p-Back+1,p) and CLOSE < OPEN) or
(Value7[p] == mathex.max(Value7,p-Back+1,p) and CLOSE < OPEN) or
(Value8[p] == mathex.min(Value8,p-Back+1,p) and CLOSE < OPEN) or
(Value9[p] == mathex.min(Value9,p-Back+1,p) and CLOSE < OPEN) ) then
VolumeBar:setColor(period,instance.parameters.DensityDn_color);
end
else
--Con 1 or Con 11
if (Value13[p] == mathex.min(Value13,p-Back+1,p)) then -- Yellow -- TwoBars or (Vlaue13[p] == mathex.min(Value13,p-Back+1,p)) then
VolumeBar:setColor(period,instance.parameters.LowVol_color);
end
--Con 2 or Con 3 or Con 8 or Con 9 or Con 12 or Con 13 or Con 18 or con 19
if ((Value14[p] == mathex.max(Value14,p-Back+1,p)) and (CLOSE > OPEN) and (source.close[p-1] > source.open[p-1])) or
((Value15[p] == mathex.max(Value15,p-Back+1,p)) and (CLOSE > OPEN) and (source.close[p-1] > source.open[p-1])) or
((Value20[p] == mathex.min(Value20,p-Back+1,p)) and (CLOSE > OPEN) and (source.close[p-1] > source.open[p-1])) or
((Value21[p] == mathex.min(Value21,p-Back+1,p)) and (CLOSE > OPEN) and (source.close[p-1] > source.open[p-1])) then --RED -- TwoBars or (Vlaue13[p] == mathex.min(Value13,p-Back+1,p)) then
VolumeBar:setColor(period,instance.parameters.ClimaxUp_color);
end
--Con 4 or Con 5 or Con 6 or Con 7 or Con 14 or Con 15 or Con 16 or con 17
if ((Value16[p] == mathex.max(Value16,p-Back+1,p)) and (CLOSE < OPEN) and (source.close[p-1] < source.open[p-1])) or
((Value17[p] == mathex.max(Value17,p-Back+1,p)) and (CLOSE < OPEN) and (source.close[p-1] < source.open[p-1])) or
((Value18[p] == mathex.min(Value18,p-Back+1,p)) and (CLOSE < OPEN) and (source.close[p-1] < source.open[p-1])) or
((Value19[p] == mathex.min(Value19,p-Back+1,p)) and (CLOSE < OPEN) and (source.close[p-1] < source.open[p-1])) then -- White
VolumeBar:setColor(period,instance.parameters.ClimaxDn_color);
end
-- Churn Con 10
if Value22[p] == mathex.max(Value22,p-Back+1,p) then -- Green
VolumeBar:setColor(period,instance.parameters.DensityUp_color);
end
--ClimaxChurn
if (Value22[p] == mathex.max(Value22,p-Back+1,p) ) and
( ((Value14[p] == mathex.max(Value14,p-Back+1,p)) and (CLOSE > OPEN) and (source.close[p-1] > source.open[p-1])) or
((Value15[p] == mathex.max(Value15,p-Back+1,p)) and (CLOSE > OPEN) and (source.close[p-1] > source.open[p-1])) or
((Value20[p] == mathex.min(Value20,p-Back+1,p)) and (CLOSE > OPEN) and (source.close[p-1] > source.open[p-1])) or
((Value21[p] == mathex.min(Value21,p-Back+1,p)) and (CLOSE > OPEN) and (source.close[p-1] > source.open[p-1])) or
((Value16[p] == mathex.max(Value16,p-Back+1,p)) and (CLOSE < OPEN) and (source.close[p-1] < source.open[p-1])) or
((Value17[p] == mathex.max(Value17,p-Back+1,p)) and (CLOSE < OPEN) and (source.close[p-1] < source.open[p-1])) or
((Value18[p] == mathex.min(Value18,p-Back+1,p)) and (CLOSE < OPEN) and (source.close[p-1] < source.open[p-1])) or
((Value19[p] == mathex.min(Value19,p-Back+1,p)) and (CLOSE < OPEN) and (source.close[p-1] < source.open[p-1])) ) then
VolumeBar:setColor(period,instance.parameters.DensityDn_color);
end
end
end
end
I did not code this indicator and take no credit for it. All I did was the following fix.
- Code: Select all
VolumeBar:setColor(period, instance.parameters.VolumeBar_color); -- Fix to ensure default bar colour is correct
EDIT: I also added the "decimal place / precision" change which is mentioned a few posts down.