Forums Development Q & A For MQ4 Coding Newbies

This topic has been reported for inappropriate content

Viewing 25 posts - 51 through 75 (of 81 total)
  • Author
    Posts
  • #10471
    smallcat
    Participant

      @simplex,

      Thanks a lot, this is really helpful :good:

      #10561
      simplex
      Moderator

        Hi Guys!

        Some of you will possibly remember that I don’t get tired to emphasize how important it is to include #property strict on top of practically every MQL code.

        This afternoon I downloaded an indicator that shows a nice example of why this is so important. Experienced coders see it at a glance, but newbies please take some minutes to think about what’s wrong with the following function contained in this indicator:

        bool LoadMsgArray() {          // Load msgs into array
           ArrayResize(msgArray, 14);   // MT4 Text Handling is all f***ked up!!!  Makes absolutely no sense!
           ArrayResize(clrArray, 14);
           msgArray[1]  = "Ultra Low Volume";
           clrArray[1]  = Red;
           msgArray[2]  = "Low Volume";
           clrArray[2]  = Blue;
           //  ...   etc ...
           msgArray[13] = "Very High Vol < Prev 2";
           clrArray[13] = DarkOrange;
           msgArray[14] = "CAUTION - Ultra High Volume";
           clrArray[14] = Red;
           return(true);
        }

        What will happen when we compile the code (a) without #property strict and (b) with #property strict included?

        In both cases, our code will be compiled, generating a .ex4 file which can be loaded.

        • In case (b) it will generate a runtime error initially after loading.
        • In case (a) it will run without an error message, possibly showing false results.

        My personal lesson learned: when I’m writing code just to play around with MT4, I might as well choose to go the easy way and prefer (a). But when writing indicators and EAs which possibly will trade with my money, then I’ll choose to use whatever technical means I have at hand to increase the probability to identify any bug before it causes any damage.

        Using MQ4 code without #property strict is not an option for me.

        And besides: turning this compiler directive always on is a good training for coding newbies, because the complier won’t get tired nagging until you’re enhancing your code. And since the compiler is really strict in this case, it’s not only a good choice for newbies!

        And NO: I did not add that comment on top of this function, it was already in there! B-)

        Drop a line when you have a solution about the bug!

        s.

        A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)

        #10611
        Anti
        Participant

          Thanks for this topic. I have several basic questions.

          1. Let’s assume that I will calculate the average range (Close - Open) of last m bars. (At the moment I’m not interested in ranges but in my volume estimates; I decided to use ranges as an example as it seems to be quite simple thus that other readers can benefit from explanations.) How can I do it. I’ve thought to write a loop that inverts all negative ranges. But unfortunately I have absolutely no idea how to do and if this is the “correct” way.
          2. Now I’d like to calculate the n-days MA of this average ranges.
          3. Especially in the FF similarity thread I’ve seen that bollinger bands have been applied on indicator values. Now let’s assume that I will do this too on results from 1.

          Many thanks in advance!

          #10620
          MTH2014
          Participant

            Thanks for this topic. I have several basic questions.

            1. Let’s assume that I will calculate the average range (Close - Open) of last m bars. (At the moment I’m not interested in ranges but in my volume estimates; I decided to use ranges as an example as it seems to be quite simple thus that other readers can benefit from explanations.) How can I do it. I’ve thought to write a loop that inverts all negative ranges. But unfortunately I have absolutely no idea how to do and if this is the “correct” way.
            2. Now I’d like to calculate the n-days MA of this average ranges.
            3. Especially in the FF similarity thread I’ve seen that bollinger bands have been applied on indicator values. Now let’s assume that I will do this too on results from 1.

            Many thanks in advance!

            Hi Brother, forgive me for my noob idea..

            1. You could use MA for this averaging , and you could use

            double MathAbs(
            double value // numeric value
            );

            to make all the calculation in positive value.
            for example ;

            
            //for your 1st question
            AverageRange{i} = MathAbs ( iMA(Symbol(),NULL,InpAveragePeriod,0,0,PRICE_CLOSE,i)
            - iMA(Symbol(),NULL,InpAveragePeriod,0,0,PRICE_OPEN, i)
            );
            //for your 2nd question
            MAonAverageRange{i} = iMAOnArray(AverageRange,0,nDays,0,0,i);
            //for your 3rd question
            BBonAverageRange{i} = iBandsOnArray(AverageRange,0,nDays,BBdeviation,BBshift,BBmode,i);
            

            PS: You should change ‘{}’ with correct bracket (I can’t type it because this bracket is reserved character here in BBCode.. i think)

            Of course you should create loop ‘for’ to make it right..

            Hope it help and best regards :good:

            MTH

            • This reply was modified 10 years, 4 months ago by MTH2014.
            • This reply was modified 10 years, 4 months ago by MTH2014.
            • This reply was modified 10 years, 4 months ago by MTH2014.

            Intuition, Experiences and Common sense..
            http://www.binaryoptionsedge.com/

            #10624
            smallcat
            Participant

              Hi Guys! Some of you will possibly remember that I don’t get tired to emphasize how important it is to include #property strict on top of practically every MQL code. This afternoon I downloaded an indicator that shows a nice example of why this is so important. Experienced coders see it at a glance, but newbies please take some minutes to think about what’s wrong with the following function contained in this indicator:

              bool LoadMsgArray() {          // Load msgs into array
                 ArayrResize(msgArray, 14);   // MT4 Text Handling is all f***ked up!!!  Makes absolutely no sense!
                 ArrayResize(clrArray, 14);
                 msgArray[1]  = "Ultra Low Volume";
                 clrArray[1]  = Red;[quote quote=10561]Hi Guys! Some of you will possibly remember that I don’t get tired to emphasize how important it is to include #property strict on top of practically every MQL code. This afternoon I downloaded an indicator that shows a nice example of why this is so important. Experienced coders see it at a glance, but newbies please take some minutes to think about what’s wrong with the following function contained in this indicator:
              bool LoadMsgArray() {          // Load msgs into array
                 ArrayResize(msgArray, 14);   // MT4 Text Handling is all f***ked up!!!  Makes absolutely no sense!
                 ArrayResize(clrArray, 14);
                 msgArray[1]  = "Ultra Low Volume";
                 clrArray[1]  = Red;
                 msgArray[2]  = "Low Volume";
                 clrArray[2]  = Blue;
                 //  ...   etc ...
                 msgArray[13] = "Very High Vol < Prev 2";
                 clrArray[13] = DarkOrange;
                 msgArray[14] = "CAUTION - Ultra High Volume";
                 clrArray[14] = Red;
                 return(true);
              }
              What will happen when we compile the code (a) without #property strict and (b) with #property strict included? In both cases, our code will be compiled, generating a .ex4 file which can be loaded.
              • In case (b) it will generate a runtime error initially after loading.
              • In case (a) it will run without an error message, possibly showing false results.
              My personal lesson learned: when I’m writing code just to play around with MT4, I might as well choose to go the easy way and prefer (a). But when writing indicators and EAs which possibly will trade with my money, then I’ll choose to use whatever technical means I have at hand to increase the probability to identify any bug before it causes any damage. Using MQ4 code without #property strict is not an option for me. And besides: turning this compiler directive always on is a good training for coding newbies, because the complier won’t get tired nagging until you’re enhancing your code. And since the compiler is really strict in this case, it’s not only a good choice for newbies! And NO: I did not add that comment on top of this function, it was already in there! B-) Drop a line when you have a solution about the bug! s. 

              msgArray[2] = "Low Volume"; clrArray[2] = Blue; // ... etc ... msgArray[13] = "Very High Vol < Prev 2"; clrArray[13] = DarkOrange; msgArray[14] = "CAUTION - Ultra High Volume"; clrArray[14] = Red; return(true); }
              What will happen when we compile the code (a) without #property strict and (b) with #property strict included? In both cases, our code will be compiled, generating a .ex4 file which can be loaded.

              • In case (b) it will generate a runtime error initially after loading.
              • In case (a) it will run without an error message, possibly showing false results.

              My personal lesson learned: when I’m writing code just to play around with MT4, I might as well choose to go the easy way and prefer (a). But when writing indicators and EAs which possibly will trade with my money, then I’ll choose to use whatever technical means I have at hand to increase the probability to identify any bug before it causes any damage. Using MQ4 code without #property strict is not an option for me. And besides: turning this compiler directive always on is a good training for coding newbies, because the complier won’t get tired nagging until you’re enhancing your code. And since the compiler is really strict in this case, it’s not only a good choice for newbies! And NO: I did not add that comment on top of this function, it was already in there! B-) Drop a line when you have a solution about the bug! s. [/quote]

              Hi simplex,
              Not so sure, but i think this can cause problem :

              ArrayResize(msgArray, 14);
              msgArray[14] = "CAUTION - Ultra High Volume";
              
              We define the size of msgArray to 14 (which is begin with 0, end with 13). Then we put at 15 position with msgArray[14],
              the MT4 will not complain about it (if we do not use "strict" property), as we compile it. But actually the text 
              ""CAUTION - Ultra High Volume" is going to the black hole ...   :-)  
              
              #10625
              smallcat
              Participant

                Thanks for this topic. I have several basic questions.

                1. Let’s assume that I will calculate the average range (Close - Open) of last m bars. (At the moment I’m not interested in ranges but in my volume estimates; I decided to use ranges as an example as it seems to be quite simple thus that other readers can benefit from explanations.) How can I do it. I’ve thought to write a loop that inverts all negative ranges. But unfortunately I have absolutely no idea how to do and if this is the “correct” way.
                2. Now I’d like to calculate the n-days MA of this average ranges.
                3. Especially in the FF similarity thread I’ve seen that bollinger bands have been applied on indicator values. Now let’s assume that I will do this too on results from 1.

                Many thanks in advance!

                Hi Brother, forgive me for my noob idea.. 1. You could use MA for this averaging , and you could use

                double MathAbs(
                double value // numeric value
                );

                to make all the calculation in positive value. for example ;

                
                //for your 1st question
                AverageRange{i} = MathAbs ( iMA(Symbol(),NULL,InpAveragePeriod,0,0,PRICE_CLOSE,i)
                - iMA(Symbol(),NULL,InpAveragePeriod,0,0,PRICE_OPEN, i)
                );
                //for your 2nd question
                MAonAverageRange{i} = iMAOnArray(AverageRange,0,nDays,0,0,i);
                //for your 3rd question
                BBonAverageRange{i} = iBandsOnArray(AverageRange,0,nDays,BBdeviation,BBshift,BBmode,i);
                

                PS: You should change ‘{}’ with correct bracket (I can’t type it because this bracket is reserved character here in BBCode.. i think) Of course you should create loop ‘for’ to make it right.. Hope it help and best regards :good: MTH

                Thanks a lot brother Kiads, this is a good example  for me to understand “OnArray” better … :good:

                #10630
                simplex
                Moderator

                  Ok:

                  1. (a) A loop over those m bars is exactly the thing to do first. I would prefer a for () { … } in this case, others might go for a while () { … } . What I like with for loops: the basic loop control is on top, I see it at a glance. (b) Inverting those negative ranges would imply to check for sign first and then multiply by -1. Easier to use MathAbs(Close – Open), and sum this up in a loop.
                  2. You want to average the result of step 1. So it makes sense to store these values in an array. And since your ranges shall be synced with your bar charts (I assume that) we will declare our array of type double as an indicator buffer. This was an implicit proposal to wrap this logic in an indicator, no script or EA. This is no necessary condition, though! When this buffer is filled, you would use standard function iMAOnArray() to accomplish your goal of averaging results of step 1. This implies you have declared a 2nd buffer for these averaged results before.
                  3. Function iBandsOnArray would be our tool in this case, having declared two more buffers for these BB lines before.

                  So far for the plan. Now there are many little details to consider until an indicator will display correctly.

                  Have you got a reliable indicator skeleton? I could post one tomorrow if you or somebody else were interested.

                  s.

                  A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)

                  #10633
                  simplex
                  Moderator

                    :good:

                    Not so sure, but i think this can cause problem :

                    Absolutely correct – that’s it! The highest warning level of this indicator will be dumped in a black hole without a warning.

                    Who wants that?

                    s.

                    Edit: Adding #property strict is always the first thing I do before compiling downloaded code. All those hidden little sins of fellow coders displayed as compiler errors and warnings. Ok – not ALL the sins you might do while coding, but some of them. Those the compiler can spot. It’s a first indicator to see whether that fellow coder knows what he / she is doing.

                    • This reply was modified 10 years, 4 months ago by simplex. Reason: addendum

                    A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)

                    #10645
                    smallcat
                    Participant

                      Ok:

                      1. (a) A loop over those m bars is exactly the thing to do first. I would prefer a for () { … } in this case, others might go for a while () { … } . What I like with for loops: the basic loop control is on top, I see it at a glance. (b) Inverting those negative ranges would imply to check for sign first and then multiply by -1. Easier to use MathAbs(Close – Open), and sum this up in a loop.
                      2. You want to average the result of step 1. So it makes sense to store these values in an array. And since your ranges shall be synced with your bar charts (I assume that) we will declare our array of type double as an indicator buffer. This was an implicit proposal to wrap this logic in an indicator, no script or EA. This is no necessary condition, though! When this buffer is filled, you would use standard function iMAOnArray() to accomplish your goal of averaging results of step 1. This implies you have declared a 2nd buffer for these averaged results before.
                      3. Function iBandsOnArray would be our tool in this case, having declared two more buffers for these BB lines before.

                      So far for the plan. Now there are many little details to consider until an indicator will display correctly. Have you got a reliable indicator skeleton? I could post one tomorrow if you or somebody else were interested. s.

                      Very nice and clear steps bro  :good:  i like to use for instead if while too (i always forget to add i++ or i–, increment or decrement at the end of the while loops, so it is always looping and freeze my mt4).   And if you don’t mind, i would like to see the whole code of this … thanks in advance.

                      #10648
                      Anti
                      Participant

                        M

                        Thank you very much, @MTH2014 (Kiads), @smallcat, and @simplex! Will try it next night …

                        • This reply was modified 10 years, 4 months ago by Anti.
                        • This reply was modified 10 years, 4 months ago by Anti.
                        #10653
                        simplex
                        Moderator

                          @smallcat:

                          And if you don’t mind, i would like to see the whole code of this … thanks in advance.

                          Ask @Anti – this is his baby! :-)

                          s.

                          A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)

                          #10658
                          Anti
                          Participant

                            @smallcat: Unfortunately at the moment I have tons of other things to do. But I will attach it here when I’ve finished this exercise.

                            #10659
                            Anti
                            Participant

                              Have you got a reliable indicator skeleton? I could post one tomorrow if you or somebody else were interested. s.

                              I’d really like to see it. Thanks in advance!

                              #10660
                              smallcat
                              Participant

                                @simplex & @anti,

                                It is ok … thanks

                                #10665
                                Anti
                                Participant

                                  Attached you can find a fast and dirty code for the mean range. Haven’t applied the BB function yet, as I think it’s not useful for graphical representation.

                                  • This reply was modified 10 years, 4 months ago by Anti.
                                  Attachments:
                                  You must be logged in to view attached files.
                                  #10677
                                  simplex
                                  Moderator

                                    :good:

                                    Attached you can find a fast and dirty code for the mean range.

                                    Not too bad, if you have no or only minimum experience in coding mq4!

                                    I did not check the function yet, but looks ok at first sight.

                                    What you should change in any case is adding indentation, function headers, etc: give your code a meaningful structure! I would suggest to read this post of mine, load the software and apply it to a copy of your script. This is the first thing I do to any mq4 I download.

                                    The result will give you an instant idea of how your code might look like when well structured.

                                    I will look for a link that covers this topic systematically and post later.

                                    s.

                                    A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)

                                    #10678
                                    Anti
                                    Participant

                                      Thank’s for your guidance. Good job :good:

                                      #10730
                                      bharath4x
                                      Participant

                                        Thanks Simplex for this great thread to help newbie coders like me.

                                        I tried to make changes to ClearMethod indicator (attached) by Simplex to have one buffer and apply color change base on applied value (1 = Green, -1 = Red, 0 = None) but did not succeed.

                                        Appreciate, if someone review my changes and advice.

                                        Thanks!

                                        • This reply was modified 10 years, 4 months ago by bharath4x.
                                        Attachments:
                                        You must be logged in to view attached files.
                                        #10733
                                        MTH2014
                                        Participant

                                          Thanks Simplex for this great thread to help newbie coders like me. I tried to make changes to ClearMethod indicator (attached) by Simplex to have one buffer and apply color change base on applied value (1 = Green, -1 = Red, 0 = None) but did not succeed. Appreciate, if someone review my changes and advice. Thanks!

                                          If I’m not wrong, you try to set 3 color condition in single index buffer ? you can’t do that. If you change according to current condition, then the new color will override the whole old color of that buffer. For 3 condition colors you need also 3 index buffers,  that’s why Simplex use 2 buffers for his ClearMethodSimple indicator in histo shape, because he only need 2 conditions with 2 colors..

                                          Best Regards

                                          MTH

                                           

                                          Intuition, Experiences and Common sense..
                                          http://www.binaryoptionsedge.com/

                                          #10738
                                          simplex
                                          Moderator

                                            Kiads already answered, and there’s not much to add.

                                            I tried to make changes to ClearMethod indicator (attached) by Simplex

                                            Re. your code: it would be nice if MT4 indicators worked that way! If you want to have different colours on screen, you got to declare one buffer per colour. From the point of view of a software architect, this is suboptimal, trying to use friendly words. A total waste of memory resources.

                                            Until a year ago (builds prior to 600), you could only have max. 8 visible buffers per indicator, now it’s 512.

                                            I think MT5 has got methods that overcome this issue, but there are not so many brokers which support the MT5 platform. And code is not backwards compatible to MT4, so most coders refuse, too. Too much hazzle to recode more or less everything, letting other issues of MT5 aside.

                                            s.

                                            A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)

                                            #10814
                                            bharath4x
                                            Participant

                                              Thanks MTH & Simplex for the detailed explanation.

                                              #10863
                                              smallcat
                                              Participant

                                                Hi,
                                                Any body have idea about the logic of creating MTF indicator ? Normally i create a main indicator, and i call it using iCustom (so i need to create 2 indicators in this case). By this way, i can create a MTF indicator set the TF from M1 to MN1 , and i can call the main indicator from other TF (lets say on TF M1, M5, … MN1 chart). The result must be same .

                                                I found a MTF indicator that is useful to get result on current TF and Bigger TF only, but can not calculate the smaller TF. Example: We attach an Moving Average MTF indicator on TF M15. We can see the result of MA for TF M15, M30, … or other bigger TF. But we can not see the result of MA of TF M1 or M5 on that M15 chart.

                                                I do not know what i did is right or wrong, but i can get result of all TF (from M1 to MN1) even i attach the MTF indicator on M15. I just need to use “i” feature on main indicator, before i call it from MTF indicator (second indicator). For example, to get the close bar of a bar, instead of using ‘Close(i)’  ** should be bracket here **, i use  ‘iClose(NULL,TF,i)’ . So, i should use these :

                                                iBars, iBarshift, iHigh, iClose, iOpen, iLow, iVolume, iTime.

                                                Lets say i have a calculation like this on a normal indicator :

                                                double avg = (Close(i) + Open (i) + High(i) + Low(i)) / 4;

                                                Note: i should be inside brackets in above equation.

                                                In my main indicator, i change it like this :

                                                double avg = ( iClose(NULL,TimeFrame,i) + iOpen(NULL,TimeFrame,i) + iHigh(NULL,TimeFrame,i) + iLow(NULL,TimeFrame,i) ) / 4;

                                                The TimeFrame here is the variable (can be in a function) passed by other indicator. So, from second (MTF) indicator, i call using iCustom and passing the TF value for each TF i want to calculate.  In this case, even i attach the indicator on TF M15 or M30, i can get the result of average of M1 candle by passing the value of TF to 1 (1 minute for TF M1).
                                                This is useful especially if i want to see the lines / level of TF M1 to MN1 from M15 or other TF where i attach the MTF indicator.

                                                Any body know, is it possible to create some thing like this just using 1 indicator, and without calling iCustom ?

                                                Thanks a lot in advance.

                                                 

                                                • This reply was modified 10 years, 3 months ago by smallcat.
                                                • This reply was modified 10 years, 3 months ago by smallcat.
                                                #10866
                                                smallcat
                                                Participant

                                                  ….  #property strict  ….. Experienced coders see it at a glance, but newbies please take some minutes to think about what’s wrong with the following function contained in this indicator:

                                                  bool LoadMsgArray() {          // Load msgs into array
                                                     ArrayResize(msgArray, 14);   // MT4 Text Handling is all f***ked up!!!  Makes absolutely no sense!
                                                     ArrayResize(clrArray, 14);
                                                     msgArray[1]  = "Ultra Low Volume";
                                                     clrArray[1]  = Red;
                                                     msgArray[2]  = "Low Volume";
                                                     clrArray[2]  = Blue;
                                                     //  ...   etc ...
                                                     msgArray[13] = "Very High Vol < Prev 2";
                                                     clrArray[13] = DarkOrange;
                                                     msgArray[14] = "CAUTION - Ultra High Volume";
                                                     clrArray[14] = Red;
                                                     return(true);
                                                  }

                                                  Hi Simplex, how can you define the  Pre >> Code  format, so we can see the bracket in the post ? This is  a good idea. Using BlockQuote can not show the brackets  of our source code in the post.

                                                  Thanks

                                                  #10867
                                                  bharath4x
                                                  Participant
                                                    
                                                    Hi Smallcat,
                                                    
                                                    We can add html tags like pre, code etc., by changing reply mode to Text (By default, it is in Visual mode).
                                                    
                                                    • This reply was modified 10 years, 3 months ago by bharath4x.
                                                    • This reply was modified 10 years, 3 months ago by bharath4x.
                                                    #10870
                                                    simplex
                                                    Moderator

                                                      @smallcat:

                                                      I found a MTF indicator that is useful to get result on current TF and Bigger TF only, but can not calculate the smaller TF.

                                                      This is not really true. You can calculate values for lower timeframes than shown on chart without any problem. You just can’t visualize those numbers in the way we are used to when looking at MT4 indicators.

                                                      Most simple case: the same timeframe on chart and on indicator (red volume histogram on my pic). We’re used to display a histogram value right below the bar it belongs to (the same value in the time domain). Thats ok, if we do not calculate specials like Ichimoku, or a delayed signal line.

                                                      If we want to calculate our Volume indicator for higher timeframes (blue histo: H1 on a M15 chart) we will usually calculate the indicator value for that higher timeframe and display it under ALL bars that relate to this time period on lower timeframe. In our example: each H1 time interval will show 4 identical volume values, the total tick volume of that H1 bar (let’s leave aside here whether it would make sense to divide this volume by 4).

                                                      Now for the other way round: M15 chart, and we want our volume indicator to show M5 values. We can calculate these values easily, but how would we visualize them? Under each bar, we would have to place 3 volume values. This would break the ‘usual’ way of displaying indicators. That’s why you will hardly find such indicators.

                                                      So most indicators labeled MTF multi timeframe are indeed HTF high timeframe indicators.

                                                      I’ll attach a simple HTF volume, just as an example of how to code such an indicator without utilizing iCustom calls. As you can see when reviewing my code, the OnCalculate() function is simple and clean, just as it should be. The only difference here as compared to a simple volume on current timeframe is to calculate which bar index on higher timeframe relates to the bar shift on current timeframe: shiftHTF = getHtfShift(symb, ctf, htf, shift); That’s all.

                                                      The rest of HTF calculation is done in OnInit(). Here we check and set the working timeframe, and we check whether a sufficient number of bars is available on current and higher timeframe. It’s as simple as that.

                                                      There are different ways to code HTF indicators, this one is just my personal preference. Would be interested in your solutions and why you would prefer those!

                                                      s.

                                                      Attachments:
                                                      You must be logged in to view attached files.

                                                      A good trader is a realist who wants to grab a chunk from the body of a trend, leaving top- and bottom-fishing to people on an ego trip. (Dr. Alexander Elder)

                                                    Viewing 25 posts - 51 through 75 (of 81 total)
                                                    • You must be logged in to reply to this topic.
                                                    Scroll to Top