Интеграция значения OHLC из Python API в MT5 с использованием MQL5 - PullRequest
0 голосов
/ 27 июня 2018

Я получил значения OHLC от iqoption и пытаюсь найти способ использовать его с 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 в виде: Вывод команды

Теперь я получаю 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")

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Хорошо, вам нужно
1. получить фид от брокера (надеюсь, вам это удалось)
2. запишите его в файл
** (оба - питон) **
3. прочитать и разобрать
4. добавить его в исторический центр / marketWatch
** (оба - mt5) **

  1. Итак, вы получаете данные в виде строки после I_want_money.get_candles(goal,60,111,time.time()) эта строка может быть json или json-array.

  2. Важным вопросом, конечно же, является путь, по которому вы собираетесь поместить данные. Эксперт по 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 в случайное время и записывать их в общую или прямую папку. Робот 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(), по какой-то причине вы получаете ошибки.

Может ли это работать в бэк-тестере? Конечно, нет. Во-первых, OnTimer() не поддерживается в MQL-тестере. Далее, вам нужна некоторая запись истории, чтобы запустить ее. Если у вас нет какой-либо истории - никто не может помочь вам, если брокер может дать ее вам; Лучшая идея - начать собирать и хранить его прямо сейчас, и когда проект будет готов (возможно, через пару месяцев), у вас будет его готовность, и вы сможете протестировать и оптимизировать стратегию с помощью доступного набора данных. Вы можете применить собранный набор в тестер (MQL5 - это действительно следующий шаг в разработке торговых алгоритмов по сравнению с MQL4), либо вручную, либо с помощью чего-то вроде tickDataSuite и его файла Csv2Fxt.ex4, который создает двоичные файлы HST, которые тестер может читать и обрабатывать; в любом случае, это другой вопрос, и никто не может сказать вам, хранит ли ваш брокер свои данные где-то, чтобы предоставить их вам.

0 голосов
/ 04 июля 2018

После второго прочтения того, что вы написали (и отредактировали), я вижу, что вы хотите:

  • символ, синхронизированный с iqoption [через прокси / удаленно]
  • Символ можно использовать для тестирования на истории
  • Символ можно использовать для отображения в реальном времени / запуска стратегии / индикатора

Это подразумевает операции вне стратегии / индикатора, которые платформы MT не позволяют автоматически - вы можете достичь этого вручную, предоставив пакет данных, проанализировав его в CSV и импортировав в создатель пользовательских символов. Хорошо задокументировано здесь .

К сожалению, вы выбираете платформу, которая по своему дизайну означает автономные стратегии и показатели, больше для начинающих, чем для профессионалов, воспринимающих это всерьез.

Обратитесь по ссылке, которую я предоставил, и убедитесь сами. Официальный документ гласит, что вы можете создать пользовательский символ с помощью mql ref , но, несмотря на то, что в предисловии говорится, что он позволяет сторонним поставщикам - на него нет ссылок нигде и он не показывает никаких возможностей интеграции.


пользовательские индикаторы

пользовательские свойства символов

...