Wszystkie pytania dozwolone początkujących programistów

O jezykach programowania w platformach i nie tylko.
Awatar użytkownika
ninjaproject
Maniak
Maniak
Posty: 4944
Rejestracja: 30 lip 2019, 13:15

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: ninjaproject »

lxi pisze:
08 wrz 2023, 16:50
Hej, powiedzcie mi czy w poniższym kodzie jest gdzieś wartość odpowiadająca za dokładność obliczeń wartości wskaźnika wyświetlanych w oknie danych? Niestety nie mam pojęcia o pisaniu i strukturze wskaźników. Wskaźnik wrzucony na wykres np. E/U pokazuje odczyty w oknie danych z dokładnością do 4 miejsc po przecinku a ja chciałbym żeby pokazywał z dokładnością do 5 miejsc (tak jak pokazywana jest cena instrumentu).
Zależy mi na tym gdyż chcę napisać w EA warunek, że jeśli cena tylko dotknie konkretnej linii wskaźnika to ma wykonać pewną czynność. Jeśli nie jestem w stanie porównać odczytów wskaźnika z aktualną ceną (różnica dokładności po przecinku) to będą wychodziły głupoty.TMA ATR Channel.mq4
NormalizeDouble(double,5);

Ale, to nic nie da, ponieważ nie ma metody na takie dokładne określenie ceny, bo zwykle takiej nie ma, jak chcemy. Wszelkie próby napisania warunku typu if(MAPrice==MyPrice) kończą się tym, że EA nic nie robi, bo nigdy nie ma takiego warunku. Nie wiem, poeksperymentuj sam, ale sukcesu nie wróżę. Jesteśmy skazani na if(MAPrice>=MyPrice) i if(MAPrice<=MyPrice).
I nic na to nie poradzimy...

To tylko zmieni co jest wyświetlane, ale nie zmieni rzeczywistości.
Tak samo jak wyrzuczasz wartość double w stringu, to masz DoubleToString(double,dokladnosc);
I to tylko ogranicza, czy normalizuje to co widzisz, ale nie ma wpływu na rzeczywistą cenę kwotowaną w tickach.
Trejder, Mentor/trener, aka. Dadas, fx-technik, obecnie ninjaproject.
Programuję wskaźniki i EA do MetaTrader 4/5.

Awatar użytkownika
ninjaproject
Maniak
Maniak
Posty: 4944
Rejestracja: 30 lip 2019, 13:15

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: ninjaproject »

lxi pisze:
02 sie 2023, 19:50
Ludziska, jak napisać formułę odczytu wartości średniej, ale średniej, która w zakładce "Poziomy" ma ustawione jakieś wartości?
Odczyt standardowy to:

Kod: Zaznacz cały

ema_up = NormalizeDouble(iMA(NULL, PERIOD_CURRENT, 20, 0, MODE_LWMA, PRICE_OPEN, 1), Digits);
Ale moja średnia LWMA 20 tworzy kanał z wartości przesuniętych.
1.png

Jak temu zaradzić? Czy język MQl4 daje w ogóle taką możliwość?

Dodam, że chciałbym odczytać wartości krańcowe czyli poziomy: 90 i -90.

EDIT: Nie było pytania. Właśnie zrozumiałem, że poziom 90 to nic innego jak wartość średniej plus 9 pipsów. A -90 to wartość średniej minus 9 pipsów.
Dziękuję, dobranoc:)
Zakładka poziomy służy do ustalania poziomów dla wskaźników, które są rysowane w osobnym oknie.
Tak jak np. RSI - poziomy OB, OS można sobie ustalić.
To nie ma nic do roboty dla średniej kroczącej w oknie głównym wykresu.

I tak, te poziomy można od razu w kodzie napisać
#property indicator_level1 60
#property indicator_level2 20
Chociaż w tym domyślnym wskaźniku rzeczywiście można tak stworzyć wstęgę.

Ale dla EA, to chyba najwygodniej po prostu wziąć dane z iMA();

Kod: Zaznacz cały

