1774 lines
41 KiB
Plaintext
1774 lines
41 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 Class Library
|
|
// --------------------------------------
|
|
// Name: XC121SMCCycleHelper
|
|
// Description: provides all based classes for use ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// Imports ...
|
|
#include "../../Classes/x-saherelm.x-bar.analyser.class.mq5"
|
|
#include "../../Classes/x-saherelm.x-poi.class.mq5"
|
|
#include "../Libraries/x-121.smc.lib.mq5"
|
|
|
|
//
|
|
// Definitions ...
|
|
|
|
//
|
|
// Implementations ...
|
|
|
|
enum ENUM_X_CYCLES
|
|
{
|
|
X_CYCLE_NONE,
|
|
X_CYCLE_TRIGGER,
|
|
X_CYCLE_DECISION,
|
|
X_CYCLE_ANALYSE,
|
|
X_CYCLE_VERIFICATION,
|
|
X_CYCLE_CONSOLIDATION,
|
|
X_CYCLE_VISION,
|
|
};
|
|
|
|
string ToString(ENUM_X_CYCLES value)
|
|
{
|
|
//
|
|
string result = EnumToString(value);
|
|
|
|
//
|
|
StringReplace(result, "X_CYCLE_", "");
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
enum ENUM_X_CYCLE_EVENTS
|
|
{
|
|
SAR_CHANGE_DETECTED,
|
|
NEW_PEAK_DETECTED,
|
|
NEW_VALE_DETECTED,
|
|
PIVOT_POINT_DETECTED,
|
|
VWAP_ORDER_CHANGE_ETECTED,
|
|
VWAP_STATE_CHANGE_DETCTED,
|
|
CONSOLIDATION_BREAKED_DETECTED,
|
|
PEAK_PIVOT_STARTED,
|
|
PEAK_PIVOT_ENDED,
|
|
VALE_PIVOT_STARTED,
|
|
VALE_PIVOT_ENDED,
|
|
};
|
|
|
|
class XC121SMCCycleHelper : public XCBase
|
|
{
|
|
//
|
|
public:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// X121 ...
|
|
XCX121Helper *mX121Helper;
|
|
|
|
//
|
|
// POI Detector ...
|
|
XCPOIDrawer *mPOIDrawer;
|
|
XCPOIDetector *mPOIDetector;
|
|
|
|
//
|
|
// Bar Analyser
|
|
XCBarAnalyser *mBarAnalyser;
|
|
|
|
//
|
|
// Constructor(s) ...
|
|
XC121SMCCycleHelper()
|
|
{
|
|
Default();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
~XC121SMCCycleHelper()
|
|
{
|
|
DeInit();
|
|
}
|
|
|
|
//
|
|
// Getter/Setter(s) ...
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Initialize ...
|
|
*
|
|
* @param symbol: String ...
|
|
* @param period: ENUM_TIMEFRAMES member ...
|
|
* @param x121Inputs: X121Inputs instance ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool Init(
|
|
string symbol,
|
|
ENUM_TIMEFRAMES period,
|
|
X121Inputs &x121Inputs,
|
|
int requiredPOIS = 50 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (requiredPOIS < 10)
|
|
{
|
|
requiredPOIS = 10;
|
|
}
|
|
|
|
//
|
|
result = IsValid(symbol) &&
|
|
IsValid(period);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// X121 ...
|
|
mX121Helper = new XCX121Helper();
|
|
result = mX121Helper.Init(
|
|
symbol,
|
|
period,
|
|
x121Inputs //
|
|
);
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mPOIDetector = new XCPOIDetector(
|
|
symbol,
|
|
period //
|
|
);
|
|
mPOIDetector.MaxNumberOfRequiredPOIs(requiredPOIS);
|
|
mPOIDetector.Init();
|
|
|
|
//
|
|
// Initialize Bar Analyser Class Instance ...
|
|
mBarAnalyser = new XCBarAnalyser();
|
|
|
|
//
|
|
// Initial and Configure POI Drawer if Required ...
|
|
mPOIDrawer = new XCPOIDrawer();
|
|
mPOIDrawer.ChartIdentification(0);
|
|
mPOIDrawer.SubWindowIdentification(0);
|
|
|
|
//
|
|
mPOIDrawer.DemandZoneFill(false);
|
|
mPOIDrawer.SupplyZoneFill(false);
|
|
mPOIDrawer.BullishFVGFill(false);
|
|
mPOIDrawer.BearishFVGFill(false);
|
|
mPOIDrawer.SupportZoneFill(false);
|
|
mPOIDrawer.ResistanceZoneFill(false);
|
|
mPOIDrawer.BullishOrderBlockFill(false);
|
|
mPOIDrawer.BearishOrderBlockFill(false);
|
|
|
|
//
|
|
// Set Chart Style ...
|
|
ApplyChartStyle();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Symbol ...
|
|
*
|
|
* @return ( string )
|
|
*/
|
|
string GetSymbol()
|
|
{
|
|
//
|
|
string result = NULL;
|
|
|
|
//
|
|
result = mX121Helper.GetSymbol();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve TimeFrame (Period) ...
|
|
*
|
|
* @return ( ENUM_TIMEFRAMES )
|
|
*/
|
|
ENUM_TIMEFRAMES GetPeriod()
|
|
{
|
|
//
|
|
ENUM_TIMEFRAMES result = NULL;
|
|
|
|
//
|
|
result = mX121Helper.GetPeriod();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get Specified Bar ...
|
|
*
|
|
* @param source: XOHCL instance, Source Bar ...
|
|
* @param bar: XOHCL instance, Dest Bar ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBar(
|
|
XOHCL &source,
|
|
XOHCL &bar //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result =
|
|
IsValid(symbol) &&
|
|
IsValid(period) &&
|
|
source.IsValid();
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int index = iBarShift(
|
|
symbol,
|
|
period,
|
|
source.time //
|
|
);
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
index //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
bar.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Specified Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
* @param index: Integer ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBar(
|
|
XOHCL &bar,
|
|
int index = 0 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
bar.Clean();
|
|
|
|
//
|
|
if (index < 0)
|
|
{
|
|
index = 0;
|
|
}
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result = bar.Init(
|
|
symbol,
|
|
period,
|
|
index //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Specified Bar ...
|
|
*
|
|
* @param bar: XOHCL instance ...
|
|
* @param time: Datetime ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetBar(
|
|
XOHCL &bar,
|
|
datetime time = NULL //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int index = GetBarIndex(time);
|
|
result = GetBar(bar,
|
|
index //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Specified Time Bar Index ...
|
|
*
|
|
* @param time: DateTime ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int GetBarIndex(datetime time = NULL)
|
|
{
|
|
//
|
|
int result = -1;
|
|
|
|
//
|
|
time = NormalizeTime(time);
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
result = iBarShift(
|
|
symbol,
|
|
period,
|
|
time //
|
|
);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Market Structure Method 2 ...
|
|
*
|
|
* @param model: XMarketStructure instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectMarketStructure(
|
|
ENUM_X_DIRECTION &dir,
|
|
int pivotsCount = 3 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
int barIndex = 0;
|
|
|
|
//
|
|
if (pivotsCount < 3)
|
|
{
|
|
pivotsCount = 3;
|
|
}
|
|
|
|
//
|
|
dir = X_DIRECTION_NONE;
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
int hpIndex = -1;
|
|
int hpIndexes[];
|
|
double hpValues[];
|
|
|
|
//
|
|
int lvIndex = -1;
|
|
int lvIndexes[];
|
|
double lvValues[];
|
|
|
|
//
|
|
for (int i = 0; i < pivotsCount; i++)
|
|
{
|
|
//
|
|
hpIndex = barIndex;
|
|
lvIndex = barIndex;
|
|
|
|
//
|
|
double lastHP = 0;
|
|
double lastLV = 0;
|
|
|
|
//
|
|
int hpCount = ArraySize(hpIndexes);
|
|
int lvCount = ArraySize(lvIndexes);
|
|
|
|
//
|
|
if (IsValidSize(hpCount))
|
|
{
|
|
//
|
|
lastHP = hpValues[hpCount - 1];
|
|
hpIndex = hpIndexes[hpCount - 1];
|
|
}
|
|
|
|
//
|
|
if (IsValidSize(lvCount))
|
|
{
|
|
//
|
|
lastLV = lvValues[lvCount - 1];
|
|
lvIndex = lvIndexes[lvCount - 1];
|
|
}
|
|
|
|
//
|
|
if (lastHP == 0)
|
|
{
|
|
//
|
|
lastHP = mX121Helper
|
|
.xpvHelper
|
|
.GetPeak(hpIndex);
|
|
}
|
|
|
|
//
|
|
if (lastLV == 0)
|
|
{
|
|
//
|
|
lastLV = mX121Helper
|
|
.xpvHelper
|
|
.GetVale(lvIndex);
|
|
}
|
|
|
|
//
|
|
int highestPeakIndex = -1;
|
|
double highesrPeak =
|
|
mX121Helper
|
|
.xpvHelper
|
|
.GetHigherPeak(
|
|
highestPeakIndex,
|
|
lastHP,
|
|
hpIndex //
|
|
);
|
|
if (IsValidIndex(highestPeakIndex))
|
|
{
|
|
//
|
|
Add(
|
|
highestPeakIndex,
|
|
hpIndexes //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
highesrPeak,
|
|
hpValues //
|
|
);
|
|
}
|
|
|
|
//
|
|
int lowestValeIndex = -1;
|
|
double lowestVale =
|
|
mX121Helper
|
|
.xpvHelper
|
|
.GetLowerVale(
|
|
lowestValeIndex,
|
|
lastLV,
|
|
lvIndex //
|
|
);
|
|
if (IsValidIndex(lowestValeIndex))
|
|
{
|
|
//
|
|
Add(
|
|
lowestValeIndex,
|
|
lvIndexes //
|
|
);
|
|
|
|
//
|
|
Add(
|
|
lowestVale,
|
|
lvValues //
|
|
);
|
|
}
|
|
|
|
//
|
|
bool canBreak = ArraySize(hpIndexes) >= pivotsCount ||
|
|
ArraySize(lvIndexes) >= pivotsCount;
|
|
if (canBreak)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
ArrayReverse(hpValues);
|
|
ArrayReverse(hpIndexes);
|
|
int countHPs = ArraySize(hpIndexes);
|
|
|
|
//
|
|
ArrayReverse(lvValues);
|
|
ArrayReverse(lvIndexes);
|
|
int countLVs = ArraySize(lvIndexes);
|
|
|
|
//
|
|
bool isValidHPs = countHPs >= pivotsCount;
|
|
bool isValidLVs = countLVs >= pivotsCount;
|
|
|
|
//
|
|
result = isValidHPs ||
|
|
isValidLVs;
|
|
if (!result)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
if (isValidHPs && isValidLVs)
|
|
{
|
|
//
|
|
hpIndex = hpIndexes[countHPs - 1];
|
|
lvIndex = lvIndexes[countLVs - 1];
|
|
}
|
|
|
|
//
|
|
dir =
|
|
!isValidHPs && isValidLVs
|
|
? X_DIRECTION_BULLISH
|
|
: !isValidLVs && isValidHPs
|
|
? X_DIRECTION_BEARISH
|
|
: hpIndex < lvIndex
|
|
? X_DIRECTION_BEARISH
|
|
: lvIndex < hpIndex
|
|
? X_DIRECTION_BULLISH
|
|
: X_DIRECTION_ALL;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Order Blocks ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectOrderBlocks(
|
|
XCOrderBlock *&bullishOrderBlocks[],
|
|
XCOrderBlock *&bearishOrderBlocks[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(bullishOrderBlocks);
|
|
Clean(bearishOrderBlocks);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int bullOBsCount = DetectValidOrderBlocks(
|
|
X_DIRECTION_BULLISH,
|
|
state,
|
|
bullishOrderBlocks //
|
|
);
|
|
|
|
//
|
|
int bearOBsCount = DetectValidOrderBlocks(
|
|
X_DIRECTION_BEARISH,
|
|
state,
|
|
bearishOrderBlocks //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(bullOBsCount +
|
|
bearOBsCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Fair Value Gaps ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectFairValueGaps(
|
|
XCFVG *&bullishFairValueGaps[],
|
|
XCFVG *&bearishFairValueGaps[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(bullishFairValueGaps);
|
|
Clean(bearishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild();
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int bullFVGsCount = DetectValidFairValueGaps(
|
|
X_DIRECTION_BULLISH,
|
|
state,
|
|
bullishFairValueGaps //
|
|
);
|
|
|
|
//
|
|
int bearFVGsCount = DetectValidFairValueGaps(
|
|
X_DIRECTION_BEARISH,
|
|
state,
|
|
bearishFairValueGaps //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(bullFVGsCount +
|
|
bearFVGsCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Support Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSupportZones(
|
|
XCOrderBlock *&bullishOrderBlocks[],
|
|
XCFVG *&bullishFairValueGaps[],
|
|
XCSupportZone *&supportZones[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(supportZones);
|
|
|
|
//
|
|
int obsCount = ArraySize(bullishOrderBlocks);
|
|
int fvgsCount = ArraySize(bullishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild() &&
|
|
IsValidSize(obsCount + fvgsCount);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int supportZonesCount = DetectValidSupportZones(
|
|
state,
|
|
bullishOrderBlocks,
|
|
bullishFairValueGaps,
|
|
supportZones //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(supportZonesCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Resistance Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectResistanceZones(
|
|
XCOrderBlock *&bearishOrderBlocks[],
|
|
XCFVG *&bearishFairValueGaps[],
|
|
XCResistanceZone *&resistanceZones[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(resistanceZones);
|
|
|
|
//
|
|
int obsCount = ArraySize(bearishOrderBlocks);
|
|
int fvgsCount = ArraySize(bearishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild() &&
|
|
IsValidSize(obsCount + fvgsCount);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int resistanceZonesCount = DetectValidResistanceZones(
|
|
state,
|
|
bearishOrderBlocks,
|
|
bearishFairValueGaps,
|
|
resistanceZones //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(resistanceZonesCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Demand Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectDemandZones(
|
|
XCOrderBlock *&bullishOrderBlocks[],
|
|
XCFVG *&bullishFairValueGaps[],
|
|
XCDemandZone *&demandZones[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(demandZones);
|
|
|
|
//
|
|
int obsCount = ArraySize(bullishOrderBlocks);
|
|
int fvgsCount = ArraySize(bullishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild() &&
|
|
IsValidSize(obsCount + fvgsCount);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int demandZonesCount = DetectValidDemandZones(
|
|
state,
|
|
bullishOrderBlocks,
|
|
bullishFairValueGaps,
|
|
demandZones //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(demandZonesCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Detect Supply Zones ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool DetectSupplyZones(
|
|
XCOrderBlock *&bearishOrderBlocks[],
|
|
XCFVG *&bearishFairValueGaps[],
|
|
XCSupplyZone *&supplyZones[] //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
Clean(supplyZones);
|
|
|
|
//
|
|
int obsCount = ArraySize(bearishOrderBlocks);
|
|
int fvgsCount = ArraySize(bearishFairValueGaps);
|
|
|
|
//
|
|
XPOIState state;
|
|
mPOIDetector.GetState(state);
|
|
bool isValid = state.IsValid() &&
|
|
state.HasChild() &&
|
|
IsValidSize(obsCount + fvgsCount);
|
|
if (!isValid)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
//
|
|
int supplyZonesCount = DetectValidSupplyZones(
|
|
state,
|
|
bearishOrderBlocks,
|
|
bearishFairValueGaps,
|
|
supplyZones //
|
|
);
|
|
|
|
//
|
|
result = IsValidSize(supplyZonesCount);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Prev Peak Repetition ...
|
|
*
|
|
* @param barIndex: Integer ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountPrevPeakRepetition(
|
|
int barIndex = 0//
|
|
) {
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0) {
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int index = barIndex + 1;
|
|
double value = mX121Helper.xpvHelper.GetPeak(index);
|
|
index++;
|
|
|
|
//
|
|
bool canContinue = true;
|
|
while(canContinue) {
|
|
//
|
|
double iValue = mX121Helper.xpvHelper.GetPeak(index);
|
|
|
|
//
|
|
canContinue = iValue == value;
|
|
if (canContinue) {
|
|
//
|
|
index++;
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Count Prev Vale Repetition ...
|
|
*
|
|
* @param barIndex: Integer ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int CountPrevValeRepetition(
|
|
int barIndex = 0//
|
|
) {
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
if (barIndex < 0) {
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
int index = barIndex + 1;
|
|
double value = mX121Helper.xpvHelper.GetVale(index);
|
|
index++;
|
|
|
|
//
|
|
bool canContinue = true;
|
|
while(canContinue) {
|
|
//
|
|
double iValue = mX121Helper.xpvHelper.GetVale(index);
|
|
|
|
//
|
|
canContinue = iValue == value;
|
|
if (canContinue) {
|
|
//
|
|
index++;
|
|
result++;
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get Cycle State and Update it ...
|
|
*
|
|
* @param state: X121SMCCycleState instance Reference ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetCycleState(X121SMCCycleState &state)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
string symbol = GetSymbol();
|
|
ENUM_TIMEFRAMES period = GetPeriod();
|
|
|
|
//
|
|
state.symbol = symbol;
|
|
state.period = period;
|
|
|
|
//
|
|
datetime cTime = TimeCurrent();
|
|
|
|
//
|
|
// Detect Order Block ...
|
|
|
|
//
|
|
bool hasBullishOBs = state.HasBullishOBs();
|
|
int bullishOBsCount = state.CountBullishOBs();
|
|
|
|
//
|
|
bool hasBearishOBs = state.HasBearishOBs();
|
|
int bearishOBsCount = state.CountBearishOBs();
|
|
|
|
//
|
|
bool hasOBs = hasBullishOBs &&
|
|
hasBearishOBs;
|
|
if (!hasOBs)
|
|
{
|
|
//
|
|
XCOrderBlock *bullishOBs[];
|
|
XCOrderBlock *bearishOBs[];
|
|
hasOBs = DetectOrderBlocks(
|
|
bullishOBs,
|
|
bearishOBs //
|
|
);
|
|
|
|
//
|
|
if (hasOBs &&
|
|
!hasBullishOBs)
|
|
{
|
|
//
|
|
Copy(
|
|
bullishOBs,
|
|
state.bullishOBs //
|
|
);
|
|
}
|
|
|
|
//
|
|
if (hasOBs &&
|
|
!hasBearishOBs)
|
|
{
|
|
//
|
|
Copy(
|
|
bearishOBs,
|
|
state.bearishOBs //
|
|
);
|
|
}
|
|
|
|
//
|
|
hasBullishOBs = state.HasBullishOBs();
|
|
bullishOBsCount = state.CountBullishOBs();
|
|
|
|
//
|
|
hasBearishOBs = state.HasBearishOBs();
|
|
bearishOBsCount = state.CountBearishOBs();
|
|
}
|
|
|
|
//
|
|
// Update Order Blocks Time ...
|
|
if (hasOBs)
|
|
{
|
|
//
|
|
if (hasBullishOBs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishOBsCount; i++)
|
|
{
|
|
state.bullishOBs[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasBearishOBs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishOBsCount; i++)
|
|
{
|
|
state.bearishOBs[i].To(cTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Fair Value Gap ...
|
|
|
|
//
|
|
bool hasBullishFVGs = state.HasBullishFVGs();
|
|
int bullishFVGsCount = state.CountBullishFVGs();
|
|
|
|
//
|
|
bool hasBearishFVGs = state.HasBearishFVGs();
|
|
int bearishFVGsCount = state.CountBearishFVGs();
|
|
|
|
//
|
|
bool hasFVGs = hasBullishFVGs &&
|
|
hasBearishFVGs;
|
|
if (!hasFVGs)
|
|
{
|
|
//
|
|
XCFVG *bullishFVGs[];
|
|
XCFVG *bearishFVGs[];
|
|
hasFVGs = DetectFairValueGaps(
|
|
bullishFVGs,
|
|
bearishFVGs //
|
|
);
|
|
|
|
//
|
|
if (hasFVGs &&
|
|
!hasBullishFVGs)
|
|
{
|
|
//
|
|
Copy(
|
|
bullishFVGs,
|
|
state.bullishFVGs //
|
|
);
|
|
}
|
|
|
|
//
|
|
if (hasFVGs &&
|
|
!hasBearishFVGs)
|
|
{
|
|
//
|
|
Copy(
|
|
bearishFVGs,
|
|
state.bearishFVGs //
|
|
);
|
|
}
|
|
|
|
//
|
|
hasBullishFVGs = state.HasBullishFVGs();
|
|
bullishFVGsCount = state.CountBullishFVGs();
|
|
|
|
//
|
|
hasBearishFVGs = state.HasBearishFVGs();
|
|
bearishFVGsCount = state.CountBearishFVGs();
|
|
}
|
|
|
|
//
|
|
// Update Fair Value Gaps Time ...
|
|
if (hasFVGs)
|
|
{
|
|
//
|
|
if (hasBullishFVGs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishFVGsCount; i++)
|
|
{
|
|
state.bullishFVGs[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
if (hasBearishFVGs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishFVGsCount; i++)
|
|
{
|
|
state.bearishFVGs[i].To(cTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Support Zones ...
|
|
|
|
//
|
|
bool hasSupportZones = state.HasSupportZones();
|
|
int supportZonesCount = state.CountSupportZones();
|
|
|
|
//
|
|
if (!hasSupportZones)
|
|
{
|
|
//
|
|
XCSupportZone *supportZones[];
|
|
hasSupportZones = DetectSupportZones(
|
|
state.bullishOBs,
|
|
state.bullishFVGs,
|
|
supportZones //
|
|
);
|
|
|
|
//
|
|
if (hasSupportZones)
|
|
{
|
|
//
|
|
Copy(
|
|
supportZones,
|
|
state.supportZones //
|
|
);
|
|
|
|
//
|
|
supportZonesCount = state.CountSupportZones();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Support Zones Time ...
|
|
if (hasSupportZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < supportZonesCount; i++)
|
|
{
|
|
state.supportZones[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Demand Zones ...
|
|
|
|
//
|
|
bool hasDemandZones = state.HasDemandZones();
|
|
int demandZonesCount = state.CountDemandZones();
|
|
|
|
//
|
|
if (!hasDemandZones)
|
|
{
|
|
//
|
|
XCDemandZone *demandZones[];
|
|
hasDemandZones = DetectDemandZones(
|
|
state.bullishOBs,
|
|
state.bullishFVGs,
|
|
demandZones //
|
|
);
|
|
|
|
//
|
|
if (hasDemandZones)
|
|
{
|
|
//
|
|
Copy(
|
|
demandZones,
|
|
state.demandZones //
|
|
);
|
|
|
|
//
|
|
demandZonesCount = state.CountDemandZones();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Support Zones Time ...
|
|
if (hasDemandZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < demandZonesCount; i++)
|
|
{
|
|
state.demandZones[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Resistance Zones ...
|
|
|
|
//
|
|
bool hasResistanceZones = state.HasResistanceZones();
|
|
int resistanceZonesCount = state.CountResistanceZones();
|
|
|
|
//
|
|
if (!hasResistanceZones)
|
|
{
|
|
//
|
|
XCResistanceZone *resistanceZones[];
|
|
hasResistanceZones = DetectResistanceZones(
|
|
state.bearishOBs,
|
|
state.bearishFVGs,
|
|
resistanceZones //
|
|
);
|
|
|
|
//
|
|
if (hasResistanceZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < ArraySize(resistanceZones); i++)
|
|
{
|
|
resistanceZones[i].To(cTime);
|
|
}
|
|
|
|
//
|
|
Copy(
|
|
resistanceZones,
|
|
state.resistanceZones //
|
|
);
|
|
|
|
//
|
|
resistanceZonesCount = state.CountResistanceZones();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Resistance Zones Time ...
|
|
if (hasResistanceZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < resistanceZonesCount; i++)
|
|
{
|
|
state.resistanceZones[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Detect Supply Zones ...
|
|
|
|
//
|
|
bool hasSupplyZones = state.HasSupplyZones();
|
|
int supplyZonesCount = state.CountSupplyZones();
|
|
|
|
//
|
|
if (!hasSupplyZones)
|
|
{
|
|
//
|
|
XCSupplyZone *supplyZones[];
|
|
hasSupplyZones = DetectSupplyZones(
|
|
state.bearishOBs,
|
|
state.bearishFVGs,
|
|
supplyZones //
|
|
);
|
|
|
|
//
|
|
if (hasSupplyZones)
|
|
{
|
|
//
|
|
Copy(
|
|
supplyZones,
|
|
state.supplyZones //
|
|
);
|
|
|
|
//
|
|
supplyZonesCount = state.CountSupplyZones();
|
|
}
|
|
}
|
|
|
|
//
|
|
// Update Resistance Zones Time ...
|
|
if (hasSupplyZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < supplyZonesCount; i++)
|
|
{
|
|
state.supplyZones[i].To(cTime);
|
|
}
|
|
}
|
|
|
|
//
|
|
result = state.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Cycle Conditions ...
|
|
*
|
|
* @param events: ENUM_X_CYCLE_EVENTS member, Array ...
|
|
* @param conditions: X121SMCCycleConditions instance ...
|
|
* @param barIndex: Integer ...
|
|
* @param loopback: Integer ...
|
|
*
|
|
* @return ( bool )
|
|
*/
|
|
bool GetConditions(
|
|
ENUM_X_CYCLE_EVENTS &events[],
|
|
ENUM_XPOI_EVENTS &poiEvents[],
|
|
X121SMCCycleConditions &conditions,
|
|
int barIndex = 0,
|
|
int loopback = 7 //
|
|
)
|
|
{
|
|
//
|
|
bool result = false;
|
|
|
|
//
|
|
if (barIndex < 0)
|
|
{
|
|
barIndex = 0;
|
|
}
|
|
|
|
//
|
|
if (loopback < 5)
|
|
{
|
|
loopback = 5;
|
|
}
|
|
|
|
//
|
|
Clean(events);
|
|
Clean(poiEvents);
|
|
conditions.Clean();
|
|
|
|
//
|
|
result = mX121Helper.GetConditions(
|
|
conditions.x121Conditions,
|
|
barIndex,
|
|
loopback //
|
|
);
|
|
if (!result)
|
|
{
|
|
//
|
|
conditions.Clean();
|
|
return result;
|
|
}
|
|
|
|
//
|
|
mPOIDetector.Update(poiEvents);
|
|
mPOIDetector.GetState(conditions.state);
|
|
|
|
//
|
|
conditions.symbol = conditions.x121Conditions.symbol;
|
|
conditions.period = conditions.x121Conditions.period;
|
|
conditions.time = TimeCurrent();
|
|
|
|
//
|
|
result = conditions.IsValid();
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Tools ...
|
|
|
|
/**
|
|
* Draw Cycle State ...
|
|
*
|
|
* @param state: X121SMCCyleState instance Reference ...
|
|
*
|
|
* @return ( int )
|
|
*/
|
|
int DrawCycleState(
|
|
X121SMCCycleState &state,
|
|
XCBaseObject *&drawnObjects[],
|
|
bool drawOrderBlocks = true,
|
|
bool drawFairValueGaps = true,
|
|
bool drawSupplyAndDemandZones = false,
|
|
bool drawSupportAndResistanceZones = false //
|
|
)
|
|
{
|
|
//
|
|
int result = 0;
|
|
|
|
//
|
|
// Order Blocks ...
|
|
if (drawOrderBlocks)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullishOBs = state.HasBullishOBs();
|
|
int bullishOBsCount = state.CountBullishOBs();
|
|
if (hasBullishOBs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishOBsCount; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iOb = state.bullishOBs[i];
|
|
|
|
//
|
|
XCBullishOrderBlockObject *iObObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateBullishOrderBlock(
|
|
iOb,
|
|
iObObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearishOBs = state.HasBearishOBs();
|
|
int bearishOBsCount = state.CountBearishOBs();
|
|
if (hasBearishOBs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishOBsCount; i++)
|
|
{
|
|
//
|
|
XCOrderBlock *iOb = state.bearishOBs[i];
|
|
|
|
//
|
|
XCBearishOrderBlockObject *iObObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateBearishOrderBlock(
|
|
iOb,
|
|
iObObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Fair Value Gaps ...
|
|
if (drawFairValueGaps)
|
|
{
|
|
//
|
|
// Bullish ...
|
|
bool hasBullishFVGs = state.HasBullishFVGs();
|
|
int bullishFVGsCount = state.CountBullishFVGs();
|
|
if (hasBullishFVGs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bullishFVGsCount; i++)
|
|
{
|
|
//
|
|
XCFVG *iFVG = state.bullishFVGs[i];
|
|
|
|
//
|
|
XCBullishFairValueGapObject *iFVGObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateBullishFairValueGap(
|
|
iFVG,
|
|
iFVGObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iFVGObj.ZoneColor(clrLime);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iFVGObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Bearish ...
|
|
bool hasBearishFVGs = state.HasBearishFVGs();
|
|
int bearishFVGsCount = state.CountBearishFVGs();
|
|
if (hasBearishFVGs)
|
|
{
|
|
//
|
|
for (int i = 0; i < bearishFVGsCount; i++)
|
|
{
|
|
//
|
|
XCFVG *iFVG = state.bearishFVGs[i];
|
|
|
|
//
|
|
XCBearishFairValueGapObject *iFVGObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateBearishFairValueGap(
|
|
iFVG,
|
|
iFVGObj //
|
|
);
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iFVGObj.ZoneColor(clrRed);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iFVGObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Support and Resistance Zones ...
|
|
if (drawSupportAndResistanceZones)
|
|
{
|
|
//
|
|
// Support Zones ...
|
|
bool hasSupportZones = state.HasSupportZones();
|
|
int supportZonesCount = state.CountSupportZones();
|
|
if (hasSupportZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < supportZonesCount; i++)
|
|
{
|
|
//
|
|
XCSupportZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateSupportZone(
|
|
state.supportZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iObj.ZoneColor(clrDarkSeaGreen);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Resistance Zones ...
|
|
bool hasResistanceZones = state.HasResistanceZones();
|
|
int resistanceZonesCount = state.CountResistanceZones();
|
|
if (hasResistanceZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < resistanceZonesCount; i++)
|
|
{
|
|
//
|
|
XCResistanceZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateResistanceZone(
|
|
state.resistanceZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iObj.ZoneColor(clrSaddleBrown);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Supply and Demand Zones ...
|
|
if (drawSupplyAndDemandZones)
|
|
{
|
|
//
|
|
// Demand Zones ...
|
|
bool hasDemandZones = state.HasDemandZones();
|
|
int demandZonesCount = state.CountDemandZones();
|
|
if (hasDemandZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < demandZonesCount; i++)
|
|
{
|
|
//
|
|
XCDemandZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateDemandZone(
|
|
state.demandZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iObj.ZoneColor(clrDarkTurquoise);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Supply Zones ...
|
|
bool hasSupplyZones = state.HasSupplyZones();
|
|
int supplyZonesCount = state.CountSupplyZones();
|
|
if (hasSupplyZones)
|
|
{
|
|
//
|
|
for (int i = 0; i < supplyZonesCount; i++)
|
|
{
|
|
//
|
|
XCSupplyZoneObject *iObj;
|
|
bool isCreated = mPOIDrawer
|
|
.CreateSupplyZone(
|
|
state.supplyZones[i],
|
|
iObj //
|
|
);
|
|
|
|
//
|
|
if (isCreated)
|
|
{
|
|
//
|
|
iObj.ZoneColor(clrChocolate);
|
|
|
|
//
|
|
Add(
|
|
(XCBaseObject *)iObj,
|
|
drawnObjects //
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
result = ArraySize(drawnObjects);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Virtuals ...
|
|
|
|
/**
|
|
* Set Default Properties Values ...
|
|
*/
|
|
virtual void Default()
|
|
{
|
|
}
|
|
|
|
//
|
|
protected:
|
|
//
|
|
|
|
//
|
|
private:
|
|
//
|
|
// Props ...
|
|
|
|
//
|
|
// Actions ...
|
|
|
|
/**
|
|
* Release All Resources ...
|
|
*/
|
|
void DeInit()
|
|
{
|
|
//
|
|
ZeroMemory(mX121Helper);
|
|
ZeroMemory(mPOIDetector);
|
|
ZeroMemory(mBarAnalyser);
|
|
|
|
//
|
|
delete mX121Helper;
|
|
delete mPOIDetector;
|
|
delete mBarAnalyser;
|
|
}
|
|
|
|
/**
|
|
* Apply Chart Style ...
|
|
*/
|
|
void ApplyChartStyle()
|
|
{
|
|
//
|
|
// Retrieve Current Chart ID ...
|
|
long chartId = ChartID();
|
|
|
|
//
|
|
ENUM_CHART_MODE mMode = CHART_CANDLES; // chart's mMode
|
|
bool mShowBidLine = true; // show bid line
|
|
bool mShowAskLine = true; // show ask line
|
|
bool mShowGrid = false; // show grids on chart
|
|
bool mShowVolumes = false; // show volumes
|
|
bool mShowTradeLevels = true; // Displaying trade levels in the chart (levels of open positions, Stop Loss, Take Profit and pending orders)
|
|
bool mAutoScroll = true; // chart autoscroll
|
|
bool mQuickNavigation = true; // chart quick navigation state
|
|
color mForeGroundColor = clrWhite; // chart's foreground color
|
|
color mBackGroundColor = clrBlack; // chart's background color
|
|
color mUpColor = clrGreen; // Up Color
|
|
color mDownColor = clrRed; // Down Color
|
|
color mBullishColor = clrGreen; // Bullish color
|
|
color mBearishColor = clrRed; // Bearish color
|
|
color mGridColor = clrGray; // grid color
|
|
color mBidLineColor = clrGray; // bid line color
|
|
color mAskLineColor = clrRed; // ask line color
|
|
color mLineColor = clrLime; // line mMode and doji candlestick color
|
|
color mStopColor = clrGold; // Color of stop order levels (Stop Loss and Take Profit)
|
|
color mVolumesColor = clrGreen; // volumes color
|
|
|
|
//
|
|
ChartSetInteger(chartId, CHART_MODE, mMode);
|
|
ChartSetInteger(chartId, CHART_SHOW_BID_LINE, mShowBidLine);
|
|
ChartSetInteger(chartId, CHART_SHOW_ASK_LINE, mShowAskLine);
|
|
ChartSetInteger(chartId, CHART_SHOW_GRID, mShowGrid);
|
|
ChartSetInteger(chartId, CHART_SHOW_VOLUMES, mShowVolumes);
|
|
ChartSetInteger(chartId, CHART_SHOW_TRADE_LEVELS, mShowTradeLevels);
|
|
ChartSetInteger(chartId, CHART_AUTOSCROLL, mAutoScroll);
|
|
ChartSetInteger(chartId, CHART_QUICK_NAVIGATION, mQuickNavigation);
|
|
ChartSetInteger(chartId, CHART_COLOR_FOREGROUND, mForeGroundColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_BACKGROUND, mBackGroundColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CHART_UP, mUpColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CHART_DOWN, mDownColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CANDLE_BULL, mBullishColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CANDLE_BEAR, mBearishColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_GRID, mGridColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_BID, mBidLineColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_ASK, mAskLineColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_STOP_LEVEL, mStopColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_CHART_LINE, mLineColor);
|
|
ChartSetInteger(chartId, CHART_COLOR_VOLUME, mVolumesColor);
|
|
}
|
|
|
|
//
|
|
};
|