我已经从 iqoption 中获得了 OHLC 值,并试图找到一种将其与 MT5 一起使用的方法。
以下是我如何获得这些值:
import time
from iqoptionapi.stable_api import IQ_Option
I_want_money=IQ_Option("email","password")
goal="EURUSD"
print("get candles")
print(I_want_money.get_candles(goal,60,111,time.time()))
上面的代码库在这里:iqoptionapi
行:I_want_money.get_candles(goal,60,111,time.time())
输出 json 为:Output of the command
现在我在输出中得到 json,所以它像 API 一样工作,我猜是这样。
与此同时,我尝试在 MT5 中创建一个自定义符号作为 iqoption
。现在我只想将 OHLC 的数据从 API 添加到它,以便它继续从 Iqoption 获取数据并在图表窗口中显示自定义交易品种 iqoption
的图表。
但我无法将其加载到自定义交易品种中。请帮助我。
已编辑
这是来自 iqoption 的实时流数据的代码:
from iqoptionapi.stable_api import IQ_Option
import logging
import time
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(message)s')
I_want_money=IQ_Option("email","password")
I_want_money.start_candles_stream("EURUSD")
thread=I_want_money.collect_realtime_candles_thread_start("EURUSD",100)
I_want_money.start_candles_stream("USDTRY")
thread2=I_want_money.collect_realtime_candles_thread_start("USDTRY",100)
time.sleep(3)
#Do some thing
ans=I_want_money.thread_collect_realtime.items()
for k, v in ans:
print (k, v)
I_want_money.collect_realtime_candles_thread_stop(thread)
I_want_money.stop_candles_stream("EURUSD")
I_want_money.collect_realtime_candles_thread_stop(thread2)
I_want_money.stop_candles_stream("USDTRY")
最佳答案
好的,你需要
1. 接收broker的feed(希望你成功了)
2. 写入文件
**(两者都是 python)**
3.读取并解析
4.添加到历史中心/marketWatch
**(两者 - mt5)**
因此,您在之后接收到字符串形式的数据
I_want_money.get_candles(目标,60,111,time.time())
此字符串可能是 json 或 json-array。重要的问题当然是您要放置数据的路径。 MQL45 专家只能访问两个文件夹(如果不应用 dll): C:\Users\MY_NAME_IS_DANIEL_KNIAZ\AppData\Roaming\MetaQuotes\Terminal\MY_TERMINAL_ID_IN_HEX_FORMAT\MQL4\Files 和 C:\Users\MY_NAME_IS_DANIEL_KNIAZ\AppData\Roaming\MetaQuotes\Terminal\Common\Files 在后一种情况下,您需要使用 const int handle=FileOpen(,|*| FILECOMMON);
打开文件
为了解析 json,您可以使用 jason.mqh https://www.mql5.com/en/code/13663库(几乎没有其他库),但据我所知它有一个错误:它无法正确解析对象数组。为了克服这个问题,我建议将每个刻度写在单独的一行中。 最后,您将在随机时间从您的 Python 应用程序接收数据,并将其写入 Common 或直接文件夹。 MT5 机器人将读取并删除。为避免混淆,最好保证文件具有唯一名称。随机(random.randint(1,1000))或日期时间的毫秒数都可以提供帮助。
到目前为止,你有 python 代码:
receivedString = I_want_money.get_candles(goal,60,111,time.time())
filePath = 'C:\Users\MY_NAME_IS_DANIEL_KNIAZ\AppData\Roaming\MetaQuotes\Terminal\MY_TERMINAL_ID_IN_HEX_FORMAT\MQL4\Files\iqoptionfeed'
fileName = os.path.join(filePath,"_"+goal+"_"+str(datetime.now())+".txt")
file = open(fileName, "w")
for string_ in receivedString:
file.write(string_)
file.close()
如果您创建了一个线程,每次您收到线程的回答时,您都会编写这样一个文件。
接下来,您需要在 MT5 中获取该数据。 最简单的方法就是遍历已有的文件,确保能读取再读取(不能读取则放弃)读取后删除,再对接收到的数据进行处理。 最简单和快速的方法当然是使用 0MQ,但让我们在没有 dll 的情况下进行。 为了读取文件,您需要设置一个可以尽可能快地工作的计时器,然后放手。由于您不能让 Windows 应用休眠时间少于 15.6 毫秒,因此您的计时器应该休眠该时间。
string path;
int OnInit()
{
EventSetMillisecondTimer(16);
path="iqoptionfeed\\*";
}
void OnDeinit(const int reason) { EventKillTimer(); }
string _fileName;
long _search_handle;
void OnTimer()
{
_search_handle=FileFindFirst(path,_fileName);
if(_search_handle!=INVALID_HANDLE)
{
do
{
ResetLastError();
FileIsExist(_fileName);
if(GetLastError()!=ERR_FILE_IS_DIRECTORY)
processFile(path+_fileName);
}
while(FileFindNext(_search_handle,_fileName));
FileFindClose(_search_handle);
}
}
这段代码循环文件夹并处理它设法找到的每个文件。 现在读取文件(两个函数)并处理其中的消息:
void processFile(const string fileName)
{
string message;
if(ReadFile(fileName,message))
processMessage(message,fileName);
}
bool ReadFile(const string fileName,string &result,const bool common=false)
{
const int handle = FileOpen(fileName,common?(FILE_COMMON|FILE_READ):FILE_READ);
if(handle==INVALID_HANDLE)
{
printf("%i - failed to find file %s (probably doesnt exist!). error=%d",__LINE__,fileName,GetLastError());
return(false);
}
Read(handle,result);
FileClose(handle);
if(!FileDelete(fileName,common?FILE_COMMON:0))
printf("%i - failed to delete file %s/%d. error=%d",__LINE__,fileName,common,GetLastError());
return(true);
}
void Read(const int handle,string &message)
{
string text="";
while(!FileIsEnding(handle) && !IsStopped())
{
text=StringConcatenate(text,FileReadString(handle),"\n");
}
//printf("%i %s - %s.",__LINE__,__FUNCTION__,text);
message=text;
}
最后但并非最不重要的:处理获得的文件。
正如上面所建议的,它有一个 json 格式的刻度,用于每个新刻度,以\r\n 分隔。
我们的目标是将它添加到符号中。为了解析 json,jason.mqh 是一个可用的解决方案,但您当然可以手动解析它。
void processMessage(const string message,const string fileName)
{
string symbolName=getSymbolFromFileName(fileName);
if(!SymbolSelect(symbolName,true))
{
if(!CustomSymbolCreate(symbolName))
return;
}
string lines[];
int size=StringSplit(message,(ushort)'\n',lines);
for(int i=0;i<size;i++)
{
if(StringLen(lines[i])==0)
continue;
CJAVal jLine(jtUNDEF,NULL);
jLine.Deserialize(lines[i]);
MqlTick mql;
//here I assume that you receive a json file like " { "time":2147483647,"bid":1.16896,"ask":1.16906,"some_other_data":"someOtherDataThatYouMayAlsoUse" } "
mql.time=(datetime)jLine["time"].ToInt();
mql.bid=(double)jLine["bid"].ToDbl();
mql.ask=(double)jLine["ask"].ToDbl();
ResetLastError();
if(CustomTicksAdd(symbolName,mql)<0)
printf("%i %s - failed to upload tick: %s %s %.5f %.5f. error=%d",__LINE__,__FILE__,symbolName,TimeToString(mql.time),mql.bid,mql.ask,GetLastError());
}
}
string getSymbolFromFileName(const string fileName)
{
string elements[];
int size=StringSplit(fileName,(ushort)'_',elements);
if(size<2)
return NULL;
return elements[1];
}
不要忘记添加调试信息和请求 GetLastError()
是出于某种原因你得到的错误。
这可以在后台测试器中工作吗?当然不是。首先,MQL 测试器不支持 OnTimer()
。接下来,您需要一些历史记录才能使其运行。如果您没有任何历史记录——没有人可以帮助您,除非经纪人可以给您;最好的办法是立即开始收集和存储它,当项目准备就绪时(可能再过几个月),您将准备好并能够使用可用数据集测试和优化策略。您可以将收集的集合应用到测试器中(与 MQL4 相比,MQL5 实际上是算法交易开发的下一步),您可以手动或使用类似 tickDataSuite 及其 Csv2Fxt.ex4 文件的东西,该文件生成测试器可以读取和处理的 HST 二进制文件;无论如何,这是另一个问题,没有人能告诉您您的经纪人是否将他们的数据存储在某处以提供给您。
关于python - 使用 MQL5 将 OHLC 值从 Python API 集成到 MT5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51061059/