ema = iMA(_Symbol, PERIOD_CURRENT, 20, 0, MODE_LWMA, PRICE_OPEN, 1);
ema_Upper = ema + 90*_Point;
ema_Lower = ema - 90*_Point;
Ostatnio zmieniony 08 wrz 2023, 17:44 przez ninjaproject, łącznie zmieniany 1 raz.
Trejder, Mentor/trener, aka. Dadas, fx-technik, obecnie ninjaproject.
Programuję wskaźniki i EA do MetaTrader 4/5.

lxi
Stały bywalec
Stały bywalec
Posty: 62
Rejestracja: 28 sty 2014, 14:04

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: lxi »

Wiem o czym mówisz, źle się wyraziłem. Z pewnością użyję warunku >= lub <=, natomiast nie wiem, która część kodu wskaźnika odpowiada za to, z jaką dokładnością wyliczane są wartości wskaźnika. Gdybym to wiedział, może byłbym w stanie zmienić tę dokładność na 5 miejsc po przecinku.
Prawdę mówiąc i bez tego sobie poradzę ale pytam w ramach edukacji:)

Awatar użytkownika
ninjaproject
Maniak
Maniak
Posty: 4944
Rejestracja: 30 lip 2019, 13:15

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: ninjaproject »

lxi pisze:
08 wrz 2023, 17:42
Wiem o czym mówisz, źle się wyraziłem. Z pewnością użyję warunku >= lub <=, natomiast nie wiem, która część kodu wskaźnika odpowiada za to, z jaką dokładnością wyliczane są wartości wskaźnika. Gdybym to wiedział, może byłbym w stanie zmienić tę dokładność na 5 miejsc po przecinku.
Prawdę mówiąc i bez tego sobie poradzę ale pytam w ramach edukacji:)
To nie ma znaczenia. Albo inaczej, jest to ograniczone dokładnością samej platformy MT4.
To, że wskaźnik obliczy coś z dokładnością do np. 19-tego miejsca po przecinku, to niczego nie zmieni na wykresie. Jedyne co jest istotne dla OrderSend() i OrderModify() to:

Kod: Zaznacz cały

PriceBuy = NormalizeDouble(PB, _Digits); 
PriceSell = NormalizeDouble(PS, _Digits); 
Tu masz artykuł:
https://www.mql5.com/en/articles/1561

PS. Sprawdź pkt. 4 !
Tego nie próbowałem - może to by zadziałało dla == gdyby porównać dwie zmienne double w taki sposób?
Ostatnio zmieniony 08 wrz 2023, 18:21 przez ninjaproject, łącznie zmieniany 1 raz.
Trejder, Mentor/trener, aka. Dadas, fx-technik, obecnie ninjaproject.
Programuję wskaźniki i EA do MetaTrader 4/5.

lxi
Stały bywalec
Stały bywalec
Posty: 62
Rejestracja: 28 sty 2014, 14:04

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: lxi »

ninjaproject pisze:
08 wrz 2023, 17:48
To nie ma znaczenia. Albo inaczej, jest to ograniczone dokładnością samej platformy MT4.
To, że wskaźnik obliczy coś z dokładnością do np. 19-tego miejsca po przecinku, to niczego nie zmieni na wykresie. Jedyne co jest istotne dla OrderSend() i OrderModify() to:

Kod: Zaznacz cały

PriceBuy = NormalizeDouble(PB, _Digits); 
Price_Sell = NormalizeDouble(PS, _Digits); 
Tu masz artykuł:
https://www.mql5.com/en/articles/1561

PS. Sprawdź pkt. 4 !
Tego nie próbowałem - może to by zadziałało dla == gdyby porównać dwie zmienne double w taki sposób?
Dzięki za pomoc i wyjaśnienia.

Awatar użytkownika
ninjaproject
Maniak
Maniak
Posty: 4944
Rejestracja: 30 lip 2019, 13:15

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: ninjaproject »

Taką funkcje se piszesz:

Kod: Zaznacz cały

//+------------------------------------------------------------------+
//| correct comparison of 2 doubles                                  |
//+------------------------------------------------------------------+
bool CompareDoubles(double number1,double number2,int precision)
  {
   if(NormalizeDouble(number1-number2,precision)==0) return(true);
   else return(false);
  }
