PDA

Виж пълната версия : МТ5 - код проблеми.



Kosyo
15.07.2021, 19:07
Отварям тази тема, да ви провокирам за намиране на заобиколни решения на проблеми в платформата МТ5.
За отговори от рода: Е те тва, нема как да стане! - Благодаря, на въздържалите се!

При четене на tick-history:

// download the first few ticks & check the download time // !!! up to 45 seconds
if (CopyTicks(_sName, Т, COPY_TICKS_ALL, 1, 4) <= 0 || GetTickCount64() > msStart + TI_MS_LOOP_LIMIT) {
// _nStatus = MW_FIRST_TICK;
return(4); // war: outside the finalization time
}

функциите: CopyTicks & CopyTicksRange - блокират робота за 45 сек при всяко обръщение, докато даунлоуда не бъде извършен.
Някакви идеи как може да се направи без фризване на робота?

Решения от рода, да се свали в предварение - не ме устройват! При брокер с над 200 инструмента и динамична поява на нови инструменти, е несериозно!

Mateev
15.07.2021, 21:32
Няма лесно решение за този проблем. Аз знам и други функции, които създават подобни проблеми, и единственото разрешение е да се пуснат да работят в отделна нишка. При MetaTrader нова нишка се създава когато програмно се отвори нов графичен прозорец. Да, ама написването на код за комуникация между два различни прозореца е голяма играчка.

Теоретично съм го мислил и съм правил разни експерименти, но никога не съм достигал до напълно завършено работещо решение. Иначе и аз се нуждая от това робота ми да работи в няколко нишки, и искам или не ще се наложи този проблем да го отработя до съвършенство. Например трябва отделна нишка за мениджъра на тиковете, който на всеки няколко милисекунди да проверява за нов тик по всички инструменти в метатрейдера от първия до последния. Това вече съм го реализирал и имам код, който логва всички тикове по всички финансови инструменти. Този код обаче трябва да си има собствена нишка (собствен прозорец), в който да работи само логването и нищо друго.

Иначе ако само с CopyTicks ти е проблема, защо не се опиташ да ги сваляш на малки порции чрез OnTime(50ms). Тогава робота няма да забива за дълги периоди от време.

Защо точно на всеки 50ms?
Ами защото независимо какви бързи процеси се случват, MetaTrader комуникира със сървъра в пакети, които са максимум по 12-15 в секунда. Това го засяках когато правех тик логера - замервах микросекундите и си го изясних този факт. Тиковете на всички инструменти, дори и да са стотици или хиляди, не идват един по един, а групирани в пакети, като самите пакети са по 10-15 на брой в секунда. Следователно ако таймера се настрои на 50ms, няма да се пропусне нито един пакет.

Kosyo
16.07.2021, 01:01
Винаги има пропуснати тикове, но не е толкова голям проблем.
И аз така го мислех, основния прозорец да си отвори нов с даунлоад апп, но не бях на 100% сигурен дали няма да блоква и останалите.
Уви, всичко трябва стабилно тестване, че даже и документираната част не работи всеки път.

Мулти трейда не му е много добър на МТ.
За сега мисля да ползвам CopyTicks само за историята, а текущите тикове ще са малко по рехави, с леки загуби.
Истината е, че не знам какво натоварване ще даде на 20 и 20+ пазара ако CopyTicks се ползва за последните пакети, циклично.
тая функция трябваше да е асинхронна!


... защо не се опиташ да ги сваляш на малки порции чрез OnTime(50ms)
Проблема е докато захапе в началото. Отнема от 5 до 15 мин и после май не се успива. А големината на пакета не е от значение, в горния код свалям само 4 тика - само инициализиране на процеса.

Интересно ми беше дали няма измислено нещо по трикаджийско.
Утре ще го тествам и ще пусна инфо
Докато капитала е под 100к, мисля, че е грешка да се пускат повече от 20 пазара, че даже и 12, но определено трябва да се тестват поне 50 пазара да се види как се представя машината.

Някой има ли протокола за комуникация със сървъра, да се стартират процесите по даунлоуда, през DLL.
Сблъсквал ли си се с бамване от сървъра, при много чести рекуести?

