add XCHVWAP Indicator, extends it's Helper class and implement it's usage inside XCH strategy ...
444 lines
12 KiB
JavaScript
444 lines
12 KiB
JavaScript
//
|
|
// Import Requirements ...
|
|
const execSync = require("child_process").execSync;
|
|
const XFileTools = require("./Documents/JsModules/x-file.tools");
|
|
const XShellTools = require("./Documents/JsModules/x-shell.tools");
|
|
const XColorTools = require("./Documents/JsModules/x-color.tools");
|
|
|
|
//
|
|
// define constants ...
|
|
const projectsPath = XFileTools.joinPath(".", "Projects");
|
|
const packsPath = XFileTools.joinPath(".", "Packs");
|
|
const excludeWorkspaceFolders = [
|
|
"BKP",
|
|
"Documents",
|
|
"Images",
|
|
"Includes",
|
|
"Logs",
|
|
"Packs",
|
|
"Profiles",
|
|
"Projects",
|
|
"Scripts",
|
|
"Services",
|
|
"Shared Projects",
|
|
//
|
|
// Exclude Defaults ...
|
|
"Examples",
|
|
"Free Indicators",
|
|
"Advisors",
|
|
"Free Robots"
|
|
];
|
|
|
|
//
|
|
// Read Command Arguments ...
|
|
let projectName = process.argv[2];
|
|
let doPackProject = process.argv[3] || false;
|
|
|
|
//
|
|
// Make Decission to what to Do based on given args ...
|
|
if (!projectName ||
|
|
projectName == "" ||
|
|
projectName.length == 0) {
|
|
//
|
|
// Compile Whole MQL Workspace ...
|
|
doPackProject = false;
|
|
const workSpacePath = XFileTools.joinPath(".", __dirname);
|
|
|
|
//
|
|
doWorkspaceCompile(workSpacePath);
|
|
} else if (projectName == "--experts" || projectName == "**experts") {
|
|
//
|
|
// Compile Experts on Workspace ...
|
|
doPackProject = false;
|
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Experts");
|
|
|
|
//
|
|
doWorkspaceCompile(workSpacePath);
|
|
} else if (projectName == "--helpers" || projectName == "**helpers") {
|
|
//
|
|
// Compile Helpers on Workspace ...
|
|
doPackProject = false;
|
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Helpers");
|
|
|
|
//
|
|
doWorkspaceCompile(workSpacePath);
|
|
} else if (projectName == "--classes" || projectName == "**classes") {
|
|
//
|
|
// Compile Classes on Workspace ...
|
|
doPackProject = false;
|
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Classes");
|
|
|
|
//
|
|
doWorkspaceCompile(workSpacePath);
|
|
} else if (projectName == "--indicators" || projectName == "**indicators") {
|
|
//
|
|
// Compile Indicators on Workspace ...
|
|
doPackProject = false;
|
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Indicators");
|
|
|
|
//
|
|
doWorkspaceCompile(workSpacePath);
|
|
} else if (projectName == "--libraries" || projectName == "**libraries") {
|
|
//
|
|
// Compile Libraries on Workspace ...
|
|
doPackProject = false;
|
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Libraries");
|
|
|
|
//
|
|
doWorkspaceCompile(workSpacePath);
|
|
}else if (projectName == "--strategies" || projectName == "**strategies") {
|
|
//
|
|
// Compile Libraries on Workspace ...
|
|
doPackProject = false;
|
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Strategies");
|
|
|
|
//
|
|
doWorkspaceCompile(workSpacePath);
|
|
}else if (projectName == "--parsers" || projectName == "**parsers") {
|
|
//
|
|
// Compile Libraries on Workspace ...
|
|
doPackProject = false;
|
|
const workSpacePath = XFileTools.joinPath(".", __dirname, "Parsers");
|
|
|
|
//
|
|
doWorkspaceCompile(workSpacePath);
|
|
} else {
|
|
//
|
|
// Compile Specific Projects ...
|
|
//
|
|
// Prepare Project Folder Path ...
|
|
const prjPath = XFileTools.joinPath(projectsPath, projectName);
|
|
|
|
//
|
|
// Check Project Folder Exists ...
|
|
const isProjectFolderExists = XFileTools.isDirectoryExists(prjPath);
|
|
if (!isProjectFolderExists) {
|
|
//
|
|
const msg = "Project doesn't Exists ...";
|
|
console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red));
|
|
throw msg;
|
|
}
|
|
|
|
//
|
|
// Call Handler Function ...
|
|
doProjectCompile(prjPath);
|
|
}
|
|
|
|
//
|
|
async function doProjectCompile(path = "") {
|
|
//
|
|
let result = await handleProjectCompile(path);
|
|
if (result && doPackProject) {
|
|
result = await handleProjectPack(path);
|
|
}
|
|
}
|
|
|
|
//
|
|
async function doWorkspaceCompile(path = "") {
|
|
//
|
|
let mustCompileFiles = await readMQLFiles(path);
|
|
|
|
//
|
|
if (mustCompileFiles && mustCompileFiles.length > 0) {
|
|
//
|
|
// Loop through items ...
|
|
for (const f of mustCompileFiles) {
|
|
//
|
|
// Check Exclude ...
|
|
const fBaseName = XFileTools.basename(f);
|
|
let fPath = f.replace(fBaseName, "");
|
|
let isExclude = false;
|
|
for (const e of excludeWorkspaceFolders) {
|
|
//
|
|
isExclude = fPath.includes(e);
|
|
if (isExclude) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
if (isExclude) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// Log ...
|
|
console.log(
|
|
XColorTools.applyForegroundColor("try to compile: ", XColorTools.COLOR_NAMES.Yellow),
|
|
XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue)
|
|
);
|
|
|
|
//
|
|
const result = await compileMQLFile(f);
|
|
|
|
//
|
|
if (result.includes("0 errors")) {
|
|
//
|
|
const msg = "compiled successfully ...";
|
|
console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green));
|
|
} else {
|
|
//
|
|
const msg = "failed ...";
|
|
console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red));
|
|
throw msg;
|
|
}
|
|
}
|
|
|
|
//
|
|
return true;
|
|
}
|
|
|
|
//
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* read all content in project path and compile it one by one ...
|
|
*
|
|
* @param {string} path Project Path ...
|
|
*/
|
|
async function handleProjectCompile(path = "") {
|
|
//
|
|
let mustCompileFiles = await readMQLFiles(path);
|
|
|
|
//
|
|
if (mustCompileFiles && mustCompileFiles.length > 0) {
|
|
//
|
|
// Loop through items ...
|
|
for (const f of mustCompileFiles) {
|
|
//
|
|
// Log ...
|
|
console.log(
|
|
XColorTools.applyForegroundColor("try to compile: ", XColorTools.COLOR_NAMES.Yellow),
|
|
XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue)
|
|
);
|
|
|
|
//
|
|
const result = await compileMQLFile(f);
|
|
|
|
//
|
|
if (result.includes("0 errors")) {
|
|
//
|
|
const msg = "compiled successfully ...";
|
|
console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green));
|
|
} else {
|
|
//
|
|
const msg = "failed ...";
|
|
console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red));
|
|
throw msg;
|
|
}
|
|
}
|
|
|
|
//
|
|
return true;
|
|
}
|
|
|
|
//
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Pack Compiled Project ...
|
|
*
|
|
* @param {string} path Project Path ...
|
|
*/
|
|
async function handleProjectPack(path = "") {
|
|
//
|
|
const projectName = XFileTools.basename(path);
|
|
|
|
//
|
|
// check packs exists or not ...
|
|
const isPacksExists = XFileTools.isDirectoryExists(packsPath);
|
|
if (!isPacksExists) {
|
|
XFileTools.createDirectory(packsPath);
|
|
}
|
|
|
|
//
|
|
// Reading Compiled Files ...
|
|
const mustCopyFiles = await readEXTFiles(path);
|
|
if (!mustCopyFiles || mustCopyFiles.length == 0) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
const prjPackPath = XFileTools.joinPath(packsPath, projectName);
|
|
|
|
//
|
|
// Check Project Packs Folder ...
|
|
const isProjectPackExists = XFileTools.isDirectoryExists(prjPackPath);
|
|
if (isProjectPackExists) {
|
|
await XFileTools.removeDirectory(prjPackPath, true);
|
|
}
|
|
|
|
//
|
|
// Create Empty Project Folder on Pack ...
|
|
XFileTools.createDirectory(prjPackPath);
|
|
|
|
//
|
|
// Loop through Files ...
|
|
for (const f of mustCopyFiles) {
|
|
//
|
|
// Prepare Destination Path ...
|
|
const fBasePath = XFileTools.basename(f);
|
|
let fDestPath = f.replace(fBasePath, "")
|
|
.replace(projectsPath, packsPath);
|
|
fDestPath = fDestPath.substring(0, fDestPath.length - 1);
|
|
|
|
//
|
|
const isFDestPathExists = XFileTools.isDirectoryExists(fDestPath);
|
|
if (!isFDestPathExists) {
|
|
XFileTools.createDirectory(fDestPath);
|
|
}
|
|
|
|
//
|
|
// Log ...
|
|
console.log(
|
|
XColorTools.applyForegroundColor("try to copy: ", XColorTools.COLOR_NAMES.Yellow),
|
|
XColorTools.applyForegroundColor(f, XColorTools.COLOR_NAMES.Blue),
|
|
XColorTools.applyForegroundColor(" to : ", XColorTools.COLOR_NAMES.Yellow),
|
|
XColorTools.applyForegroundColor(fDestPath, XColorTools.COLOR_NAMES.Magenta)
|
|
);
|
|
|
|
//
|
|
let result = await XFileTools.copyFile(f, fDestPath);
|
|
if (result) {
|
|
//
|
|
const msg = "copy successfully ...";
|
|
console.log(
|
|
XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Green)
|
|
);
|
|
} else {
|
|
//
|
|
const msg = "copy failed ...";
|
|
console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red));
|
|
throw msg;
|
|
}
|
|
}
|
|
|
|
//
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Extract Project MQL files ...
|
|
*
|
|
* @param {string} path Folder Path ...
|
|
* @returns
|
|
*/
|
|
async function readMQLFiles(path = "") {
|
|
//
|
|
const result = await extractFiles(path, [".mq5", ".mq4"]);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Extract Project Compiled files ...
|
|
*
|
|
* @param {string} path Folder Path ...
|
|
* @returns
|
|
*/
|
|
async function readEXTFiles(path = "") {
|
|
//
|
|
const result = await extractFiles(path, [".ex5", ".ex4"]);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Compile Specific MQL File ...
|
|
*
|
|
* @param {string} path MQL file path ...
|
|
* @returns
|
|
*/
|
|
async function compileMQLFile(path = "") {
|
|
//
|
|
// Check File Exists ...
|
|
const isExists = XFileTools.isFileExists(path);
|
|
if (!isExists) {
|
|
//
|
|
const msg = "file not found ...";
|
|
console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red));
|
|
throw msg;
|
|
}
|
|
|
|
//
|
|
const ext = XFileTools.getFileExtension(path);
|
|
if (ext !== ".mq5" && ext !== "mq4") {
|
|
//
|
|
const msg = "invalid file extension ...";
|
|
console.log(XColorTools.applyForegroundColor(msg, XColorTools.COLOR_NAMES.Red));
|
|
throw msg;
|
|
}
|
|
|
|
//
|
|
const cwd = __dirname;
|
|
const cmd = "compile.cmd " + path;
|
|
|
|
//
|
|
const result = await XShellTools.execute(cmd, cwd);
|
|
return result;
|
|
}
|
|
|
|
|
|
/**
|
|
* Extract Specific files from a folder and it's content ...
|
|
*
|
|
* @param {string} path Folder Path ...
|
|
* @returns
|
|
*/
|
|
async function extractFiles(path = "", ext = []) {
|
|
//
|
|
const result = [];
|
|
|
|
//
|
|
if (!ext || ext.length == 0) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
const pathContent = await XFileTools.getDirectoryContents(path);
|
|
if (!pathContent || pathContent.length == 0) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop through Content ...
|
|
for (const c of pathContent) {
|
|
//
|
|
// Prepare full path ...
|
|
const cPath = XFileTools.joinPath(path, c);
|
|
|
|
//
|
|
// check content path is file or not ...
|
|
const isCFile = XFileTools.isFileExists(cPath);
|
|
const isCDirectory = XFileTools.isDirectoryExists(cPath);
|
|
if (isCFile) {
|
|
//
|
|
// Check it is MQL file or not ...
|
|
const cExt = XFileTools.getFileExtension(cPath);
|
|
if (ext.includes(cExt)) {
|
|
result.push(cPath);
|
|
}
|
|
} else if (isCDirectory) {
|
|
//
|
|
const destFolderName = XFileTools.basename(cPath);
|
|
const isExcluded = excludeWorkspaceFolders.includes(destFolderName);
|
|
if (isExcluded) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
const cFiles = await extractFiles(cPath, ext);
|
|
if (cFiles && cFiles.length > 0) {
|
|
result.push(...cFiles);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|