/*
* Encog(tm) Core v3.4 - Java Version
* http://www.heatonresearch.com/encog/
* https://github.com/encog/encog-java-core
* Copyright 2008-2016 Heaton Research, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* For more information on Heaton Research copyrights, licenses
* and trademarks visit:
* http://www.heatonresearch.com/copyright
*/
package org.encog.app.generate.generators.mql4;
import java.io.File;
import org.encog.app.analyst.EncogAnalyst;
import org.encog.app.analyst.script.DataField;
import org.encog.app.analyst.script.normalize.AnalystField;
import org.encog.app.analyst.script.prop.ScriptProperties;
import org.encog.app.generate.AnalystCodeGenerationError;
import org.encog.app.generate.generators.AbstractTemplateGenerator;
import org.encog.ml.MLMethod;
import org.encog.neural.flat.FlatNetwork;
import org.encog.neural.networks.BasicNetwork;
import org.encog.persist.EncogDirectoryPersistence;
import org.encog.util.EngineArray;
public class GenerateMQL4 extends AbstractTemplateGenerator {
@Override
public String getNullArray() {
return "{-1}";
}
@Override
public String getTemplatePath() {
return "org/encog/data/mt4.mql4";
}
private void processCalc() {
AnalystField firstOutputField = null;
final int barsNeeded = Math.abs(getAnalyst().determineMinTimeSlice());
final int inputCount = getAnalyst().determineInputCount();
final int outputCount = getAnalyst().determineOutputCount();
setIndentLevel(2);
addLine("if( _inputCount>0 && Bars>=" + barsNeeded + " )");
addLine("{");
indentIn();
addLine("double input[" + inputCount + "];");
addLine("double output[" + outputCount + "];");
int idx = 0;
for (final AnalystField field : getAnalyst().getScript().getNormalize()
.getNormalizedFields()) {
if (field.isInput()) {
final DataField df = getAnalyst().getScript().findDataField(
field.getName());
String str;
switch (field.getAction()) {
case PassThrough:
str = EngineArray.replace(df.getSource(), "##", "pos+"
+ (-field.getTimeSlice()));
addLine("input[" + idx + "]=" + str + ";");
idx++;
break;
case Normalize:
str = EngineArray.replace(df.getSource(), "##", "pos+"
+ (-field.getTimeSlice()));
addLine("input[" + idx + "]=Norm(" + str + ","
+ field.getNormalizedHigh() + ","
+ field.getNormalizedLow() + ","
+ field.getActualHigh() + ","
+ field.getActualLow() + ");");
idx++;
break;
case Ignore:
break;
default:
throw new AnalystCodeGenerationError(
"Can't generate Ninjascript code, unsupported normalizatoin action: "
+ field.getAction().toString());
}
}
if (field.isOutput()) {
if (firstOutputField == null) {
firstOutputField = field;
}
}
}
if (firstOutputField == null) {
throw new AnalystCodeGenerationError(
"Could not find an output field.");
}
addLine("Compute(input,output);");
addLine("ExtMapBuffer1[pos] = DeNorm(output[0]" + ","
+ firstOutputField.getNormalizedHigh() + ","
+ firstOutputField.getNormalizedLow() + ","
+ firstOutputField.getActualHigh() + ","
+ firstOutputField.getActualLow() + ");");
indentOut();
addLine("}");
setIndentLevel(2);
}
private void processHeaders() {
final DataField[] fields = getAnalyst().getScript().getFields();
final StringBuilder line = new StringBuilder();
line.append("FileWrite(iHandle");
for (final DataField df : fields) {
line.append(",");
line.append("\"");
line.append(df.getName());
line.append("\"");
}
line.append(");");
addLine(line.toString());
}
private void processMainBlock() {
final EncogAnalyst analyst = getAnalyst();
final String processID = analyst.getScript().getProperties()
.getPropertyString(ScriptProperties.PROCESS_CONFIG_SOURCE_FILE);
final String methodID = analyst
.getScript()
.getProperties()
.getPropertyString(
ScriptProperties.ML_CONFIG_MACHINE_LEARNING_FILE);
final File methodFile = analyst.getScript().resolveFilename(methodID);
final File processFile = analyst.getScript().resolveFilename(processID);
MLMethod method = null;
int[] contextTargetOffset = null;
int[] contextTargetSize = null;
boolean hasContext = false;
int inputCount = 0;
int[] layerContextCount = null;
int[] layerCounts = null;
int[] layerFeedCounts = null;
int[] layerIndex = null;
double[] layerOutput = null;
double[] layerSums = null;
int outputCount = 0;
int[] weightIndex = null;
double[] weights = null;
int neuronCount = 0;
int layerCount = 0;
int[] activation = null;
double[] p = null;
if (methodFile.exists()) {
method = (MLMethod) EncogDirectoryPersistence
.loadObject(methodFile);
final FlatNetwork flat = ((BasicNetwork) method).getFlat();
contextTargetOffset = flat.getContextTargetOffset();
contextTargetSize = flat.getContextTargetSize();
hasContext = flat.getHasContext();
inputCount = flat.getInputCount();
layerContextCount = flat.getLayerContextCount();
layerCounts = flat.getLayerCounts();
layerFeedCounts = flat.getLayerFeedCounts();
layerIndex = flat.getLayerIndex();
layerOutput = flat.getLayerOutput();
layerSums = flat.getLayerSums();
outputCount = flat.getOutputCount();
weightIndex = flat.getWeightIndex();
weights = flat.getWeights();
activation = createActivations(flat);
p = createParams(flat);
neuronCount = flat.getLayerOutput().length;
layerCount = flat.getLayerCounts().length;
}
setIndentLevel(2);
indentIn();
addNameValue("string EXPORT_FILENAME", "\"" + processFile.getName()
+ "\"");
addNameValue("int _neuronCount", neuronCount);
addNameValue("int _layerCount", layerCount);
addNameValue("int _contextTargetOffset[]", contextTargetOffset);
addNameValue("int _contextTargetSize[]", contextTargetSize);
addNameValue("bool _hasContext", hasContext ? "true" : "false");
addNameValue("int _inputCount", inputCount);
addNameValue("int _layerContextCount[]", layerContextCount);
addNameValue("int _layerCounts[]", layerCounts);
addNameValue("int _layerFeedCounts[]", layerFeedCounts);
addNameValue("int _layerIndex[]", layerIndex);
addNameValue("double _layerOutput[]", layerOutput);
addNameValue("double _layerSums[]", layerSums);
addNameValue("int _outputCount", outputCount);
addNameValue("int _weightIndex[]", weightIndex);
addNameValue("double _weights[]", weights);
addNameValue("int _activation[]", activation);
addNameValue("double _p[]", p);
indentOut();
setIndentLevel(0);
}
private void processObtain() {
setIndentLevel(3);
addLine("FileWrite(iHandle, when,");
final DataField[] fields = getAnalyst().getScript().getFields();
String lastLine = null;
for (final DataField field : fields) {
final DataField df = field;
if (!df.getName().equalsIgnoreCase("time")
&& !df.getName().equalsIgnoreCase("prediction")) {
final String str = EngineArray.replace(df.getSource(), "##",
"pos");
if (lastLine != null) {
addLine(lastLine + ",");
}
lastLine = str;
}
}
if (lastLine != null) {
addLine(lastLine);
}
addLine(");");
setIndentLevel(0);
}
@Override
public void processToken(final String command) {
if (command.equalsIgnoreCase("MAIN-BLOCK")) {
processMainBlock();
} else if (command.equals("CALC")) {
processCalc();
} else if (command.equals("OBTAIN")) {
processObtain();
} else if (command.equals("HEADERS")) {
processHeaders();
}
setIndentLevel(0);
}
}