/* 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";
}
// ------