I have a sort algorithm that sorts on class data fields I want to pass a generic pointer of the data field to the sort instead of making the decision inside the sort
Anyone know how to do this in mql4?
General rules and best pratices of the Forum. - General - MQL5 programming forum
I have a sort algorithm that sorts on class data fields I want to pass a generic pointer of the data field to the sort instead of making the decision inside the sort
Anyone know how to do this in mql4?
- MT4/5 doesn't have pointers, so cant be done.
- Either go the CObject route where a int is passed to the overridden compare method.
- Or go my route, a custom comparator function. Sort multiple arrays - MQL4 and MetaTrader 4 -
MQL4 programming forum
Anyone know how to do this in mql4?
I agree with whroeder1; there's no way of doing this for any arbitrary object in MQL.
It's possible in something like Javascript, because any object is just an associative array (nothing to do with "pointers"), and Object.x is equivalent to Object["x"]. Therefore, in Javascript, it's possible to write code such as the following:
// Sorts by a.high compared to b.high var strSortByMember = "high"; arr.sort(function (a, b) { return a[strSortByMember] - b[strSortByMember]; });
But there's no MQL equivalent to that.
Like whroeder1, I'd also suggest a "custom comparator" function, but I'd propose quicksort rather than insertion-sort; it's faster on average for any general usage. Example attached.
When you post code please use the SRC button! Please edit your post.
General rules and best pratices of the Forum. - General - MQL5 programming forum
- MT4/5 doesn't have pointers, so cant be done.
- Either go the CObject route where a int is passed to the overridden compare method.
- Or go my route, a custom comparator function. Sort multiple arrays - MQL4 and MetaTrader 4 -
MQL4 programming forum
Nice link...thanks. I will adapt when have opportunity. re-post source - can't see how to but my question is answered
I agree with whroeder1; there's no way of doing this for any arbitrary object in MQL.
It's possible in something like Javascript, because any object is just an associative array (nothing to do with "pointers"), and Object.x is equivalent to Object["x"]. Therefore, in Javascript, it's possible to write code such as the following:
But there's no MQL equivalent to that.
Like whroeder1, I'd also suggest a "custom comparator" function, but I'd propose quicksort rather than insertion-sort; it's faster on average for any general usage. Example attached.
Your comments have been absorbed. The situation is clarified. Its a script and not time critical however I have archived the link you provided for future works.
Many thanks
Your version of quicksort is terrible; it partitions down to 16 items and insertion-sorts below that. All good implementations that I know of, stop partitioning at 16 items, and performs one final insertion-sort.
If there are less than ~30 items then just insertion-sort will be quicker on MT4/5 where array accesses are 5-10x slower than other languages. This is why I only provided IS and not my complete (but untested) QS, because most lists will not exceed that limit.
Your version of quicksort is terrible
If we're going to get personal, I quickly adapted it from MarcoNeri's old post some time ago in the thread where you and he/she were exchanging comments. His/her code - of which mine is just a templated adaptation - may be "terrible", but I also did a benchmark which said that, despite being terrible, it still outperformed your insertion sort in any plausible scenario. Attached.
(Underlying JIT compilation of the MT4 platform may have changed in the interim, affecting the results.)
I think the answer you're looking for is using the standard library collections. In order to implement pointer sorting you have to derive a class from CObject and override the compare method. Then you add the pointer to the collection object and sort as needed.
//+------------------------------------------------------------------+ //| instrument_class_sort.mq4 | //| Copyright 2017, nicholishen | //| https://www.forexfactory.com/nicholishen | //+------------------------------------------------------------------+ #property copyright "Copyright 2017, nicholishen" #property link "https://www.forexfactory.com/nicholishen" #property version "1.00" #property strict #include <Arrays\List.mqh> #define SORT_SPREAD 0 #define SORT_NAME 1 class Instrument : public CObject { public: string symbol; double marginRequired; double spread; double csi; int digits; double stopLevel; double lotSize; double lotStep; double lotMin; double pointSize; double tickValue; double tickSize; string descr; double bid; double swapLong; double swapShort; string swaptype; string tradeAllowed; string profitCalcMode; double adx; double adxr; double atr; void Instrument(string Sy,string des=""){setValues(Sy,des);} void setValues(string Sy,string des="") { symbol=Sy; marginRequired=MarketInfo(Sy,MODE_MARGINREQUIRED); spread=MarketInfo(symbol,MODE_SPREAD); digits=int(MarketInfo(Sy,MODE_DIGITS)); stopLevel=MarketInfo(Sy,MODE_STOPLEVEL); lotSize=MarketInfo(Sy,MODE_LOTSIZE); lotStep=MarketInfo(Sy,MODE_LOTSTEP); lotMin=MarketInfo(Sy,MODE_MINLOT); pointSize=MarketInfo(Sy,MODE_POINT); tickValue=MarketInfo(Sy,MODE_TICKVALUE); tickSize=MarketInfo(Sy,MODE_TICKSIZE); descr=des; bid=MarketInfo(Sy,MODE_BID); swapLong=MarketInfo(Sy,MODE_SWAPLONG); swapShort=MarketInfo(Sy,MODE_SWAPSHORT); //swaptype=InfoToStr(MarketInfo(Sy,MODE_SWAPTYPE),MODE_SWAPTYPE); //tradeAllowed=InfoToStr(MarketInfo(Sy,MODE_TRADEALLOWED),MODE_TRADEALLOWED); //profitCalcMode=InfoToStr(MarketInfo(Sy,MODE_PROFITCALCMODE),MODE_PROFITCALCMODE); } void calcADX(string Sy,ENUM_TIMEFRAMES timeFrame,int period) { adx=iADX(Sy,timeFrame,period,PRICE_CLOSE,0,1); } void calcADXR(string Sy,ENUM_TIMEFRAMES timeFrame,int period,int adxBefore,int mBars) { adxr=iCustom(Sy,timeFrame,"ADXR",period,adxBefore,mBars,3,1); } void calcATR(string Sy,ENUM_TIMEFRAMES timeFrame,int period) { atr=iATR(Sy,timeFrame,period,1); } void calcCSI(string Sy,ENUM_TIMEFRAMES timeFrame,int period,int adxBefore,int mBars) { csi=iCustom(Sy,timeFrame,"CSI",period,adxBefore,mBars,0,1); int debug=1; } int Compare(const CObject *node,const int mode=0)const override { Instrument *other = (Instrument*)node; if(mode==SORT_NAME) { if(this.symbol>other.symbol) return 1; if(this.symbol<other.symbol) return -1; } if(mode==SORT_SPREAD) { if(this.spread>other.spread) return 1; if(this.spread<other.spread) return -1; } return 0;//same or sorting not implemented. } }; void OnStart() { //--- CList list; for(int i=0;i<SymbolsTotal(false);i++) list.Add(new Instrument(SymbolName(i,false))); list.Sort(SORT_SPREAD); for(Instrument *i=list.GetFirstNode();i!=NULL;i=i.Next()) Print(i.symbol," has a spread of ",i.spread); } //+------------------------------------------------------------------+
#include <Arrays\List.mqh> #include <stderror.mqh> #include <stdlib.mqh> #define SORT_SPREAD 0 #define SORT_NAME 1 #define SORT_CSI 2 CList list; //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ ENUM_TIMEFRAMES tfEnum[]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1}; //int sizePeriods=ArraySize(tfEnum); extern int IndPeriod=14;//Period extern int adxAgo=14;//Period extern ENUM_TIMEFRAMES tf=PERIOD_D1; int TotalSymbols; //int totalWatchSymbols; string Symbols[1000]; string descr[1000]; int fontSize=8; int fontSpacing=14; string fontType="Windings";//Times New Roman"; string comment=NULL; color clrVar1=clrDarkGray; color clrVar2=clrLemonChiffon; color clrHeader=clrAzure; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class instrument : public CObject { public: string symbol; double marginRequired; double spread; double csi; int digits; double stopLevel; double lotSize; double lotStep; double lotMin; double pointSize; double tickValue; double tickSize; string descr; double bid; double swapLong; double swapShort; string swaptype; string tradeAllowed; string profitCalcMode; double adx; double adxr; double atr; void instrument(string Sy="",string des="",ENUM_TIMEFRAMES timeFrame=PERIOD_D1,int period=14,int adxBefore=14,int mBars=2000) { symbol=Sy; marginRequired=MarketInfo(Sy,MODE_MARGINREQUIRED); spread=MarketInfo(symbol,MODE_SPREAD); digits=int(MarketInfo(Sy,MODE_DIGITS)); stopLevel=MarketInfo(Sy,MODE_STOPLEVEL); lotSize=MarketInfo(Sy,MODE_LOTSIZE); lotStep=MarketInfo(Sy,MODE_LOTSTEP); lotMin=MarketInfo(Sy,MODE_MINLOT); pointSize=MarketInfo(Sy,MODE_POINT); tickValue=MarketInfo(Sy,MODE_TICKVALUE); tickSize=MarketInfo(Sy,MODE_TICKSIZE); descr=des; bid=MarketInfo(Sy,MODE_BID); swapLong=MarketInfo(Sy,MODE_SWAPLONG); swapShort=MarketInfo(Sy,MODE_SWAPSHORT); swaptype=InfoToStr(MarketInfo(Sy,MODE_SWAPTYPE),MODE_SWAPTYPE); tradeAllowed=InfoToStr(MarketInfo(Sy,MODE_TRADEALLOWED),MODE_TRADEALLOWED); profitCalcMode=InfoToStr(MarketInfo(Sy,MODE_PROFITCALCMODE),MODE_PROFITCALCMODE); adx=iADX(Sy,timeFrame,period,PRICE_CLOSE,0,1); adxr=iCustom(Sy,timeFrame,"ADXR",period,adxBefore,mBars,3,1); atr=iATR(Sy,timeFrame,period,1); csi=iCustom(Sy,timeFrame,"CSI",period,adxBefore,mBars,0,1); double normaliseTickNotEqualPoint = MarketInfo(symbol, MODE_POINT) / MarketInfo(symbol, MODE_TICKSIZE); double priceOneLotThisStopDistance=spread * MarketInfo(symbol,MODE_TICKVALUE) * normaliseTickNotEqualPoint; } int Compare(const CObject *node,const int mode=0)const override { instrument *other=(instrument*)node; if(mode==SORT_NAME) { if(this.symbol>other.symbol) return 1; if(this.symbol<other.symbol) return -1; } if(mode==SORT_SPREAD) { if(this.spread>other.spread) return 1; if(this.spread<other.spread) return -1; } if(mode==SORT_CSI) { if(this.csi>other.csi) return 1; if(this.csi<other.csi) return -1; } return 0;//same or sorting not implemented. } }; //+------------------------------------------------------------------+ //|OnStart | //+------------------------------------------------------------------+ void OnStart() { //set and count the symbols data TotalSymbols=FindSymbols(); ArrayResize(Symbols,TotalSymbols); ArrayResize(descr,TotalSymbols); string var="variable"; //set Headers int posY=0; displayHeaders(var,posY); //--- for(int j=0; j<TotalSymbols; j++)//all Instruments { if(!IsSymbolInMarketWatch(Symbols[j])) continue; //list.Add(new instrument(SymbolName(j,false))); list.Add(new instrument(Symbols[j],descr[j])); } list.Sort(SORT_CSI); //Display sorted symbols data posY++; displaySymbolsData(var,posY); }
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use