PS: Аз имам и други задачки закачки, но една по една, че апетита идва с яденето :)

Mizzo
17.07.2021, 15:12
Пробвай да извикваш CopyTicks() без параметрите from и count. Пише, че така ще се свалят максимум последните 2000 тика и няма как да се мотае 45 секунди. Мисля, че това е интимния замисъл на Метакуотци да я викаш без да забива за дълго и да сваля само последните тикове. А през уикенда вече, когато пазара си е затворен, бота да я извиква функцията с параметри за да свали и синхронизира всичко от сървъра, примерно from=1, count=UINT_MAX. Разбира се не съм го пробвал, но само това ми идва като идея. Тия 45 секунди би трябвало да са time_out, дори да сваляш цялата история с тикове, да не се мотае повече от 45 секунди, без значение доколко е успешен резултата.
Очевидно бота ще вкарва всички свалени тикове в частни Символи без графики, то тука нямаш избор щото има лимит от 100 отворени графики в Терминала.

Със сигурност има лимит на броя на заявките към сървъра, но няма от къде да се вземе инфо за случая. Хора са споделяли, че са ги банвали заради ботове които работят само с чакащи поръчки и (да кажем) и на всеки няколко тика местят ордерите. После са били разправии със съпорта и насландисване да ти пуснат пак автоматизираната търговия. Но не знам нищо повече.

Kosyo
17.07.2021, 15:55
Mizzo, в горния пример свалям само 4 тика, но от началото на сървърните данни за пазара.
Доста тестове правих и все си иска неговите 45 сек през първите около 15 мин, при всяко обръщение, докато не направи синхронизиране на историята.
Бях се спрял на решение от 5 до 20 мин да правя обръщение към сървъра и така да сведа блокажите до 1 или 2-3.

Идеята нови пазари да се включват от понеделник само, е проста, но решение, даунлоуда да става през уикенда, независимо кога е пусната заявката за нов пазар.
Уикенда да се използва за адаптации и ъпдейти, съм го мислил, но понеже съм максималист, за новите пазари не ми беше хрумвало!

Вчера докато гледах за паралелни нишки (различни роботи) и попаднах на Service, преди 1-2 г. го нямаше! Изглежда може да реши доста проблеми в мулти-маркет, включително и горния.
За съжаление няма никакъв контрол над Service от робота, както и да стартираш от робот, друг робот. Но при роботите поне можеш да изключваш други роботи.

Преди време се бях заиграл да влизам с SDK по менютата и да стартирам процеси които са достъпни само на ръчно, но след страничните ефектите който постигнах и якото чистене след това се въздържам от подобни техники. :)

Ако някой се сблъсква с други интересни проблеми, нека не се въздържа! ...опитвам се да съживя форума, да сме си взаимно полезни :)

nmind
17.07.2021, 18:06
Някой има ли протокола за комуникация със сървъра, да се стартират процесите по даунлоуда, през DLL.
Сблъсквал ли си се с бамване от сървъра, при много чести рекуести?

Протокол няма да намериш, защото това е бизнес модела на Метакуотс да им ползваш терминала. Но заради огромния натиск от страна на клиентите направиха питонтско АПИ за МТ5. Работи бързо (ако го ползваш правилно) и покрива почти всички функционалности (включително доунлоадване на тикове):
https://www.mql5.com/en/docs/integration/python_metatrader5

Тези 45 сек са таймаут, трябва да гледаш грешката (GetLastError), и да повториш заявката, може няколко пъти да изтече по таймаут за един рекуест, но рядко се случва.

Валидациите по заявките са заложени в клиентската част на МТ5, а на сървъра има ограничения за броя позиции (все пак сървърите на брокера не са с неограничена RAM памет).

nmind
17.07.2021, 18:20
При MetaTrader нова нишка се създава когато програмно се отвори нов графичен прозорец. Да, ама написването на код за комуникация между два различни прозореца е голяма играчка.

