Tick Data & Charting : De ce nu un MetaTrader de Nivel II ?
[English version] [MQLmagazine.com in english] [Editia romaneasca]
Ar trebui sa vezi acest articol ca pe o continuare a celui despre Progress Apama, pentru ca vine cu probleme institutionale la nivelul MetaTrader5. Daca vezi strategia de arbitraj statistic, o sa observi ca are o executie cel mult la 1-2 secunde. Deci, nu pare HFT deloc. Dar devine HFT in contextul rularii a 500 de instante – pentru ca va avea sute de executii pe secunda. Totusi, pana la 10-20 de instante, e ceva ce si MetaTrader5 poate suporta.
Aceasta strategie m-a inspirat sa ma gandesc la un indicator care deseneaza charturi la nivel de tick. Desigur, poti vedea un asemenea chart, dar in Market Watch, facand clic pe “Tick Chart” langa “Symbols”. Dar daca vrei sa vezi mai mult decat una la un moment dat? Asa ca am scris un indicator. Nu prea mi-a reusit, dar Rosh (Rashid Umarov) mi-a sarit in ajutor. Acesta este corpul indicatorului, scris dupa inserarea nivelelor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | //+------------------------------------------------------------------+ //| Ticks.mq5 | //| Copyright 2010, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "2010, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_buffers 2 #property indicator_plots 2 //--- plot Bid #property indicator_label1 "Bid" #property indicator_type1 DRAW_LINE #property indicator_color1 Blue #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot Ask #property indicator_label2 "Ask" #property indicator_type2 DRAW_LINE #property indicator_color2 Red #property indicator_style2 STYLE_SOLID #property indicator_width2 1 #property indicator_level0 0.00 #property indicator_level1 0.00 #property indicator_level2 0.00 #property indicator_level3 0.00 #property indicator_level4 0.00 #property indicator_level5 0.00 #property indicator_level6 0.00 #property indicator_level7 0.00 #property indicator_level8 0.00 #property indicator_level9 0.00 #property indicator_level10 0.00 #property indicator_level11 0.00 #property indicator_level12 0.00 #property indicator_level13 0.00 #property indicator_level14 0.00 #property indicator_level15 0.00 //--- input parameters input int number_of_ticks=1000; input int points_indent=10; input int LevelsCount=7; //--- indicator buffers double BidBuffer[]; double AskBuffer[]; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,BidBuffer,INDICATOR_DATA); SetIndexBuffer(1,AskBuffer,INDICATOR_DATA); PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0); PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0); IndicatorSetString(INDICATOR_SHORTNAME,Symbol()+" Tick Chart"); //--- return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { static int ticks=0; //--- if(ticks==0) { ArrayInitialize(AskBuffer,0); ArrayInitialize(BidBuffer,0); } setMaxMinPrice(ticks,points_indent); //--- CopyRates MqlTick last_tick; if(SymbolInfoTick(Symbol(),last_tick)) { BidBuffer[ticks]=last_tick.bid; AskBuffer[ticks]=last_tick.ask; int shift=rates_total-1-ticks; ticks++; BidBuffer[rates_total-1]=last_tick.bid; AskBuffer[rates_total-1]=last_tick.ask; PlotIndexSetInteger(0,PLOT_SHIFT,shift); PlotIndexSetInteger(1,PLOT_SHIFT,shift); Comment("Bid =",last_tick.bid," Ask =",last_tick.ask); } //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| set Maximum and Minimum for an indicator window based on last values //+------------------------------------------------------------------+ void setMaxMinPrice(int last_values,int indent) { int dgs; double dist; int visiblebars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS); int depth=MathMin(last_values,visiblebars); int startindex=last_values-depth; if (startindex<0) startindex=0; int max_index=ArrayMaximum(AskBuffer,startindex,depth); max_index=max_index>=0?max_index:0; int min_index=ArrayMinimum(BidBuffer,startindex,depth); min_index=min_index>=0?min_index:0; double MaxPrice=AskBuffer[max_index]+indent*_Point; double MinPrice=BidBuffer[min_index]-indent*_Point; IndicatorSetDouble(INDICATOR_MAXIMUM,MaxPrice); IndicatorSetDouble(INDICATOR_MINIMUM,MinPrice); dgs=SymbolInfoInteger(Symbol(),SYMBOL_DIGITS); dist=NormalizeDouble( (MaxPrice-MinPrice)/(LevelsCount+1), dgs); for (int i=0;i<LevelsCount;i++) { IndicatorSetDouble(INDICATOR_LEVELVALUE,i,MinPrice+dist*(i+1)); } } //+------------------------------------------------------------------+ |
Ca si indicator la nivel de tick, arata bine. Dar daca vrei sa mai pui ceva pe el, cum ar fi medii mobile sau benzi Bollinger, sau chiar sa monitorizezi spread-uri, ca in fereastra strategiei din Progress Apama ? Asta inseamna ca trebuie sa scrii indicatori din nou si din nou, numai ca sa-ti arate. Desigur, calculele sunt simplu de facut dintr-un expert – vor avea loc in marea majoritate in evenimentul OnTick() – dar ai nevoie de indicatori ca sa te ajute sa-ti vizualizezi strategia, chiar si daca aplicarea lor practica va fi in mai tot timpul non necesara, datorita calculului separat in expert. Dar fii constient ca nu exista istoric la nivel de tick. Asemenea indicatori deseneaza de la zero. Daca vrei sa vezi pe termen mai indelungat, chiar si cata vreme Strategy Tester nu e disponibil ca sa poti pune indicatorul pe el, trebuie sa-i dai timp sa afiseze, nefiind instant ca ceilalti indicatori.
Deci, daca ar exista istoric la nivel de tick, insemnand si PERIOD_TICK de asemenea, atunci anumite lucruri bune pentru noi vor aparea, cum ar fi:
a. Nu ar fi nevoie de indicatori speciali pentru nivelul de tick.
b. Charturile la nivel de tick apar imediat si se intind pe tot istoricul
c. Istoricul la nivel de tick va face backtesterul mai corect, pentru ca nu va avea nevoie sa inventeze ticksi ca sa acopere asemenea zone.
d. (bila neagra): Spatiu foarte mare de hard disk ocupat de istoric, cerinte mai mari de memorie.
Ce inseamna pentru MetaQuotes:
a. Schimbare in istoric si agregarea datelor, incepand de la tick pentru a face restul, nu de la M1, pastrand M1 ca referinta pentru istoricul vechi unde datele de tick nu sunt disponibile;
b. Modificari minore la functiile de acces la date (gen campuri openbid, openask, closebid, closeask la structura MqlRates etc).
c. Modificari minore la backtester;
d. MetaTrader brandat ca platforma aproape institutionala.
De ce am vrea asta? Ei bine, de ce baietii mari nu folosesc charturi la nivel de bara? La urma urmei, nu exista surprize pe charturile la nivel de tick – si o sa investigam asta alta data – asa ca n-o sa te mai temi ca o bara ca un picior de paianjen iti va atinge stop loss in mijlocul unui trend care arata bine.
Asa ca, daca ai Nivelul II disponibil, si daca il automatizezi, esti aproape de nivelul HFT. De fapt, ceea ce e blama astazi nu e intregul trading algoritmic – pentru ca nu se gandesc niciodata la userii de MetaTrader, E-Signal sau chiar NeoTicker – ci tradingul institutional , necinstit (a se citi “colocat”). La suprafata, discutia este de conflictul intre tradingul computerizat si cel uman. Dar ambele parti ale conflictului lucreaza pe Nivelul II, unde exista posibilitatea de a cota si a avea ordinul executat (adica sa cumperi la bid sau sa vinzi la ask), si sa platesti mici comisioane pentru aceste tranzactii. Chestia e ca, daca am avea Nivel II plus automatizarea MetaTrader, cu comisioane mici de brokeraj, anumite forme de HFT ar deveni aplicabile. Asta e un lucru care a ramas ascuns, faptul ca tradingul de latenta redusa nu e chiar acelasi lucru cu tradingul de frecventa inalta. Eu cred ca tradingul algoritmic de Nivel II poate fi proiectat sa fie HFT chiar daca nu beneficiaza de executia cu latenta redusa. Problema e, traderii au fost indoctrinati asa de mult cu Nivelul I, incat e foarte greu sa faci ca Nivelul II sa fie acceptat. Pentru ca Nivelul I are o mentalitate “cumperi sau vinzi acum, vezi mai tarziu daca ai avut dreptate”, pe cand Nivelul II o are in gen “vezi asta, cotezi, inchizi mai tarziu daca ai avut executie”. Acelasi “mai tarziu” are intelesuri diferite, pentru Nivelul I inseamna de la minute in sus, de regula ore, pe cand la Nivelul II inseamna secunde. Stopul tarator in Nivelul II se misca pip cu pip. Si totul este pentru a face bani in timp real. Nu in ore, nu maine, nu saptamana viitoare. Ci mai degraba, ca sa vezi equity crescand de cateva ori pe minut. Ceea ce se uita de multe ori in trading, e ca strategiile de trading nu sunt pentru roboti care pot astepta o eternitate sa-si imbunatateasca strategiile de trading. Viata se intampla in timp real. Nu suntem nemuritori si dincolo de asta, tineretea e al naibii de scurta. Acesta e si unul din factorii care imping reducerea latentei. Pe de o parte, exista nevoia de a avea ordinele executate inaintea concurentei, pe de alta parte, mai multe si mai multe profituri pe o unitate de timp din ce in ce mai mica inseamna salarii mai grase pentru management… In acest timp, chiar si cel mai rationali si mai de succes traderi pe Nivelul I nu pot trece de anumite limte ale rentabilitatii. Esential, sistemele automate de Nivel II au scopul asta, de a comprima timpul, si de a obtine rentabilitati similare Nivelului I, dar intr-un timp de o suta de ori mai mic sau chiar si mai mic. Dar aceste rentabilitati sunt relative si mici, vazute din interiorul industriei hedge fund. Pentru ca, rezultatele sistemelor sunt relative fata de lichiditatea medie utilizata. Adica, o mare parte din lichiditate ramane neutilizata, dar trebuie sa intoarca rentabilitate. Si, in timp ce diversificarea e un mod de a utiliza mai multa lichiditate, timpul e cealalta fata a monedei, pentru ca o tranzactie pe secunda e un ceva, iar o suta de tranzactii in aceeasi secunda, intinzandu-se pe intervale in microsecunde fiecare, sunt altceva. Pe de alata parte, platformele HFT costa sume nerusinate de bani, iar institutiile mai mici nu si le permit, pentru ca o mare parte din rentabilitate trebuie sa finanteze costurile platformelor si salariile quantilor cu PhD. Acum intelegi de ce un MetaTrader de Nivel II, chiar fara latenta redusa, este important ? Chiar si Irene Aldridge admite ca nu sunt prea multe companii care vand produse pentru buyside. De fapt, daca excludem Strategy Runner, X-Trader si Ninja Trader, nici nu-mi aduc aminte de altele. X-Trader are o automatizare institutionala in termeni de costuri, iar Strategy Runner e asa de criptic ca trebuie sa platesti foarte mult pentru dezvoltarea strategiilor. Niciuna dintre aceste platforme nu integreaza optiunile, iar formarea pietei in optiuni, avand executii acolo, e o cale importanta de a face economii, caci spreadurile optiunilor sunt ridicate.
La urma urmei, daca te uiti pe forumul MQL5, poti vedea ca MetaQuotes cel putin pare a fi hotarata sa faca MetaTrader 5 cea mai buna platforma de trading din lume. Daca MetaTrader5 devine Level II ready (va amintiti vechile placi de baza cu eticheta Prescott ready ?) si prin generarea unei constientizari crescute asupra importantei actiunii la nivel de tick in comunitatea de retail trading, se pot determina schimbari la nivelul brokerajelor.
Pe masura ce brokerii vor da mai mult acces la ECN-uri (de la Electronic Currency Network) cu spreaduri stranse, acestea vor cobori, si e posibil ca sistemul bazat pe spreaduri chiar sa dispara, fiind inlocuit de modelul pe baza de comision – si zic aici comisioane mici, suficient de mici cat sa-l faca pe trader sa simta ca e intr-un ECN , nu ca are doar un feed de retail care brandeaza comisionul in loc de spread. In acest fel mult strategii de la nivelele institutionale vor deveni portabile catre MetaTrader si lumea de retail – care poate chiar va deveni “institutional cu latenta mare” , sau, mai important pentru traderii de retail, HFT GRATUIT, usor de instalat care nu e bazat pe latenta. Problema e, comisioanele sunt functie de volum. Cu cat e mai mare volumul, cu atat sunt mai mici comisioanele. Totusi, cel putin traderii forex au levier mare. (Da, americanii s-ar putea ca in curand sa nu-l mai aiba). Avand levier mare, pierderile mici continua sa loveasca in equity. Cat de mult ai putea suporta pierderi din comisioane pana cand acestea devin destul de mici pentru trece pe profit din rabaturi? Sa nu uitam, economia globala e in recesiune, si brokerii, ca orice afacere normala din lumea asta, traiesc din vanzari… Ceea ce-i face mai deschisi pentru inovare si reducerea comisioanelor, de la mici la infime.
Pe de alta parte, cum ar putea fi MT sa fie utilizat ca platforma de Nivel II asa cum e acum? Sigur, OrderSend() poate fi folosit intr-o maniera Level II, dar cu un backtester care doar modeleaza ticksi, in loc de a fosi ticksi reali? Cred ca nu. Datele la nivel de tick sunt absolut necesare pentru ca statia sa fie brandata ca una de Nivel II.
Totusi, mai sunt lucruri de facut pana acolo, caci MetaQuotes mai are si alte teme de facut : Strategy Tester, o sintaxa mai buna pentru OnTrade(), fereastra Depth of Market si mai ales OnBookEvent(). Cand toate acestea vor fi completate, MT5 va fi atat de departe incat vei uita de dulciurile MT4, sunt sigur de asta…
Daca traderii din comunitatea de retail nu cer totusi mai mult, nimic nu se va obtine, caci ei tin mult la Level II…