//+------------------------------------------------------------------+ //| MTBalancer.mqh | //| Copyright 2018, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property library #property version "1.7"; #include #include #include #include CAccountInfo account; CTrade trade; #define ASK NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits) #define BID NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits) #define PRICE NormalizeDouble((ASK+BID)/2, _Digits) //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void place_a_long(double price, int take_profit, int volume_mult=1, int stop_loss=0) { double Ask = price; double t_stop_loss = 0; if(stop_loss>0) { t_stop_loss = Ask-stop_loss*_Point; } trade.Buy( 0.10*volume_mult, // Volume, in this case 10 mini lost or .1 std-lot NULL, // symbol im running from ( most of my run are done in the EURUSD) Ask, // Buying price ... since buy, its done using the ask for this case t_stop_loss, // stop-loss, this should be ignored in this case ... we will see Ask+take_profit*_Point, // take profit ( this is our band activation for the box NULL // this is a comment ); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void place_a_short(double price, int take_profit, int volume_mult=1, int stop_loss=0) { double Bid = price; double t_stop_loss = 0; if(stop_loss > 0) { t_stop_loss = Bid+stop_loss*_Point; } trade.Sell(0.10*volume_mult, NULL, Bid, t_stop_loss, Bid-take_profit*_Point, NULL); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Sorting done by least - to - most profitable //| Also will mean that (more to less costly positions) //+------------------------------------------------------------------+ void SortedPositions(int &buffer[]) { CSortedMap s_positions; for(int i=PositionsTotal()-1; i>=0; i--) { int ticket = (int)PositionGetTicket(i); double profit = PositionGetDouble(POSITION_PROFIT); s_positions.Add(profit, ticket); } double keys[]; s_positions.CopyTo(keys, buffer, 0); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int GetHighestCostPosition(bool isLong=true) { int s_positions[]; SortedPositions(s_positions); for(int i=0; i=0; i--) { int ticket = s_positions[i]; PositionSelectByTicket(ticket); if(isLong) { if(PositionGetInteger(POSITION_TYPE)== POSITION_TYPE_BUY) { return ticket; } } else { if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { return ticket; } } } return -1; // if this where to happen there is an error! } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetVolume(bool isLong=true) { double Total_Volume = 0; for(int i=0; i<=PositionsTotal(); i++) { int ticket = (int)PositionGetTicket(i); PositionSelectByTicket(ticket); if(isLong) { if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { Total_Volume += PositionGetDouble(POSITION_VOLUME); } } else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { Total_Volume += PositionGetDouble(POSITION_VOLUME); } } return Total_Volume; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void close_all_positions() { for(int i=PositionsTotal()-1 ; i>= 0 ; i--) { int ticket = (int)PositionGetTicket(i); trade.PositionClose(ticket); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetVolumeDifference(bool wDirection=false) { if(wDirection) { return GetVolumeInLong() - GetVolumeInShort(); } return fabs(GetVolumeInLong() - GetVolumeInShort()); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetVolumeInShort() { return GetVolume(false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetVolumeInLong() { return GetVolume(true); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double depositLoad() { return (account.Margin() / account.Balance()) * 100; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int CountPositionsByType(bool isLong=true) { int long_count=0, short_count=0; for(int i=PositionsTotal() -1 ; i>=0; i--) { PositionSelectByTicket(PositionGetTicket(i)); if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) { long_count ++; } else { short_count ++; } } if(isLong) { return long_count; } return short_count; } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int PositionDifferenceByType(bool wDirrection=false) { int long_c= CountPositionsByType(); int short_c=CountPositionsByType(false); if(wDirrection) { return fabs(long_c - short_c); } return (long_c - short_c); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetHigestPositionOpenPrice() { double result=-1; for(int i=0; i< PositionsTotal(); i++) { long ticket = (int)PositionGetTicket(i); PositionSelectByTicket(ticket); double new_price = PositionGetDouble(POSITION_PRICE_OPEN); if(new_price>result) { result = new_price; } } return result; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetLowestPositionOpenPrice() { double result=-1; for(int i=0; i< PositionsTotal(); i++) { long ticket = (int)PositionGetTicket(i); PositionSelectByTicket(ticket); double new_price = PositionGetDouble(POSITION_PRICE_OPEN); if(new_price= 0 ; i--) { int ticket = (int)PositionGetTicket(i); PositionSelectByTicket(ticket); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) { trade.PositionClose(ticket); } } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CloseAllLongs() { for(int i=PositionsTotal()-1 ; i>= 0 ; i--) { int ticket = (int)PositionGetTicket(i); PositionSelectByTicket(ticket); if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) { trade.PositionClose(ticket); } } } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ double GetPositionSizeByRisk(double risk_percent, int stop_loss,double price) { // pip_at_risk * pip_value * lots_traded = amount to risk //amount_at_risk / (pip_at_risk * pip_value) = lots double amount_to_risk = account.Balance() * risk_percent; double pips_to_risk = stop_loss; double pip_value = (0.0001 * 100000) / price; double lots_to_trade = amount_to_risk / (pips_to_risk * pip_value); return NormalizeDouble(lots_to_trade, 2); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void PlaceLongPosition(int take_profit, int stop_loss, double risk_percent) { double volume = GetPositionSizeByRisk(risk_percent, stop_loss, BID); double position_sl = NormalizeDouble(ASK - (stop_loss*_Point), _Digits); double positons_tp = NormalizeDouble(ASK + (take_profit*_Point), _Digits); trade.Buy(volume, _Symbol, ASK, position_sl, positons_tp, NULL); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void PlaceShortPosition(int take_profit, int stop_loss, double risk_percent) { double volume = GetPositionSizeByRisk(risk_percent, stop_loss, BID); double position_sl = NormalizeDouble(BID + (stop_loss*_Point), _Digits); double positons_tp = NormalizeDouble(BID - (take_profit*_Point), _Digits); trade.Sell(volume, _Symbol, BID, position_sl, positons_tp, NULL); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool HasReachedPriceChange(double base_price, double curr_price, int pip_change) { double pip_difference = fabs(base_price - curr_price); Print("Looking Inside: ", StringFormat("%2.5f | %2.5f | %2.5f", base_price, curr_price, pip_difference)); if(pip_difference > (120*_Point)) { Print("Difference: ", pip_difference); } return pip_difference >= (pip_change * _Point); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class HTTPAccountLog { private: string address; int port; int socket; CAccountInfo account; bool httpSend(string request) { char req[]; int len = StringToCharArray(request, req)-1; if(len<0) return false; else return(SocketSend(socket,req,len)==len); } double deposit_load() { return (account.Margin()/ account.Equity()) * 100; } public: void log_data() { string dl = "\"deposit_load\" : \"" + deposit_load()+ "\""; string date = "\"date\" : \""+ TimeToString(TimeCurrent())+ "\""; string equity = "\"equity\" : \"" + account.Equity() + "\""; string json_req = StringFormat("{ %s , %s , %s}", dl,date,equity); string http_request_tmplt = "POST %s HTTP/1.1\r\nHost: %s:%d\r\nContent-Type: application/json\r\nContent-Length: %d\r\n\r\n %s"; string http_request = StringFormat(http_request_tmplt, "/upload/01", address, port, StringLen(json_req), json_req); bool resp = httpSend(http_request); if(resp) { Print("Could write to server"); } else { Print("failed writing to server ..."); } } void AccountLog(void) { socket = SocketCreate(); address = "127.0.0.1"; port = 5001; account = CAccountInfo(); } void closeConnect(void) { SocketClose(socket); } }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class AccountLog { private: string foldername; string filename; string ffilename; CFile fp; CAccountInfo account; double max_deposit_load; double min_deposit_load; datetime start_date; double deposit_load(void) { return (account.Margin()/ account.Equity()) * 100; } public: void store_log(void) { double crr_deposit_load = deposit_load(); if(crr_deposit_load > max_deposit_load) { max_deposit_load = crr_deposit_load; } else if(crr_deposit_load < min_deposit_load) { min_deposit_load = crr_deposit_load; } } void write_log(void) { fp.Open(ffilename, FILE_WRITE|FILE_READ|FILE_ANSI|FILE_CSV|FILE_COMMON, ','); fp.Seek(0, SEEK_END); FileWrite(fp.Handle(), "min_deposit_load", min_deposit_load, "max_deposit_load", max_deposit_load, "deposit_load", deposit_load(), "start_date", start_date, "end_date", TimeToString(TimeCurrent()), "equity", account.Equity()); fp.Close(); } void AccountLog(void) { foldername = "LogReport"; filename = "report_01_03.csv"; ffilename = foldername+"\\"+filename; account = CAccountInfo(); fp = CFile(); max_deposit_load = -1; min_deposit_load = 999; start_date = TimeCurrent(); } void AccountLog(string nfilename) { foldername = "LogReport"; filename = nfilename; ffilename = foldername+"\\"+filename; account = CAccountInfo(); fp = CFile(); max_deposit_load = -1; min_deposit_load = 999; start_date = TimeCurrent(); } }; //+------------------------------------------------------------------+