-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Roffild
committed
Mar 18, 2019
1 parent
2d5e816
commit 1c30921
Showing
23 changed files
with
1,454 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* 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. | ||
* | ||
* https://github.com/Roffild/RoffildLibrary | ||
*/ | ||
#property copyright "Roffild" | ||
#property link "https://github.com/Roffild/RoffildLibrary" | ||
|
||
extern string PythonHome = ""; | ||
|
||
#include <Roffild/PythonDLL.mqh> | ||
#include <Roffild/ToIndicator.mqh> | ||
|
||
#resource "PythonDLL_Example.py" as string _PyCode_ | ||
CPythonDLL python; | ||
|
||
CToIndicator indicMedian; | ||
|
||
int OnInit() | ||
{ | ||
if (PythonHome == "") { | ||
Print("ERROR: PythonHome == \"\""); | ||
return INIT_FAILED; | ||
} | ||
if (python.initialize(PythonHome) == false) { | ||
Print("ERROR: Py_NewInterpreter() is not created."); | ||
return INIT_FAILED; | ||
} | ||
const string errinit = python.getErrorText(); | ||
if (errinit != "") { | ||
Print(errinit); | ||
return INIT_FAILED; | ||
} | ||
if (python.eval(_PyCode_, true) == false) { | ||
const string errmycode = python.getErrorText(); | ||
if (errmycode != "") { | ||
Print(errmycode); | ||
return INIT_FAILED; | ||
} | ||
} | ||
uchar array[]; | ||
StringToCharArray("Version_info: ", array); | ||
Print(python.getString(1, "Version: ", array)); | ||
Print(python.getString(2, "", array)); | ||
Print(python.getString(3, "", array)); | ||
Print("Error in Python:"); | ||
python.getString(99, "", array); | ||
|
||
if (indicMedian.init("indicMedian") == INVALID_HANDLE) { | ||
Print("ERROR: indicMedian.init"); | ||
return INIT_FAILED; | ||
} | ||
indicMedian.addPlot(DRAW_COLOR_LINE, "Median"); | ||
indicMedian.plotIndexSetInteger(0, PLOT_LINE_WIDTH, 5); | ||
indicMedian.plotIndexSetInteger(0, PLOT_COLOR_INDEXES, 2); | ||
indicMedian.plotIndexSetInteger(0, PLOT_LINE_COLOR, 0, clrAquamarine); | ||
indicMedian.plotIndexSetInteger(0, PLOT_LINE_COLOR, 1, clrPink); | ||
|
||
indicMedian.show(); | ||
return INIT_SUCCEEDED; | ||
} | ||
|
||
void OnTick() | ||
{ | ||
MqlRates rt[]; | ||
CopyRates(Symbol(), Period(), 0, 2, rt); | ||
ArraySetAsSeries(rt, true); | ||
double pack[4]; | ||
pack[0] = rt[0].open; | ||
pack[1] = rt[0].high; | ||
pack[2] = rt[0].low; | ||
pack[3] = rt[0].close; | ||
double result[100]; | ||
python.getDouble(0, 0, pack, result); | ||
|
||
const double median = result[0]; | ||
const double median1 = (rt[1].high + rt[1].low) / 2.0; | ||
indicMedian.buffer(median, 0, (uchar)(median > median1)); | ||
indicMedian.flush(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# 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. | ||
# | ||
# https://github.com/Roffild/RoffildLibrary | ||
# ============================================================================== | ||
|
||
import sys | ||
import os | ||
|
||
class PythonDLL_Example(): | ||
def getLong(self, magic: int, value: int, array: tuple) -> tuple or list: | ||
raise NotImplementedError | ||
|
||
def getULong(self, magic: int, value: int, array: tuple) -> tuple or list: | ||
raise NotImplementedError | ||
|
||
def getDouble(self, magic: int, value: float, array: tuple) -> tuple or list: | ||
return [(array[1] + array[2]) / 2.0] | ||
|
||
def getString(self, magic: int, value: str, array: bytes) -> str: | ||
if magic == 1: | ||
return value + str(sys.version) | ||
if magic == 2: | ||
return str(array) + " " + str(sys.version_info) | ||
if magic == 3: | ||
return "sys.path:\n" + "\n".join(sys.path) + \ | ||
"os.environ[\"PATH\"]:\n" + os.environ["PATH"].replace(";", "\n") | ||
raise Exception("This is not a bug! This is a feature :D") | ||
|
||
|
||
__mql__ = PythonDLL_Example() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,241 @@ | ||
/* | ||
* 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. | ||
* | ||
* https://github.com/Roffild/RoffildLibrary | ||
*/ | ||
#include "../../Libraries/Roffild/PythonDLL/public.h" | ||
|
||
/** | ||
* Class for PythonDLL.dll | ||
*/ | ||
class CPythonDLL | ||
{ | ||
protected: | ||
string bufstr; | ||
|
||
public: | ||
CPythonDLL() | ||
{ | ||
StringInit(bufstr, 1000111); | ||
} | ||
|
||
/** | ||
* Attempt to create a Python environment. | ||
* If python_home is set incorrectly, the terminal will be destroyed. | ||
* | ||
* @param[in] python_home path to the environment of Python. | ||
* @param[in] console show console window. | ||
* @return Py_NewInterpreter() != NULL | ||
*/ | ||
bool initialize(const string python_home, const bool console = false) | ||
{ | ||
const string packages = | ||
python_home + "/python37.zip;" | ||
+ python_home + "/lib;" | ||
+ python_home + "/lib/site-packages;" | ||
+ python_home + "/DLLs;" | ||
+ python_home + "/;"; | ||
const string dlls = | ||
python_home + "/;" | ||
+ python_home + "/Library/bin;" // Anaconda | ||
+ python_home + "/DLLs;"; | ||
return pyInitialize(packages, dlls, console); | ||
} | ||
|
||
/** | ||
* Check the active environment of Python. | ||
* | ||
* @return status. | ||
*/ | ||
bool isInitialized() | ||
{ | ||
return pyIsInitialized(); | ||
} | ||
|
||
/** | ||
* It is not necessary to use this function, | ||
* because it is always called when a test is completed or MetaTrader is closed. | ||
*/ | ||
void finalize() | ||
{ | ||
pyFinalize(); | ||
} | ||
|
||
/** | ||
* Compiling and executing code. | ||
* | ||
* @param[in] pycode | ||
* @param[in] override_class when changing the variable __mql__, set to true. | ||
* @return error status. | ||
*/ | ||
bool eval(const string pycode, const bool override_class = false) | ||
{ | ||
return pyEval(pycode, override_class); | ||
} | ||
|
||
/** | ||
* Checks for errors. | ||
* To get an error message, use getErrorText(). | ||
* | ||
* @param[in] clear clears the error. | ||
* @return error status. | ||
*/ | ||
bool isError(const bool clear = true) | ||
{ | ||
return pyIsError(clear); | ||
} | ||
|
||
/** | ||
* Checks for errors, gets text and clears the error. | ||
*/ | ||
string getErrorText() | ||
{ | ||
const int size = pyGetErrorText(bufstr, StringBufferLen(bufstr)); | ||
if (size < 0) { | ||
return "Error in getErrorText()"; | ||
} | ||
if (size == 0) { | ||
return ""; | ||
} | ||
return bufstr; | ||
} | ||
|
||
/** | ||
* Calls the __mql__.getLong() function with the data passed. | ||
* The error is automatically displayed in the log. | ||
* | ||
* @param[in] magic | ||
* @param[in] value | ||
* @param[in] inputs | ||
* @param[out] outputs array size will not change. | ||
* @param[in] inputs_size | ||
* @param[in] outputs_size | ||
* @return the size of the array returned from Python or -1 on a runtime error. | ||
*/ | ||
int getLong(const long magic, const long value, const long &inputs[], long &outputs[], | ||
const int inputs_size = WHOLE_ARRAY, const int outputs_size = WHOLE_ARRAY) | ||
{ | ||
const int size = pyMQL_getLong( | ||
magic, value, | ||
inputs, (inputs_size < 0 ? ArraySize(inputs) : inputs_size), | ||
outputs, (outputs_size < 0 ? ArraySize(outputs) : outputs_size) | ||
); | ||
if (size < 0) { | ||
Print(getErrorText()); | ||
} | ||
return size; | ||
} | ||
|
||
/** | ||
* Calls the __mql__.getULong() function with the data passed. | ||
* The error is automatically displayed in the log. | ||
* | ||
* @param[in] magic | ||
* @param[in] value | ||
* @param[in] inputs | ||
* @param[out] outputs array size will not change. | ||
* @param[in] inputs_size | ||
* @param[in] outputs_size | ||
* @return the size of the array returned from Python or -1 on a runtime error. | ||
*/ | ||
int getULong(const long magic, const ulong value, const ulong &inputs[], ulong &outputs[], | ||
const int inputs_size = WHOLE_ARRAY, const int outputs_size = WHOLE_ARRAY) | ||
{ | ||
const int size = pyMQL_getULong( | ||
magic, value, | ||
inputs, (inputs_size < 0 ? ArraySize(inputs) : inputs_size), | ||
outputs, (outputs_size < 0 ? ArraySize(outputs) : outputs_size) | ||
); | ||
if (size < 0) { | ||
Print(getErrorText()); | ||
} | ||
return size; | ||
} | ||
|
||
/** | ||
* Calls the __mql__.getDouble() function with the data passed. | ||
* The error is automatically displayed in the log. | ||
* | ||
* @param[in] magic | ||
* @param[in] value | ||
* @param[in] inputs | ||
* @param[out] outputs array size will not change. | ||
* @param[in] inputs_size | ||
* @param[in] outputs_size | ||
* @return the size of the array returned from Python or -1 on a runtime error. | ||
*/ | ||
int getDouble(const long magic, const double value, const double &inputs[], double &outputs[], | ||
const int inputs_size = WHOLE_ARRAY, const int outputs_size = WHOLE_ARRAY) | ||
{ | ||
const int size = pyMQL_getDouble( | ||
magic, value, | ||
inputs, (inputs_size < 0 ? ArraySize(inputs) : inputs_size), | ||
outputs, (outputs_size < 0 ? ArraySize(outputs) : outputs_size) | ||
); | ||
if (size < 0) { | ||
Print(getErrorText()); | ||
} | ||
return size; | ||
} | ||
|
||
/** | ||
* Calls the __mql__.getString() function with the data passed. | ||
* The error is automatically displayed in the log. | ||
* | ||
* @param[in] magic | ||
* @param[in] value | ||
* @param[in] inputs | ||
* @param[in] inputs_size | ||
* @return the string returned from Python or "" on a runtime error. | ||
*/ | ||
string getString(const long magic, const string value, const uchar &inputs[], | ||
const int inputs_size = WHOLE_ARRAY) | ||
{ | ||
const int size = pyMQL_getString( | ||
magic, value, | ||
inputs, (inputs_size < 0 ? ArraySize(inputs) : inputs_size), | ||
bufstr, StringBufferLen(bufstr) | ||
); | ||
if (size < 0) { | ||
Print(getErrorText()); | ||
return ""; | ||
} | ||
return bufstr; | ||
} | ||
|
||
/** | ||
* Calls the __mql__.getString() function with the data passed. | ||
* The error is automatically displayed in the log. | ||
* | ||
* @param[in] magic | ||
* @param[in] value | ||
* @param[in] inputs | ||
* @param[out] buffer | ||
* @param[in] inputs_size | ||
* @param[in] stringBufferLen use StringBufferLen(buffer) | ||
* @return the size of the array returned from Python or -1 on a runtime error. | ||
*/ | ||
int getString(const long magic, const string value, const uchar &inputs[], string &buffer, | ||
const int inputs_size = WHOLE_ARRAY, const int stringBufferLen = WHOLE_ARRAY) | ||
{ | ||
const int size = pyMQL_getString( | ||
magic, value, | ||
inputs, (inputs_size < 0 ? ArraySize(inputs) : inputs_size), | ||
buffer, (stringBufferLen < 0 ? StringBufferLen(buffer) : stringBufferLen) | ||
); | ||
if (size < 0) { | ||
Print(getErrorText()); | ||
} | ||
return size; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# gitignore | ||
/python_source/ | ||
/x64/ | ||
/.vs/ | ||
*.vcxproj.user |
Oops, something went wrong.