Теоретично съм го мислил и съм правил разни експерименти, но никога не съм достигал до напълно завършено работещо решение. Иначе и аз се нуждая от това робота ми да работи в няколко нишки, и искам или не ще се наложи този проблем да го отработя до съвършенство. Например трябва отделна нишка за мениджъра на тиковете, който на всеки няколко милисекунди да проверява за нов тик по всички инструменти в метатрейдера от първия до последния. Това вече съм го реализирал и имам код, който логва всички тикове по всички финансови инструменти. Този код обаче трябва да си има собствена нишка (собствен прозорец), в който да работи само логването и нищо друго.

Това с нишките и комуникацията между тях има няколко решения, зависи на какво ниво ти е програмирането и какво бързодействие търсиш. Примерно ползвай сокети или директно мемори мап файлове (и за двата случая можеш да намериш готов код в нета за MQL).

Kosyo
17.07.2021, 22:16
Това с нишките и комуникацията между тях има няколко решения, зависи на какво ниво ти е програмирането и какво бързодействие търсиш. Примерно ползвай сокети или директно мемори мап файлове (и за двата случая можеш да намериш готов код в нета за MQL).

за тоя случай аз бих ползвал handle (HWND) на charta с директни msg-и

Kosyo
17.07.2021, 22:29
Протокол няма да намериш, защото това е бизнес модела на Метакуотс да им ползваш терминала. Но заради огромния натиск от страна на клиентите направиха питонтско АПИ за МТ5. Работи бързо (ако го ползваш правилно) и покрива почти всички функционалности (включително доунлоадване на тикове):
https://www.mql5.com/en/docs/integration/python_metatrader5

Тези 45 сек са таймаут, трябва да гледаш грешката (GetLastError), и да повториш заявката, може няколко пъти да изтече по таймаут за един рекуест, но рядко се случва.

Като чуя няма или не може и вече съм го приел за лично предизвикателство! :)

Достатъчна е проверката: if (CopyTicks(_sName, Т, COPY_TICKS_ALL, 1, 4) <= 0)
и докато не се свалят първите пакети, много вероятно и някакво синхронизиране (мисля, че не финалното), всеки рекуест ти коства 45 сек блокаж на робота, но както казах по-горе ако вторият ти рекуест е след около 15 мин, няма да имаш повече блокажи по тоя пазар, независимо от големината на пакетите които четеш.

Mateev
18.07.2021, 01:41
Като чуя няма или не може и вече съм го приел за лично предизвикателство! :)

Достатъчна е проверката: if (CopyTicks(_sName, Т, COPY_TICKS_ALL, 1, 4) <= 0)
и докато не се свалят първите пакети, много вероятно и някакво синхронизиране (мисля, че не финалното), всеки рекуест ти коства 45 сек блокаж на робота, но както казах по-горе ако вторият ти рекуест е след около 15 мин, няма да имаш повече блокажи по тоя пазар, независимо от големината на пакетите които четеш.

Защо просто не си направиш втори робот, който в реално време да сваля историята на всички символи, включително и на новопоявилите се в реално време. Този робот ще си работи в отделен прозорец (отделна графика) и въобще няма да ти пука, че от време на време зависва. В същото време обаче всичко, което робота свали в неговата си графика, ще бъде на секундата достъпно за всички други графики и всички други роботи.

Kosyo
18.07.2021, 10:23
Защо просто не си направиш втори робот

В момента го обмислям, тествам, но мисля с 2 символа в минута на тая жега. Защо се разписах, да се появи младо попълнение, ама не! :)

Но както вика един приятел: Поне повика неволята и сега ще си го напишеш! :)

За сега варианта с три робота, ми се вижда най-приемлив.
Основния - стартира и спира два спомагателни, който да му вършат мръсната работа.
Единия за даунлоад и синхронизация, другия за обхождане на пазарите. Може и други функции да имат или да се появи трети спомагателен ако се наложи.
Комуникацията през OnChartEvent - асинхронно, на принципа на OnTick - само 1 event, а не стеково.

На база аксиомата: С решаване на един проблем се появяват няколко нови. - С напредване в решението, очаквам да наблюдавам ефекта на следствията.

Друга закачка: Някой виждал ли е OnBookEvent да работи на Real? Да сподели брокера. (На демо и тестера - работи, real-a е проблема!)