16.02.22
|
Neues Mitglied
|
|
Registriert seit: May 2020
Ort: Duisburg
Beiträge: 28
|
|
CCalc klasse
Immer wieder muss man Preise runden damit es nicht zu Fehlern wie "Invalid Price" oder "Invalid Vloume" kommt. An dieser Stelle hilft die CCalc Klasse
Sie beinhaltet neben den runden der Preise und Volumen auch eine Moneymanagement - Komponente, bei dieser (GetLot) wird das Volumen anhand des SL als double fertig ausgegeben.
Auch kann der aktuelle Start des Tages, der Woche,des Monat oder Jahr abgefragt werden.
Code:
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CCalc
{
private:
double roundLots(string symbol,double& lots);
protected:
double Getlot(string symbol,double sl,ENUM_ORDER_TYPE PosType,double riskaspercent);
double roundUp(string symbol, double price);
double roundDn(string symbol, double price);
datetime GetDayStart();
datetime GetWeekStart();
datetime GetMonthStart();
datetime GetYearStart();
public:
};
//+------------------------------------------------------------------+
//| Matrix Zeitraum Tag |
//+------------------------------------------------------------------+
datetime CCalc::GetDayStart()
{
datetime MatrixDay;
string StartDay="00:00:00";
return MatrixDay=StringToTime(StartDay);
}
//+------------------------------------------------------------------+
//| Matrix Zeitraum Woche |
//+------------------------------------------------------------------+
datetime CCalc::GetWeekStart()
{
MqlDateTime int2;
TimeToStruct(TimeTradeServer(),int2);
int dayofWeekServer=int2.day_of_week;
string StartDay="00:00:00";
datetime Day=StringToTime(StartDay);
if(dayofWeekServer==1)
{
Day=StringToTime(StartDay);
}
else
if(dayofWeekServer==2)
{
Day=StringToTime(StartDay)-86400;
}
else
if(dayofWeekServer==3)
{
Day=StringToTime(StartDay)-172800;
}
else
if(dayofWeekServer==4)
{
Day=StringToTime(StartDay)-259200;
}
else
if(dayofWeekServer==5)
{
Day=StringToTime(StartDay)-345600;
}
else
if(dayofWeekServer==6)
{
Day=StringToTime(StartDay)-432000;
}
else
if(dayofWeekServer==0)
{
Day=StringToTime(StartDay)-518400;
}
return Day;
}
//+------------------------------------------------------------------+
//| Matrix Zeitraum Monat |
//+------------------------------------------------------------------+
datetime CCalc::GetMonthStart()
{
MqlDateTime stm;
TimeToStruct(TimeTradeServer(),stm);
stm.day=1;
stm.hour=0;
stm.min=0;
stm.sec=0;
return(StructToTime(stm));
}
//+------------------------------------------------------------------+
//| Matrix Zeitraum Jahr |
//+------------------------------------------------------------------+
datetime CCalc::GetYearStart()
{
MqlDateTime stm;
TimeToStruct(TimeTradeServer(),stm);
stm.day=1;
stm.mon=1;
stm.hour=0;
stm.min=0;
stm.sec=0;
return(StructToTime(stm));
}
//+------------------------------------------------------------------+
//| Ermittlung des Handelsvolumen / OK |
//+------------------------------------------------------------------+
double CCalc::Getlot(string symbol,double sl,ENUM_ORDER_TYPE PosType,double riskaspercent)
{
double res=0;
double lot=0;
double Capitalbase = AccountInfoDouble(ACCOUNT_EQUITY);
double point=SymbolInfoDouble(symbol,SYMBOL_POINT);
if(PosType==ORDER_TYPE_BUY)
{
//Umrechnung SL in Pip
double kurs=SymbolInfoDouble(symbol,SYMBOL_ASK);
int SLinPoint=(int)NormalizeDouble((kurs-sl)/point,0);
//Berechnung der Lot
double risk = MathMin(riskaspercent,100.0)/100;
lot=Capitalbase*risk*kurs/SLinPoint;
// Print("risk: ",risk," Cap: ",Capitalbase,"SLinPoint: ",SLinPoint,"Lot: ",lot);
}
if(PosType==ORDER_TYPE_SELL)
{
//Umrechnung SL in Pip
double kurs=SymbolInfoDouble(symbol,SYMBOL_BID);
int SLinPoint=(int)NormalizeDouble((sl-kurs)/point,0);
//Berechnung der Lot
double risk = MathMin(riskaspercent,100.0)/100;
lot=Capitalbase*risk*kurs/SLinPoint;
//Print("risk: ",risk," Cap: ",Capitalbase,"SLinPoint: ",SLinPoint,"Lot: ",lot);
}
res=roundLots(symbol,lot);
//Print("Res: ",res);
return res;
}
//+------------------------------------------------------------------+
//| Aufunden des Preises /OK |
//+------------------------------------------------------------------+
double CCalc::roundUp(string symbol, double price)
{
int Dig=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
double Points=NormalizeDouble(SymbolInfoDouble(symbol,SYMBOL_POINT),Dig);
double ticksize =
NormalizeDouble(SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE),Dig);
price = NormalizeDouble(price,Dig);
double rest = price - NormalizeDouble(price/ticksize,0) * ticksize;
rest = NormalizeDouble(rest,Dig);
if(rest != 0)
{
for(double i = Points; i <= ticksize; i += Points)
{
price = NormalizeDouble(price + Points,Dig);
rest = price - NormalizeDouble(price/ticksize,0) * ticksize;
rest = NormalizeDouble(rest,Dig);
if(rest == 0)
break;
}
}
return price;
}
//+------------------------------------------------------------------+
//| Abunden des Preises /OK |
//+------------------------------------------------------------------+
double CCalc::roundDn(string symbol,double price)
{
int Dig=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
double Points=NormalizeDouble(SymbolInfoDouble(symbol,SYMBOL_POINT),Dig);
double ticksize =NormalizeDouble(SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE),Dig);
price = NormalizeDouble(price,Dig);
double rest = price - NormalizeDouble(price/ticksize,0) * ticksize;
rest = NormalizeDouble(rest,Dig);
if(rest != 0)
{
for(double i = Points; i <= ticksize; i += Points)
{
price = NormalizeDouble(price - Points,Dig);
rest = price - NormalizeDouble(price/ticksize,0) * ticksize;
rest = NormalizeDouble(rest,Dig);
if(rest == 0)
break;
}
}
return price;
}
//+------------------------------------------------------------------+
//| Runden des zuvor klakulierten Handelsvolumen /OK |
//+------------------------------------------------------------------+
double CCalc::roundLots(string symbol,double& lots)
{
double startLots = lots;
double lotstep = NormalizeDouble(SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP),2);
lots = NormalizeDouble(lots,2);
double rest = lots - NormalizeDouble(lots/lotstep,0) * lotstep;
rest = NormalizeDouble(rest,2);
if(rest != 0)
{
for(double i = 0.01; i <= lotstep; i += 0.01)
{
lots = NormalizeDouble(lots + 0.01,2);
rest = lots - NormalizeDouble(lots/lotstep,0) * lotstep;
rest = NormalizeDouble(rest,2);
if(rest == 0)
break;
}
}
if(lots - startLots > startLots - (lots - lotstep))
{
lots -= lotstep;
}
lots = MathMin(lots,SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX));
lots = MathMax(lots,SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN));
return lots;
}
//+------------------------------------------------------------------+
Man kann natürlich auch die funktionen als Public deklarieren... ich habe diese nur Protected weil diese nur in bestimmten Punkten meiner Klassenhirachie verfügbar sein sollen.
Geändert von Aleksi (16.02.22 um 21:08 Uhr)
|