/* Gives good results on BUY, but no sales */ void main() { OUT_CLEANUP(); string strImagePath = "c:\\S_Projects\\CortexPro\\data\\my_forex\\images\\"; string strForexName = "EURUSD_H1"; //"EURUSD_H1"; string strNnPath = "c:\\S_Projects\\CortexPro\\data\\my_forex\\nn\\"; string strNnFileName; // ------------ string strDataFileName = "c:\\S_Projects\\CortexPro\\data\\my_forex\\quotes\\" + strForexName + ".TXT"; string strLagFileName = "c:\\S_Projects\\CortexPro\\data\\my_forex\\lags\\" + strForexName + "_evolution_04.lgg"; double bIsPathRelative = 0; array arrDate = CREATE_ARRAY(0); array arrTime = CREATE_ARRAY(0); array arrOpen = CREATE_ARRAY(0); array arrHigh = CREATE_ARRAY(0); array arrLow = CREATE_ARRAY(0); array arrClose = CREATE_ARRAY(0); TABLE_LOADER(strDataFileName, bIsPathRelative, 0, "", 0, "", 0, arrDate, 1, arrTime, 2, arrOpen, 3, arrHigh, 4, arrLow, 5, arrClose); double nCloseArraySize = ARRAY_SIZE(arrClose); double dSuccessRatio; double nCorrectStops = 0; double nIncorrectStops = 0; double dMaxDrawDown; // Interval, Range, Ma array_s arrNocParameters = CREATE_ARRAY_S(0); arrNocParameters[0] = "12,0.012,5"; double dMinStop = 0.0030; // 30 points double dMaxStop = 0.0250; // 250 points array arrRange; double nTradeNumberBuy = 0; double nTradeNumberSell = 0; double nTradeNumber = 0; // --- array arrNeurons = CREATE_ARRAY(0); arrNeurons[0] = 5; array arrNocLags = CREATE_ARRAY(0); array_s arrStrNocLags = CREATE_ARRAY_S(0); // arrStrNocLags[0] = "8,1,3,6,8,10,12,16,24"; arrStrNocLags[0] = "22,1,2,3,4,6,8,10,12,16,20,24,28,32,36,42,48,54,60,68,76,84,92"; array arrNoc; array arrNocSmooth; double nRemoveFirst = 100; // Arrays to keep NN output, created by ApplyNN, used in Test array arrNnAdvice = CREATE_ARRAY(0); array arrNnStopLoss = CREATE_ARRAY(0); array arrNnTakeProfit = CREATE_ARRAY(0); array arrProfits = CREATE_ARRAY(1); // Sorted array array arrLearnProfits = CREATE_ARRAY(0); array arrTestProfits = CREATE_ARRAY(0); array arrNetworks = CREATE_ARRAY(0); array arrProfitsTmp = CREATE_ARRAY(0); array arrCorrections = CREATE_ARRAY(0); array arrLearnProfitsTmp = CREATE_ARRAY(0); array arrTestProfitsTmp = CREATE_ARRAY(0); array arrNetworksTmp = CREATE_ARRAY(0); array arrUpdates = CREATE_ARRAY(0); // How many NNs from a new generation survived array arrUpdated = CREATE_ARRAY(0); // ------ array arrBalance = CREATE_ARRAY(0); array arrBalanceBuy = CREATE_ARRAY(0); array arrBalanceSell = CREATE_ARRAY(0); double nDrawChartEvery = 1; double nPopulationSize = 15; string strParam; string strToken; double nMa; double hNn; double nExtractRecords = 0.5 * nCloseArraySize; for(double nNocParIdx = 0; nNocParIdx < ARRAY_SIZE(arrNocParameters); nNocParIdx = nNocParIdx + 1) { strParam = arrNocParameters[nNocParIdx]; strToken = GET_TOKEN(strParam, ","); double nNocInterval = STR2NUM(strToken); strToken = GET_TOKEN(strParam, ","); double dNocRange = STR2NUM(strToken); arrNoc = CreateNoc(nNocInterval, dNocRange); // strToken = GET_TOKEN(strParam, ","); // nMa = STR2NUM(strToken); // arrNocSmooth = EXP_MVAVG(arrNoc, nMa); for(double nNocLagIdx = 0; nNocLagIdx < ARRAY_SIZE(arrStrNocLags); nNocLagIdx = nNocLagIdx + 1) { string strNocLagBuf = arrStrNocLags[nNocLagIdx]; CreateLagFile(strNocLagBuf, nRemoveFirst); for(double nNeuronsIdx = 0; nNeuronsIdx < ARRAY_SIZE(arrNeurons); nNeuronsIdx = nNeuronsIdx + 1) { double nNeurons = arrNeurons[nNeuronsIdx]; // -------------------- // Create initial population PRINT("%s\r\n", "Creating initial population"); strNnFileName = strNnPath + strForexName + "_evolution_0.nn"; NewNn(arrNocLags, nNeurons); arrNetworks[0] = OPEN_NN(strNnFileName, bIsPathRelative); for(double nNnIdx = 1; nNnIdx < nPopulationSize; nNnIdx = nNnIdx + 1) { arrNetworks[nNnIdx] = MUTATION_NN(arrNetworks[nNnIdx - 1], 2, 0.4); PAUSE(100); } PRINT("%s\r\n", "Creating wrapper for profit charts"); // 15 arrays, showing profit improvement array arrProfit_00 = CREATE_ARRAY(0); array arrProfit_01 = CREATE_ARRAY(0); array arrProfit_02 = CREATE_ARRAY(0); array arrProfit_03 = CREATE_ARRAY(0); array arrProfit_04 = CREATE_ARRAY(0); array arrProfit_05 = CREATE_ARRAY(0); array arrProfit_06 = CREATE_ARRAY(0); array arrProfit_07 = CREATE_ARRAY(0); array arrProfit_08 = CREATE_ARRAY(0); array arrProfit_09 = CREATE_ARRAY(0); array arrProfit_10 = CREATE_ARRAY(0); array arrProfit_11 = CREATE_ARRAY(0); array arrProfit_12 = CREATE_ARRAY(0); array arrProfit_13 = CREATE_ARRAY(0); array arrProfit_14 = CREATE_ARRAY(0); array arrTestProfit_00 = CREATE_ARRAY(0); array arrTestProfit_01 = CREATE_ARRAY(0); array arrTestProfit_02 = CREATE_ARRAY(0); array arrTestProfit_03 = CREATE_ARRAY(0); array arrTestProfit_04 = CREATE_ARRAY(0); array arrTestProfit_05 = CREATE_ARRAY(0); array arrTestProfit_06 = CREATE_ARRAY(0); array arrTestProfit_07 = CREATE_ARRAY(0); array arrTestProfit_08 = CREATE_ARRAY(0); array arrTestProfit_09 = CREATE_ARRAY(0); array arrTestProfit_10 = CREATE_ARRAY(0); array arrTestProfit_11 = CREATE_ARRAY(0); array arrTestProfit_12 = CREATE_ARRAY(0); array arrTestProfit_13 = CREATE_ARRAY(0); array arrTestProfit_14 = CREATE_ARRAY(0); double nLearn = 3000; double nStep = 128; for(double nGeneration = 1; nGeneration < 100000; nGeneration = nGeneration + 1) { string strXML = "\r\n\r\n"; string strHistoryXML = ""; OUT_CLEANUP(); PRINT("====== Generation %.0f ======\r\n", nGeneration); // Add one child for each network, with slightly different weights PRINT("%s\r\n", "Creating children"); for(nNnIdx = nPopulationSize; nNnIdx < 2 * nPopulationSize; nNnIdx = nNnIdx + 1) { // NN_MUTATION to Cortex. Applies Gauss-distributed noice to weights arrNetworks[nNnIdx] = MUTATION_NN(arrNetworks[nNnIdx - nPopulationSize], 2, RAND(0.1)); PAUSE(100); arrUpdates[nNnIdx - nPopulationSize] = arrNetworks[nNnIdx]; } // Find best networks in both generations for(nNnIdx = 0; nNnIdx < 2 * nPopulationSize; nNnIdx = nNnIdx + 1) { PRINT("Testing NN %.0f; ", nNnIdx); APPLY_NN(arrNetworks[nNnIdx], nCloseArraySize, 1.0, 1, arrNoc, arrNocLags, 3, arrNnAdvice, arrNnStopLoss, arrNnTakeProfit); double dAdviceMax = ARRAY_MAX(arrNnAdvice, -1, -1); double dAdviceMin = ARRAY_MIN(arrNnAdvice, -1, -1); double nStart = nRemoveFirst + RAND(nExtractRecords - nLearn - nRemoveFirst); dMaxDrawDown = Test(dAdviceMax, dAdviceMin, nStart, nStart + nLearn); double dBalance = arrBalance[ARRAY_SIZE(arrBalance) - 1] - 1000; // double dCorrection = 10000000; if(nTradeNumberBuy != 0 && nTradeNumberSell != 0 && arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1] != 0 && arrBalanceBuy[ARRAY_SIZE(arrBalanceSell) - 1] != 0) { dCorrection = dCorrection * (dAdviceMax - dAdviceMin); if(ABS(arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy) - 1]) / ABS(arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1]) > 3 || ABS(arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1]) / ABS(arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy) - 1]) > 3) { dCorrection = dCorrection * 0.1; } if(arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy) - 1] < 0 || arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1] < 0) { dCorrection = dCorrection * 0.1; } if(dMaxDrawDown > 0.5) { dCorrection = dCorrection * 0.1; } else { if(dMaxDrawDown >= 0.3) { dCorrection = dCorrection * (2.35 - 4.5 * dMaxDrawDown); } } if(nCorrectStops != 0) { dCorrection = dCorrection * nCorrectStops / (nCorrectStops + nIncorrectStops); } else { dCorrection = dCorrection / (nCorrectStops + nIncorrectStops); } if(nTradeNumberSell < 10) { dCorrection = dCorrection * (nTradeNumberSell * 0.1 + 0.000001); } if(nTradeNumberBuy < 10) { dCorrection = dCorrection * (nTradeNumberBuy * 0.1 + 0.000001); } if(nTradeNumber < 30) { dCorrection = dCorrection * (nTradeNumber * 0.033 + 0.000001); } dCorrection = ABS(dCorrection * dSuccessRatio); } else { dCorrection = 0.00000001; } PRINT("dCorrection = %.8f\r\n", dCorrection); // ARRAY_ADD(arrCorrections, dCorrection); ARRAY_ADD(arrProfitsTmp, dBalance); ARRAY_ADD(arrNetworksTmp, arrNetworks[nNnIdx]); dMaxDrawDown = Test(dAdviceMax, dAdviceMin, nRemoveFirst, nExtractRecords); ARRAY_ADD(arrLearnProfitsTmp, arrBalance[ARRAY_SIZE(arrBalance) - 1]); if(nGeneration % nDrawChartEvery == 0) { Chart(strForexName, nNnIdx); } PRINT("\t\tBalance: %.4f; ", arrBalance[ARRAY_SIZE(arrBalance) - 1], "(%.4f, ", arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy) - 1], "%.4f), ", arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1], "trades: %.0f\r\n", ARRAY_SIZE(arrBalance)); Test(dAdviceMax, dAdviceMin, nExtractRecords, nCloseArraySize); ARRAY_ADD(arrTestProfitsTmp, arrBalance[ARRAY_SIZE(arrBalance) - 1]); if(nGeneration % nDrawChartEvery == 0) { ChartTest(strForexName, nNnIdx); } } // for(nIdx = 0; nNnIdx < 2 * nPopulationSize double dMinProfit = ARRAY_MIN(arrProfitsTmp, -1, -1); arrProfitsTmp = arrProfitsTmp - dMinProfit; // 0-based, no negatives double nPos; for(nNnIdx = 0; nNnIdx < 2 * nPopulationSize; nNnIdx = nNnIdx + 1) { nPos = ARRAY_ADD(arrProfits, arrProfitsTmp[nNnIdx] * arrCorrections[nNnIdx]); ARRAY_INSERT(arrNetworks, arrNetworksTmp[nNnIdx], nPos); ARRAY_INSERT(arrLearnProfits, arrLearnProfitsTmp[nNnIdx], nPos); ARRAY_INSERT(arrTestProfits, arrTestProfitsTmp[nNnIdx], nPos); } PRINT("%s\r\n", "Removing NNs with poor performance"); double nUpdated = 0; for(nNnIdx = nPopulationSize - 1; nNnIdx >= 0; nNnIdx = nNnIdx - 1) { CLOSE_NN(arrNetworks[nNnIdx]); ARRAY_REMOVE(arrNetworks, nNnIdx); if(ARRAY_FIND(arrUpdates, arrNetworks[nNnIdx]) == -1) { nUpdated = nUpdated + 1; } } arrUpdated[ARRAY_SIZE(arrUpdated)] = nUpdated; // Close NNs, that have poor performance // More fitness - more chances to be selected // Indixes to be removed arrProfit_00[ARRAY_SIZE(arrProfit_00)] = arrLearnProfits[29]; arrProfit_01[ARRAY_SIZE(arrProfit_01)] = arrLearnProfits[28]; arrProfit_02[ARRAY_SIZE(arrProfit_02)] = arrLearnProfits[27]; arrProfit_03[ARRAY_SIZE(arrProfit_03)] = arrLearnProfits[26]; arrProfit_04[ARRAY_SIZE(arrProfit_04)] = arrLearnProfits[25]; arrProfit_05[ARRAY_SIZE(arrProfit_05)] = arrLearnProfits[24]; arrProfit_06[ARRAY_SIZE(arrProfit_06)] = arrLearnProfits[23]; arrProfit_07[ARRAY_SIZE(arrProfit_07)] = arrLearnProfits[22]; arrProfit_08[ARRAY_SIZE(arrProfit_08)] = arrLearnProfits[21]; arrProfit_09[ARRAY_SIZE(arrProfit_09)] = arrLearnProfits[20]; arrProfit_10[ARRAY_SIZE(arrProfit_10)] = arrLearnProfits[19]; arrProfit_11[ARRAY_SIZE(arrProfit_11)] = arrLearnProfits[18]; arrProfit_12[ARRAY_SIZE(arrProfit_12)] = arrLearnProfits[17]; arrProfit_13[ARRAY_SIZE(arrProfit_13)] = arrLearnProfits[16]; arrProfit_14[ARRAY_SIZE(arrProfit_14)] = arrLearnProfits[15]; arrTestProfit_00[ARRAY_SIZE(arrTestProfit_00)] = arrTestProfits[29]; arrTestProfit_01[ARRAY_SIZE(arrTestProfit_01)] = arrTestProfits[28]; arrTestProfit_02[ARRAY_SIZE(arrTestProfit_02)] = arrTestProfits[27]; arrTestProfit_03[ARRAY_SIZE(arrTestProfit_03)] = arrTestProfits[26]; arrTestProfit_04[ARRAY_SIZE(arrTestProfit_04)] = arrTestProfits[25]; arrTestProfit_05[ARRAY_SIZE(arrTestProfit_05)] = arrTestProfits[24]; arrTestProfit_06[ARRAY_SIZE(arrTestProfit_06)] = arrTestProfits[23]; arrTestProfit_07[ARRAY_SIZE(arrTestProfit_07)] = arrTestProfits[22]; arrTestProfit_08[ARRAY_SIZE(arrTestProfit_08)] = arrTestProfits[21]; arrTestProfit_09[ARRAY_SIZE(arrTestProfit_09)] = arrTestProfits[20]; arrTestProfit_10[ARRAY_SIZE(arrTestProfit_10)] = arrTestProfits[19]; arrTestProfit_11[ARRAY_SIZE(arrTestProfit_11)] = arrTestProfits[18]; arrTestProfit_12[ARRAY_SIZE(arrTestProfit_12)] = arrTestProfits[17]; arrTestProfit_13[ARRAY_SIZE(arrTestProfit_13)] = arrTestProfits[16]; arrTestProfit_14[ARRAY_SIZE(arrTestProfit_14)] = arrTestProfits[15]; PRINT("\r\n------------------%s\r\n", ""); ARRAY_REMOVE(arrProfits, -1); ARRAY_REMOVE(arrProfitsTmp, -1); ARRAY_REMOVE(arrLearnProfits, -1); ARRAY_REMOVE(arrTestProfits, -1); ARRAY_REMOVE(arrLearnProfitsTmp, -1); ARRAY_REMOVE(arrTestProfitsTmp, -1); ARRAY_REMOVE(arrNetworksTmp, -1); if(nGeneration % nDrawChartEvery == 0) { PRINT("%s\r\n", "Saving NNs with good performance"); for(nNnIdx = 0; nNnIdx < nPopulationSize; nNnIdx = nNnIdx + 1) { strNnFileName = strNnPath + strForexName + "_evolution_" + NUM2STR(nNnIdx, "%.0f") + ".nn"; // To do: create Cortex SAVE_NN function // SAVE_NN(arrNetworks[nNnIdx], strNnFileName); } WrapChart(strForexName); WrapTestChart(strForexName); STR_REPLACE(strXML, "", strHistoryXML); strXML = strXML + "\r\n"; F_UNLINK(strImagePath + "chart_forex_nn.xml"); SAVE_XML(strImagePath, "chart_forex_nn", "chart_forex_nn", "root", strXML); } } // nGeneration } // for(double nNeuronsIdx = 0; nNeuronsIdx < ARRAY_SIZE(arrNeurons); } // for(double nNocLagIdx = 0; nNocLagIdx < ARRAY_SIZE(arrStrNocLags); } // for(double nNocParIdx = 0; nNocParIdx < ARRAY_SIZE(arrNocParameters); PRINT("%s\r\nDone\r\n", ""); } // --------------- double Test(double dAdviceMax, double dAdviceMin, double nFirstRecordNum, double nLastRecordNum) { dSuccessRatio = 0.001; nCorrectStops = 0; nIncorrectStops = 0; double nWinTrades = 0; double nLooseTrades = 0; ARRAY_REMOVE(arrBalance, -1); arrBalance[0] = 1000; ARRAY_REMOVE(arrBalanceBuy, -1); arrBalanceBuy[0] = 0; ARRAY_REMOVE(arrBalanceSell, -1); arrBalanceSell[0] = 0; array arrBars = CREATE_ARRAY(0); arrBars[0] = nFirstRecordNum; double dLotSize = 100; // 0.1 lot double nTradeType = 0; // 1 buy, -1 sell, 0 - none double nCurrentTradeType = 0; // 1 buy, -1 sell, 0 - none double dSpread = 0.0005; double bStop; dMaxDrawDown = 0; double dCurrentMax = 1000; // Used to calculate drawdown nTradeNumber = 0; nTradeNumberBuy = 0; nTradeNumberSell = 0; double dOpenPrice; double dStop; double dTp = 0; double dStopLoss; double dTakeProfit; double dClosedAt; double dAdviceInterval = dAdviceMax - dAdviceMin; double BUY = -2; double CLOSE_SELL = -1; double CLOSE_BUY = 1; double SELL = 2; for(double nBar = nFirstRecordNum + 1; nBar < nLastRecordNum; nBar = nBar + 1) { if(arrNnStopLoss[nBar - 1] < dMinStop || arrNnStopLoss[nBar - 1] > dMaxStop) { nIncorrectStops = nIncorrectStops + 1; if(arrNnStopLoss[nBar - 1] < dMinStop) { dStopLoss = dMinStop; } else { dStopLoss = dMaxStop; } } else { nCorrectStops = nCorrectStops + 1; dStopLoss = arrNnStopLoss[nBar - 1]; } if(arrNnTakeProfit[nBar - 1] < dMinStop || arrNnTakeProfit[nBar - 1] > dMaxStop) { nIncorrectStops = nIncorrectStops + 1; if(arrNnTakeProfit[nBar - 1] < dMinStop) { dTakeProfit = dMinStop; } else { dTakeProfit = dMaxStop; } } else { nCorrectStops = nCorrectStops + 1; dTakeProfit = arrNnTakeProfit[nBar - 1]; } nTradeType = 0; if(arrNnAdvice[nBar - 1] < dAdviceMin + dAdviceInterval / 4) { nTradeType = BUY; } else { if(arrNnAdvice[nBar - 1] < dAdviceMin + dAdviceInterval / 2) { nTradeType = CLOSE_SELL; } else { if(arrNnAdvice[nBar - 1] < dAdviceMin + 3 * dAdviceInterval / 4) { nTradeType = CLOSE_BUY; } else { nTradeType = SELL; } } } // -1 or 1 if(nCurrentTradeType != 0) { bStop = 0; double dProfit; // If BUY and stop loss or take profit reached, or SELL signal received if(nCurrentTradeType == -1 && (arrLow[nBar - 1] <= dStop || (dTakeProfit > 0 && arrHigh[nBar - 1] >= dTp - dSpread) || nTradeType >= CLOSE_BUY)) { dProfit = 100 * (arrOpen[nBar] - dOpenPrice) * dLotSize; arrBalance[ARRAY_SIZE(arrBalance)] = arrBalance[ARRAY_SIZE(arrBalance) - 1] + dProfit; arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy)] = arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy) - 1] + dProfit; arrBalanceSell[ARRAY_SIZE(arrBalanceSell)] = arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1]; bStop = 1; dClosedAt = arrOpen[nBar]; } else { if(nCurrentTradeType == 1 && (arrHigh[nBar - 1] >= dStop - dSpread || (dTakeProfit > 0 && arrLow[nBar - 1] <= dTp) || nTradeType <= CLOSE_SELL)) { dProfit = 100 * (dOpenPrice - arrOpen[nBar] - dSpread) * dLotSize; arrBalance[ARRAY_SIZE(arrBalance)] = arrBalance[ARRAY_SIZE(arrBalance) - 1] + dProfit; arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy)] = arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy) - 1]; arrBalanceSell[ARRAY_SIZE(arrBalanceSell)] = arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1] + dProfit; bStop = 1; dClosedAt = arrOpen[nBar]; } } if(bStop == 1) { nCurrentTradeType = 0; arrBars[ARRAY_SIZE(arrBars)] = nBar; if(dProfit > 0) { nWinTrades = nWinTrades + 1; } else { nLooseTrades = nLooseTrades + 1; } } } double dDrawDown = (dCurrentMax - arrBalance[ARRAY_SIZE(arrBalance) - 1]) / 1000; //dCurrentMax; dMaxDrawDown = MAX(dMaxDrawDown, dDrawDown); dCurrentMax = MAX(dCurrentMax, arrBalance[ARRAY_SIZE(arrBalance) - 1]); // BUY signal // && dStopLoss >= dMinStop) if(nCurrentTradeType != -1 && nTradeType == BUY) { dOpenPrice = arrOpen[nBar]; dStop = dOpenPrice - dStopLoss; dTp = dOpenPrice + dTakeProfit; nCurrentTradeType = -1; nTradeNumber = nTradeNumber + 1; nTradeNumberBuy = nTradeNumberBuy + 1; } else { // && dStopLoss >= dMinStop) if(nCurrentTradeType != 1 && nTradeType == SELL) { dOpenPrice = arrOpen[nBar]; dStop = dOpenPrice + dStopLoss; dTp = dOpenPrice - dTakeProfit; nCurrentTradeType = 1; nTradeNumber = nTradeNumber + 1; nTradeNumberSell = nTradeNumberSell + 1; } } } // If at the end we have open positions, close them bStop = 0; if(nCurrentTradeType == 1) { dProfit = 100 * (dOpenPrice - arrOpen[nBar - 1] - dSpread) * dLotSize; arrBalance[ARRAY_SIZE(arrBalance)] = arrBalance[ARRAY_SIZE(arrBalance) - 1] + dProfit; arrBalanceSell[ARRAY_SIZE(arrBalanceSell)] = arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1] + dProfit; arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy)] = arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy) - 1]; arrBars[ARRAY_SIZE(arrBars)] = nBar - 1; bStop = 1; } else { if(nCurrentTradeType == -1) { dProfit = 100 * (arrOpen[nBar - 1] - dOpenPrice) * dLotSize; arrBalance[ARRAY_SIZE(arrBalance)] = arrBalance[ARRAY_SIZE(arrBalance) - 1] + dProfit; arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy)] = arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy) - 1] + dProfit; arrBalanceSell[ARRAY_SIZE(arrBalanceSell)] = arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1]; arrBars[ARRAY_SIZE(arrBars)] = nBar - 1; bStop = 1; } } if(bStop == 1) { if(dProfit > 0) { nWinTrades = nWinTrades + 1; } else { nLooseTrades = nLooseTrades + 1; } } if(nWinTrades + nLooseTrades > 0) { dSuccessRatio = nWinTrades / (nWinTrades + nLooseTrades); } return dMaxDrawDown; } // --------------- array CreateNoc(double nNocInterval, double dMinRange) { PRINT("%s\r\n", "Creating NOC indicator"); array arrNormOnCondition = CREATE_ARRAY(0); array arrPeriodLow = CREATE_ARRAY(0); array arrPeriodHigh = CREATE_ARRAY(0); array arrPeriodLow = MV_MIN(arrLow, nNocInterval); array arrPeriodHigh = MV_MAX(arrHigh, nNocInterval); for(double i = 0; i < nNocInterval; i = i + 1) { arrNormOnCondition[i] = 0; } double dClose; double dLow; double dHigh; for(i = nNocInterval; i < nCloseArraySize; i = i + 1) { dClose = arrClose[i]; dLow = arrPeriodLow[i]; dHigh = arrPeriodHigh[i]; if(dHigh - dLow > dMinRange) { // / 2 + 1 to confine to 0...1 instead of -1...1 arrNormOnCondition[i] = (((dClose - dLow) - (dHigh - dClose)) / (dHigh - dLow)) / 2 + 0.5; } else { arrNormOnCondition[i] = (((dClose - dLow) - (dHigh - dClose)) / dMinRange) / 2 + 0.5; } } return arrNormOnCondition; } // ---------------- void CreateLagFile(string strNocLags, double nRemoveFirst) { PRINT("%s\r\n", "Creating Lag file"); double hFile = F_OPEN(strLagFileName, "wb"); F_PRINT(hFile, "%s", "No"); // --- ARRAY_REMOVE(arrNocLags, -1); strToken = GET_TOKEN(strNocLags, ","); double nNumOfLags = STR2NUM(strToken); for(double i = 0; i < nNumOfLags; i = i + 1) { strToken = GET_TOKEN(strNocLags, ","); arrNocLags[i] = STR2NUM(strToken); F_PRINT(hFile, ",Noc-%.0f", arrNocLags[i]); } // --- F_PRINT(hFile, "%s\r\n", ""); // --- double nNum; for(i = nRemoveFirst; i < nCloseArraySize; i = i + 1) { nNum = i - nRemoveFirst + 1; F_PRINT(hFile, "%.0f", nNum); for(double nLagIdx = 0; nLagIdx < nNumOfLags; nLagIdx = nLagIdx + 1) { F_PRINT(hFile, ",%f", arrNoc[i - arrNocLags[nLagIdx]]); } F_PRINT(hFile, "%s\r\n", ""); } F_CLOSE(hFile); } // -------------- void NewNn(array arrNocLags, double nNeuronsLayer2) { double dStopError = 0; double nStopEpoch = 0; double nSkipBefore = 0; double nSkipAfter = 0; string strStartLine = ""; string strEndLine = ""; double bReverseArrays = 0; // Inputs array arrInputColumns = CREATE_ARRAY(0); array_s arrInputColumnNames = CREATE_ARRAY_S(0); // 0 - Number, our input begins at column No 1 for(double nInputCol = 0; nInputCol < ARRAY_SIZE(arrNocLags); nInputCol = nInputCol + 1) { arrInputColumns[nInputCol] = nInputCol + 1; arrInputColumnNames[nInputCol] = "Noc-" + NUM2STR(arrNocLags[nInputCol], "%.0f"); } array arrOutputColumns = CREATE_ARRAY(0); // Not used anywhere, however, should be 3 outputs, to match what we // pass to CREATE_NN arrOutputColumns[0] = 1; arrOutputColumns[1] = 2; arrOutputColumns[2] = 3; array_s arrOutputColumnNames = CREATE_ARRAY_S(0); arrOutputColumnNames[0] = "Advice"; arrOutputColumnNames[1] = "StopLoss"; arrOutputColumnNames[2] = "TakeProfit"; double nNeuronsLayer1 = ARRAY_SIZE(arrNocLags); // Passed as function parameter // double nNeuronsLayer2 = nNeuronsLayer1 / 2; double nNeuronsLayer3 = 5; double nNeuronsLayer4 = 3; double nLayers = 4; double nActivation = 0; double nAdjustRange = 1.0; array arrOutTabInputColumns = CREATE_ARRAY(0); arrOutTabInputColumns[0] = 0; // Number array_s arrOutTabInputColumnNames = CREATE_ARRAY_S(0); arrOutTabInputColumnNames[0] = "Advice"; arrOutTabInputColumnNames[1] = "StopLoss"; arrOutTabInputColumnNames[2] = "TakeProfit"; array arrOutTabOutputColumns = CREATE_ARRAY(0); // Desired output and NN output will be added to the // same list, right after inputs arrOutTabOutputColumns[0] = ARRAY_SIZE(arrNocLags) + 1; arrOutTabOutputColumns[1] = ARRAY_SIZE(arrNocLags) + 2; arrOutTabOutputColumns[2] = ARRAY_SIZE(arrNocLags) + 3; array_s arrOutTabOutputColumnNames = CREATE_ARRAY_S(0); arrOutTabOutputColumnNames[0] = "NN:Advice"; arrOutTabOutputColumnNames[1] = "NN:StopLoss"; arrOutTabOutputColumnNames[2] = "NN:TakeProfit"; CREATE_NN(strNnFileName, bIsPathRelative, strLagFileName, bIsPathRelative, nSkipBefore, nSkipAfter, strStartLine, strEndLine, bReverseArrays, arrInputColumns, arrInputColumnNames, arrOutputColumns, arrOutputColumnNames, nExtractRecords, dStopError, nStopEpoch, nNeuronsLayer1, nNeuronsLayer2, nNeuronsLayer3, nNeuronsLayer4, nLayers, nActivation, nAdjustRange, arrOutTabInputColumns, arrOutTabInputColumnNames, arrOutTabOutputColumns, arrOutTabOutputColumnNames); } // ---------------- void WrapChart(string strForexName) { string strImageFileName = strImagePath + "evolution_" + strForexName + ".png"; strHistoryXML = ""; array arrX = CREATE_ARRAY(0); for(double i = 0; i < ARRAY_SIZE(arrProfit_00); i = i + 1) { arrX[i] = i; } strHistoryXML = strHistoryXML + "\t\r\n\t\t" + SAVE_CHART(400, 300, 0, strImageFileName, arrX, arrProfit_00, arrProfit_01, arrProfit_02, arrProfit_03, arrProfit_04, arrProfit_05, arrProfit_06, arrProfit_07, arrProfit_08, arrProfit_09, arrProfit_10, arrProfit_11, arrProfit_12, arrProfit_13, arrProfit_14); strHistoryXML = strHistoryXML + "\t\r\n"; } // ------ void WrapTestChart(string strForexName) { string strImageFileName = strImagePath + "evolution_test_" + strForexName + ".png"; array arrX = CREATE_ARRAY(0); for(double i = 0; i < ARRAY_SIZE(arrTestProfit_00); i = i + 1) { arrX[i] = i; } strHistoryXML = strHistoryXML + "\t\r\n\t\t" + SAVE_CHART(400, 300, 0, strImageFileName, arrX, arrTestProfit_00, arrTestProfit_01, arrTestProfit_02, arrTestProfit_03, arrTestProfit_04, arrTestProfit_05, arrTestProfit_06, arrTestProfit_07, arrTestProfit_08, arrTestProfit_09, arrTestProfit_10, arrTestProfit_11, arrTestProfit_12, arrTestProfit_13, arrTestProfit_14); strHistoryXML = strHistoryXML + "\t\r\n"; // --- strImageFileName = strImagePath + "evolution_updated_" + strForexName + ".png"; strHistoryXML = strHistoryXML + "\t\r\n\t\t" + SAVE_CHART(400, 300, 0, strImageFileName, arrX, arrUpdated); strHistoryXML = strHistoryXML + "\t\r\n"; } // ------ void Chart(string strForexName, double nNnIdx) { string strImageFileName = strImagePath + "evolution_" + strForexName + NUM2STR(nNnIdx, "_%.0f") + ".png"; strXML = strXML + "\t\r\n\t\t\r\n"; strXML = strXML + "Trades: " + NUM2STR(nTradeNumber, "%.0f") + "(Buy: " + NUM2STR(nTradeNumberBuy, "%.0f") + ", Sell :" + NUM2STR(nTradeNumberSell, "%.0f)\r\n") + "NocInterval: " + NUM2STR(nNocInterval, "%.0f") + ", Range: " + NUM2STR(dNocRange, "%.3f") + ", Ma: " + NUM2STR(nMa, "%.0f\r\n") + ", Neurons: " + NUM2STR(nNeurons, "%.0f\r\n") + "Drawdown: " + NUM2STR(dMaxDrawDown, "%.3f\r\n") + "Profit: " + NUM2STR(arrBalance[ARRAY_SIZE(arrBalance) - 1] - 1000, "%f") + " (long: " + NUM2STR(arrBalanceBuy[ARRAY_SIZE(arrBalanceBuy) - 1], "%f") + ", short: " + NUM2STR(arrBalanceSell[ARRAY_SIZE(arrBalanceSell) - 1], "%f)\r\n"); strXML = strXML + "\t\t\r\n"; strXML = strXML + "\t\t" + SAVE_CHART(400, 300, 0, strImageFileName, arrBars, arrBalance, arrBalanceBuy, arrBalanceSell); strXML = strXML + "\t\r\n"; } // ------ void ChartTest(string strForexName, double nNnIdx) { string strImageFileName = strImagePath + "evolution_test_" + strForexName + NUM2STR(nNnIdx, "_%.0f") + ".png"; strXML = strXML + "\t\r\n"; strXML = strXML + "\t\t" + SAVE_CHART(400, 300, 0, strImageFileName, arrBars, arrBalance, arrBalanceBuy, arrBalanceSell); strXML = strXML + "\t\r\n"; } // ------