//+------------------------------------------------------------------+
Trejder, Mentor/trener, aka. Dadas, fx-technik, obecnie ninjaproject.
Programuję wskaźniki i EA do MetaTrader 4/5.

SuchyRyz
Bywalec
Bywalec
Posty: 19
Rejestracja: 26 lis 2017, 23:24

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: SuchyRyz »

Może ktoś zerknąć na poniższy kod? Otóż, chciałem go przerobić i podstawić zamiast TipuCCI, wskaźnik od Clusterdelta i zrobić skumulowaną deltę. Problem w tym, że nie jestem programistą i prośba czy ktoś mógłby mnie nakierować. Otóż chciałem funkcję iCustom zamienić "ClusterDelta_#Delta...", i zostaje jeszcze przerobienie obszaru "Tipu indicator parameters"? Czy mógłbym całkowicie tą sekcję wywalić i wrzucić funkcję icustom z cluserdelta?

Kod: Zaznacz cały

//+------------------------------------------------------------------+
//|                                              WeisWaveTipuCCI.mq4 |
//|                                Copyright 2023, Sergey Shevchenko |
//|                            https://www.mql5.com/ru/users/baromix |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Sergey Shevchenko"
#property link      "https://www.mql5.com/ru/users/baromix"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_type1 DRAW_HISTOGRAM
#property indicator_color1 clrGreen
#property indicator_width1 3
#property indicator_type2 DRAW_HISTOGRAM
#property indicator_color2 clrRed
#property indicator_width2 3

enum ENUM_SignalMark
{
   None=0,
   Arrows=1,
   VLine=2,
};

input int bars_calc  =  500;  //Bars to calculate

input string   str1  =  "";//---- ZigZag indicator parameters
input int InpDepth=12;     // Depth
input int InpDeviation=5;  // Deviation
input int InpBackstep=3;   // Backstep

input string   str2  =  "";//---- Tipu indicator parameters
input string sCCISettings="---CCI Settings"; //CCI Settings
input int      iCCI_Period=14;                //CCI Period
input ENUM_APPLIED_PRICE eAppliedPrice=PRICE_TYPICAL; //Applied Price
input int      iCCI_OB            = 0;                //Overbought
input int      iCCI_OS            = 0;                //Oversold
input string               sSignalType="----Signal Types--"; //Signal Types
input ENUM_SignalMark      eMarkSignals=1;    //Mark Buy/Sell Signals
input int                  iAOffset=5;     //Arrow offset (pips)
input color          cUpCandle         =  C'31,159,192';  //Up Color
input color          cDwnCandle        =  C'230,77,69';   //Down Color
input string   sAlert0="---Buy/Sell Global Alert Settings----------"; //Alert Settings
input bool     bAlertBuy = true;                      //Alert Buy?
input bool     bAlertSell = true;                     //Alert Sell?
input int      iAlertShift       = 1;                 //Alert Shift
input bool     bAlertM           = false;             //Alert Mobile
input bool     bAlertS=true;             //Alert Onscreen
input bool     bAlertE=false;             //Alert Email

double buf_up[],buf_dn[];
static datetime Old_Time=Time[0];
bool IsNewBar=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   IndicatorBuffers(2);
   SetIndexBuffer(0,buf_up,INDICATOR_DATA);
   SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,3,clrGreen);
   SetIndexBuffer(1,buf_dn,INDICATOR_DATA);
   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,3,clrRed);
   ArraySetAsSeries(buf_up,true);
   ArraySetAsSeries(buf_dn,true);
//--- indicator buffers mapping
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| 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[])
{
//---
   IsNewBar=false;
   if(Old_Time!=iTime(_Symbol,PERIOD_CURRENT,0))
      {
         IsNewBar=true;
         Old_Time=iTime(_Symbol,PERIOD_CURRENT,0);
      };
   double _zig[];
   double tipu_up[],tipu_dn[];
   ArrayResize(buf_up,rates_total);
   ArrayResize(_zig,rates_total);
   ArrayResize(tipu_up,rates_total);
   ArrayResize(tipu_dn,rates_total);
   ArrayInitialize(_zig,0);
   int start_pos=0;
   for(int i=0; i<bars_calc-1; i++)
      {
         _zig[i]=iCustom(_Symbol,PERIOD_CURRENT,"ZigZag",InpDepth,InpDeviation,InpBackstep,0,i);
         tipu_up[i]=iCustom(_Symbol,PERIOD_CURRENT,"Tipu_CCI",sCCISettings,iCCI_Period,eAppliedPrice,iCCI_OB,iCCI_OS,sSignalType,eMarkSignals,iAOffset,
                            cUpCandle,cDwnCandle,sAlert0,bAlertBuy,bAlertSell,iAlertShift,bAlertM,bAlertS,bAlertE,0,i);
         tipu_dn[i]=iCustom(_Symbol,PERIOD_CURRENT,"Tipu_CCI",sCCISettings,iCCI_Period,eAppliedPrice,iCCI_OB,iCCI_OS,sSignalType,eMarkSignals,iAOffset,
                            cUpCandle,cDwnCandle,sAlert0,bAlertBuy,bAlertSell,iAlertShift,bAlertM,bAlertS,bAlertE,1,i);
      };
   for(int i=bars_calc-100; i>0; i--)
      {
         double sum=0.0;
         if(_zig[i]!=0 && _zig[i]!=EMPTY_VALUE)
            {
               int j=i-1;
               while((_zig[j]==0 || _zig[j]==EMPTY_VALUE) && j>0)
                  {
                     if(tipu_up[j]!=EMPTY_VALUE)
                        sum=sum+tipu_up[j];
                     if(tipu_dn[j]!=EMPTY_VALUE)
                        sum=sum+tipu_dn[j];
                     if(sum>0)
                        buf_up[j]=sum;
                     if(sum<0)
                        buf_dn[j]=sum;
                     j--;
                  };
               if(tipu_up[j]!=EMPTY_VALUE)
                  sum=sum+tipu_up[j];
               if(tipu_dn[j]!=EMPTY_VALUE)
                  sum=sum+tipu_dn[j];
               if(sum>0)
                  buf_up[j]=sum;
               if(sum<0)
                  buf_dn[j]=sum;
               i=j+1;
            };
      }
//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+

Sabtor
Uczestnik
Uczestnik
Posty: 1
Rejestracja: 29 maja 2022, 13:25

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: Sabtor »

Cześć wszystkim, od niedawna uczę się programowania. Nigdzie nie mogę znaleźć funkcji zwracającej cenę poziomu fibonacci expansion. Czy jest ktoś w stanie mi pomóc?

lxi
Stały bywalec
Stały bywalec
Posty: 62
Rejestracja: 28 sty 2014, 14:04

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: lxi »

Mam takiego case'a. Nie potrafię pisać wskaźników więc chciałem jeden z nich przerobić na moje potrzeby.
Chciałbym aby wskaźnik rysował strzałkę w górę gdy RSI przebija poziom 30 od dołu ORAZ gdy EMA 49>EMA89.
Strzałka w dół ma być rysowana gdy RSI schodzi poniżej poziomu 70 ORAZ gdy EMA49<EMA89.

Dodałem kilka rzeczy do kodu ale kod nie bierze w ogóle pod uwagę warunku ułożenia średnich.

Kod: Zaznacz cały

   if (TimeFrame == Period())
   {
      for(i=limit; i>=0; i--)
      {
         double rsi = iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,i); 
         double rsi_prev = iRSI(NULL,0,RSIPeriod,PRICE_CLOSE,i+1);
         double ema_49 = iMA(NULL, 0, 49, 0, MODE_EMA, PRICE_CLOSE, 1);//Dopisane przeze mnie
         double ema_89 = iMA(NULL, 0, 89, 0, MODE_EMA, PRICE_CLOSE, 1);//Dopisane przeze mnie
         arrUp[i] = EMPTY_VALUE; 
         arrDn[i] = EMPTY_VALUE;
         if (i<Bars-1)
         { 
           //trend[i] = trend[i+1];
           if (rsi>30&&rsi_prev<=30&&ema_49>ema_89) trend[i] = 1;//Warunek ze średnimi dopisany przeze mnie
           if (rsi<70&&rsi_prev>=70&&ema_49<ema_89) trend[i] =-1;//Warunek ze średnimi dopisany przeze mnie
         }
         //if (i<Bars-1 && trend[i]!= trend[i+1])
         //{
            if (trend[i] ==  1) arrUp[i] = Low[i] -iATR(NULL,0,15,i)*ArrowGapUp;
            if (trend[i] == -1) arrDn[i] = High[i]+iATR(NULL,0,15,i)*ArrowGapDn;
          //}
       }
Może ktoś jest w stanie zrobić to odpowiednio?
Cały kod załączam poniżej.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.

mql5programowanie
Uczestnik
Uczestnik
Posty: 2
Rejestracja: 26 maja 2024, 15:29

Re: Wszystkie pytania dozwolone początkujących programistów

Nieprzeczytany post autor: mql5programowanie »

lxi pisze:
25 kwie 2024, 17:26

Poniżej masz kod ale na mt5.


#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots 2
#property indicator_label1 "ArrowUp"
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrGreen
#property indicator_style1 STYLE_SOLID
#property indicator_width1 5
#property indicator_label2 "ArrowDown"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrRed
#property indicator_style2 STYLE_SOLID
#property indicator_width2 5
input string _____1_____ = "Indicator settings";
input ENUM_TIMEFRAMES Inp_Timeframe = PERIOD_CURRENT; // Timeframe for indicator
input int Inp_Period = 7; // Rsi period
input ENUM_MA_METHOD Inp_MA_Method = MODE_EMA;
input ENUM_APPLIED_PRICE Inp_Applied_price = PRICE_CLOSE;
int min_rates_total=90;
double Up[],Down[];
int rsi,ma_fast,ma_slow;
double MaFast[],MaSlow[],Rsi[];
int OnInit(){
SetIndexBuffer(0,Up,INDICATOR_DATA);
SetIndexBuffer(1,Down,INDICATOR_DATA);
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total);
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,min_rates_total);
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,EMPTY_VALUE);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,EMPTY_VALUE);
PlotIndexSetInteger(0,PLOT_ARROW,233);
PlotIndexSetInteger(1,PLOT_ARROW,234);
return(INIT_SUCCEEDED);
}
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[]){
rsi=iRSI(_Symbol,Inp_Timeframe,Inp_Period,Inp_Applied_price);
ma_fast=iMA(_Symbol,Inp_Timeframe,49,0,Inp_MA_Method,Inp_Applied_price);
ma_slow=iMA(_Symbol,Inp_Timeframe,89,0,Inp_MA_Method,Inp_Applied_price);
if(rates_total < min_rates_total) return(0);
if(BarsCalculated(ma_fast) < rates_total ||
BarsCalculated(ma_slow) < rates_total){
Print("Not all data is calculated. Error ", GetLastError());
return 0;}
if(IsStopped()) return(0);
if(CopyBuffer(ma_fast, 0, 0, rates_total, MaFast) <= 0 ||
CopyBuffer(ma_slow, 0, 0, rates_total, MaSlow) <= 0 ||
CopyBuffer(rsi, 0, 0, rates_total, Rsi) <= 0){
Print("CopyBuffer failed! Error ", GetLastError());
return(0);}
int limit=prev_calculated-1;
if(prev_calculated==0) limit=0;
for(int i=limit;i<rates_total;i++){
if(i>0&&Rsi>30&&Rsi[i-1]<=30&&MaFast>MaSlow){
Up=high+50*_Point;
Down=EMPTY_VALUE;}
else if(i>0&&Rsi<70&&Rsi[i-1]>=70&&MaFast<MaSlow){
Down=high[i]+50*_Point;
Up[i]=EMPTY_VALUE;}
else{
Up[i]=EMPTY_VALUE;
Down[i]=EMPTY_VALUE;}}
return(rates_total);
}

ODPOWIEDZ