Who wants a strategy? Lots and for free) - page 58

 
1. I can rewrite the indicators in order to replace float with double.
2. protected static float fMicron = 0.000075f; // Coef used when we compare two floats
3. Indicator Base Constructor:

/// <summary>
/// The default constructor
/// </summary>
public Indicator()
{
    sIndicatorName  = string. Empty;
    bSeparatedChart = false;
    bIsDescreteValues = false;
    afSpecValue     = new float[] { };
    fMinValue       = float. MaxValue;
    fMaxValue       = float. MinValue;
    bIsCalculated   = false;
    parameters      = new IndicatorParam();
    component       = new IndicatorComp[] { };
}




4. Base Price:



/// <summary>
/// Calculates the base price.
/// </summary>
/// <param name="price">The base price type.</param>
/// <returns>Base price.</returns>
protected static float[] Price( BasePrice price)
{
    float[] afPrice = new float[Bars];

    switch( price)
    {
        case BasePrice.Open:
            afPrice = Open;
            break;
        case BasePrice.High:
            afPrice = High;
            break;
        case BasePrice.Low:
            afPrice = Low;
            break;
        case BasePrice.Close:
            afPrice = Close;
            break;
        case BasePrice. Median:
            for (int iBar = 0; iBar < Bars; iBar++)
                afPrice[ iBar] = (Low[ iBar] + High[ iBar]) / 2;
            break;
        case BasePrice. Typical:
            for (int iBar = 0; iBar < Bars; iBar++)
                afPrice[ iBar] = (Low[ iBar] + High[ iBar] + Close[ iBar]) / 3;
            break;
        case BasePrice. Weighted:
            for (int iBar = 0; iBar < Bars; iBar++)
                afPrice[ iBar] = (Low[ iBar] + High[ iBar] + 2 * Close[ iBar]) / 4;
            break;
        default:
            break;
    }
    return afPrice;
}

6. I have got working NET <-> MT bridge. Its metter of time to make FSB trading through MT. Of course it will be for demo accounts only untill became "rock solid".

 

As I think Aroon indicator only uses: bIsDescreteValues = true;


About RSI, I remember I was wondering about the formula. It was 5-6 years ago. I think I used this formula from a popular TA book. Don't remember exactly which one.

 

"Use previous bar value"

I personally think that this is one of the most important features of FSB.


        /// <summary>
        /// Sets the "Use previous bar value" checkbox
        /// </summary>
        /// <returns>Is any Changes</returns>
        public bool SetUsePrevBarValueCheckBox(int iSlot)
        {
            bool isChanged = false;

            for (int iParam = 0; iParam < Slot[ iSlot]. IndParam. CheckParam. Length; iParam++)
            {
                if ( Slot[ iSlot]. IndParam. CheckParam[ iParam]. Caption == "Use previous bar value")
                {
                    bool bOrigChecked = Slot[ iSlot]. IndParam. CheckParam[ iParam]. Checked;
                    bool bChecked = true;

                    // Entry slot
                    if ( Slot[ iSlot]. SlotType == SlotTypes.Open)
                    {
                        bChecked = true;
                    }

                    // Open filter slot
                    else if ( Slot[ iSlot]. SlotType == SlotTypes. OpenFilter)
                    {
                        bChecked = EntryExecutionTime != TimeExecution. Closing;
                    }

                    // Close slot
                    else if ( Slot[ iSlot]. SlotType == SlotTypes.Close)
                    {
                        bChecked = true;
                    }

                    // Close filter slot
                    else if ( Slot[ iSlot]. SlotType == SlotTypes. CloseFilter)
                    {
                        bChecked = false;
                    }

                    if ( bChecked)
                    {
                        for (int iPar = 0; iPar < Slot[ iSlot]. IndParam. ListParam. Length; iPar++)
                        {
                            if ( Slot[ iSlot]. IndParam. ListParam[ iPar]. Caption == "Base price" &&
                                Slot[ iSlot]. IndParam. ListParam[ iPar]. Text    == "Open")
                            {
                                bChecked = false;
                            }
                        }
                    }

                    if ( bChecked != bOrigChecked)
                    {
                        isChanged = true;
                        Slot[ iSlot]. IndParam. CheckParam[ iParam]. Checked = bChecked;
                    }
                }
            }

            return isChanged;
        }
 

To see the indicator values in their full precision press F12 in the chart window.


Another option is to use the "Command Console". ind xxxx shows the indicators for bar xxxx




I don't dig deeply in MT formulas. Probably they are not too much different. Here are the default FSB RSI and MT RSI.







___________________--

Edit:

I tried to calculate RSI without this additional smoothing:

            for (int iBar = 1; iBar < Bars; iBar++)
            {
                if ( afBasePrice[ iBar] > afBasePrice[ iBar - 1]) afPos[ iBar] = afBasePrice[ iBar] - afBasePrice[ iBar - 1];
                if ( afBasePrice[ iBar] < afBasePrice[ iBar - 1]) afNeg[ iBar] = afBasePrice[ iBar - 1] - afBasePrice[ iBar];
            }

            float[] afPosMA = MovingAverage( iPeriod, 0, maMethod, afPos);
            float[] afNegMA = MovingAverage( iPeriod, 0, maMethod, afNeg);

            //for (int iBar = iFirstBar; iBar < Bars; iBar++)
            //{
            //    afPosMA[iBar] = (afPosMA[iBar - 1] * (iPeriod - 1) + afPos[iBar]) / iPeriod;
            //    afNegMA[iBar] = (afNegMA[iBar - 1] * (iPeriod - 1) + afNeg[iBar]) / iPeriod;
            //}

            for (int iBar = iFirstBar; iBar < Bars; iBar++)
            {
                if ( afNegMA[ iBar] == 0)
                    afRSI[ iBar] = 100;
                else
                    afRSI[ iBar] = 100 - (100 / (1 + afPosMA[ iBar] / afNegMA[ iBar]));
            }


But in this case the RSI value for 2009.3.24 jumps to 74.800.



----------------------


Thank you Stellarator for the good words!

I'll not abandon Forex Strategy Builder, and just because of people like you. Even in opposite I'm open for discussion in order to make FSb more robust and user friendly.

In that direction I think I can add MT indicators in FSB. Something like MT compatibility mode:)

MT_MACD, MT_RSI, ... These to be with the same parameters as the MT standard ones.


We have to find solution to Bar Opening and Bar closing entry/exit points. They are vital for FSB -> MT integration.


 
Stellarator >> :

.........Combine them (two buffers) into one (I was thinking... There may be not only 1/0 (which could be turned into a bitmask), but also price tags). Most likely I'll have to do something with the indicator values themselves... We'll see... As I go...

Why can't it work(?).

For a long time I have been using a single icustom call for getting several values from different indicator buffers, it's too wasteful to use this function several times in the code, especially during optimization, and even with "heavy" indicators. In fact, all we need (at most) is to obtain the trade direction and level of SL & TP..... the problem is solved by simple arithmetic.

Here is a fragment of indicator code with only one additional buffer (Signal):

// в самом кончике start такой фрагмент

      
   if ( Direction[0] !=0)
      {
      if ( Direction[0] > 0) Signal[0]= Set_TP[0]/Point*1000000 + Set_SL[0]/Point;
      if ( Direction[0] < 0) Signal[0]=-( Set_TP[0]/Point*1000000 + Set_SL[0]/Point);
      }
   return(0);

And here is the reverse conversion in the Expert Advisor code:

int start()
  {
   // Получение значений из буфера индикатора в последней фазе формирования бара
   if (TimeCurrent() > (Time[0]+ CP60)
      {
      Signal=iCustom(NULL, 0, "_iK_tay_v01M1", Discret,6,0)
      }     

   if(Time[0] != prevtime)
      { 
      Calcul();
      //if (Tral !=0) CalcLevel();
      prevtime = Time[0];
      }
   else return;

.........

void Calcul()
  {
   OpenSell=0; OpenBuy=0; CloseBuy=0; CloseSell=0;
   
   if( Signal > 0) 
      {
      OpenBuy=1; CloseSell=1;
      TP=NormalizeDouble ( Signal*Point/1000000, Digits-1);      
      SL=( Signal- TP/Point*1000000)*Point;   
      }
   if( Signal < 0) 
      {
      CloseBuy=1; OpenSell=1;
      TP=NormalizeDouble (MathAbs( Signal)*Point/1000000, Digits-1);      
      SL=(MathAbs( Signal)- TP/Point*1000000)*Point;   
      }   
   return;
  }

Thus, we get 3 values of the indicator (direction, TP and SL) with a single call of the indicator. The results obtained can be further manipulated as you want :)

I hope you understand the principle.

 

Good morning everyone!


Miroslav_Popov писал(а) >>

1. I can rewrite the indicators in order to replace float with double.

Miroslav - it's important! I've already given some of the reasons in my posts. But I am well aware of the labour involved as well... And that now (most probably) you're working on the bridge you're looking for or something substantial.


But time has to be found. My prediction is no more than some number of hours (within a day). Because it's not just a matter of replacing one by the other when declaring variables (which will also entail at least a visual check and a visual correction "for beauty" (where variables are described with tabs, for example, etc.) :) - although it is not a matter of principle).

First of all, there may well be cases where float is used purposely (to force a decrease in accuracy). You need to see the entire code here.

Secondly, there is a question of comparing such ("new") numbers and their mapping to FSB (about it below, in section 2).

Shorter - we'll need to carefully run through all code and at least think about possible drawbacks associated with the transition of real to double maths.


Miroslav_Popov wrote (a) >>.

2. protected static float fMicron = 0.000075f; // Coef used when we compare two floats


(and below):

To see the indicator values in its full precision press F12 in the chart window.

And this is one of the problems! Why 0.000075? And not 0.00005? Or 0.000001? (as I have).

An extended problem (for those interested) and a question:

As you know, comparison of two real numbers for equality should never be done by such constructions:

double Value1, Value2;

if (Value1 == Value2) {
  // Some useful code there
}

This is because after the results of some calculations (especially variations on multiply/divide), the values of these variables may be visually similar (1.0 and 1.0, for example), but actually NOT the same. (1.000001 and 1.000000, in fact). This property stems from some discreteness of the representation of real numbers in computers and with some (finite) discreteness (accuracy) of computation. In general, the comparison for equality is done by variations on a classical theme (which, by the way, Miroslav uses):

if (Math.Abs(afIndValue[iCurrBar] - afIndValue[iBaseBar]) < fMicron) {
  // Some code there
}

This is the "classic" comparison of two real numbers for equality with some finite precision, defined by fMicron, in this case.


And herein lies one of the potential problems. How, who and for what cases should determine the value of this very fMicron? Is it always a good constant, like Miroslav's (the question of which value is still under discussion, too)?


In general, if not to add intrigue - I'm for the following theory:

1. In general there are two types of comparison of such variables, for equality and for inequality (<, >).

2. There are two types of variables themselves: variables with guaranteed fixed accuracy (prices, lots, etc.), and abstract values without any definite accuracy (like indicator values).

For inequality, variables (of any type) are compared (in general) "head-to-head" (if (Value1 < Value2) { ...}). If it is necessary to limit accuracy (which is quite rare), you can use a construction like Miroslav's:

if (afIndValue[iBaseBar] < afIndValue[iCurrBar] - fMicron) {
  // Some code there
}

4. For equality, however, the problem is (usually) approached differently, depending on the data in question.

4.1 If we need to compare two numbers with fixed precision (for instance, two price values to decide whether or not to modify the order (to avoid getting a "No Result")), we usually do it that way (also "classic"):

int ComparePriceInt(double Value1, double Value2) {
   Value1 -= Value2;
   Value2 = Point / 2.0;
   if ( Value1 > Value2)
      return(1);
   if ( Value1 < - Value2)
      return(-1);
   return(0);
}

The function is redundant in our case, but that's not the point. The key construct in it is Point / 2.0. It is this fMicron that gives us the required, correct and sufficient calculation accuracy... IN THIS PARTICULAR CASE! When two prices are compared (with the same Digits and, consequently, Point ). i.e. in the case of (Point = 0.0001), for example

fMicron = 0.00005

and comparing 1.2345 (order price) with 1.23451 (indicator value) - we obtain equality, and 1.2345 with 1.23456 - inequality... Guess what happens in the last case when fMicron = 0.000075? ;) You could, of course, pre-normalise the variables to one (lower) accuracy. But that's not our method :D...

Once again - the choice of this parameter is important, and for each case "a little bit unique" :)1


I would suggest the following paradigm:

1. Fixed-precision variables are compared with a calculated fMicron value (Point / 2, e.g. for the price case)

2. Values of indicators and other similar "infinitely accurate trifles" :), are compared to the fMicron constant which is equal to the minimum value of Point, used instruments, divided by 10. I.e. in the case of instruments where Digits does not exceed 4 - fMicron = 0.00001, if Digits = 5, fMicron = 0.000001 and similarly.

Miroslav - expert opinion required :)?!


Now a question for the public:

WHY in all sorts of DataWindow (in MT or in FSB (Indicator Charts)) - indicator values are always displayed with a fixed accuracy (Digits = 4)? And why not 3 decimal places? Or 5, 6, 7, ...? :)?! No, really?

Miroslav had a "hidden feature? ;)) - I mean F12! And in MT what to press?

And in general, well, who defined this constant? (4 decimal places).

My guess is that it is almost directly related to the dimension of incoming quotes (1.2345), for most instruments (someone just filled it in). But it's not a secret that many brokerage companies pass to larger values (5 for example). So why not show the indicator values in the dimensionality, that coincides with the instrument quotes dimension (Digits)?

Or maybe I do not "get" something in principle in the subject (please - someone explain, maybe it's "necessary" because...)!


Miroslav_Popov wrote (a) >>.

3. Indicator Base Constructor:

4. Base Price:

Miroslav, I've understood the code on Source page very well:). I understand well what protected static float[] Price( BasePrice price) does. If this is a hint at the unwieldiness of my code - I answer that I intentionally refused to use additional buffers for storage (in general case - either copies of price buffers or calculated copies of them (Typical, etc.)). And space is saved, and where there are all sorts of Typicals, they ALWAYS need to be calculated!


Here we need to mention the critical difference in approach to calculation of indicator values in FSB and MT:

1. First, at least at the moment - quotes that are loaded in FSB are static, it has once loaded them, calculated ONE time the required indicator values for the entire range of bars and then just "drives" by them, emulating the behavior of the trading robot. Once again, the indicator values are calculated only once, BEFORE running the virtualization of the trading robot. This, in particular, explains the speed of emulation of trading transactions. But the quotes in MT come all the time and the native strategy tester does not see the future, i.e. we have to calculate the indicator values every time. And if I just use Miroslav's approach (whole buffer calculation)... I'll be thrown with rotten eggs :). Therefore, special attention is paid to use IndicatorCounted()! Indicators are calculated with almost maximum possible speed in each case (if all bars need to be counted, or only one). Somewhere, some things can still be optimized, but at your leisure...

2. Therefore, each time (when a new tick comes), it is redundant to generate price values in additional buffers. You have to calculate them all anyway, so let the functions (the same MovingAverage, etc.) do it themselves. It saves space, simplifies logic (no need to analyse every time, which bars should be recalculated in these buffers), and saves speed (even somewhere higher, in general case). "It looks that way to me" (c) Winnie the Pooh


If we are going to discuss my indicator conversions again, perhaps what is important is that I completely preserve the logic of functions (and indicators themselves), but modify it slightly for a specific use case in MT. I also save the order and names of parameters for controlling the indicator itself.

Guys, look at the source code, though. I tried to do "nice" :).


The final idea of my conversion is the following. For example, we have an Opening Point of the Position and three indicators for additional logic. Here is how the code for order placing will look like (well, roughly, of course):

if ( IsSignal(iCustom(NULL, 0, "fsbIndicator1", SLOT_TYPE_LC, Param2, Param3, ..., 0, 0))
    && IsSignal(iCustom(NULL, 0, "fsbIndicator2", SLOT_TYPE_LC, Param2, Param3, ..., 0, 0))
    && IsSignal(iCustom(NULL, 0, "fsbIndicator3", SLOT_TYPE_LC, Param2, Param3, ..., 0, 0)) )
{    
// Открываем длинную позицию (предпоследний 0 в значениях индикаторов - указатель на буфер логики длинных позиций (1, соотв. - на буфер логики коротких))
    // Если у нас значение POP берется из еще одного индикатора, то это значение берется аналогично, только меняется логика поведения индикатора:
    // iCustom(NULL, 0, "fsbIndicator", SLOT_TYPE_POP, Param2, Param3, ..., 0, 0)
}

Something like this. You feed iCustom with your parameter values and wait until they all give a signal. That is all. There is no analysis of indicator values themselves... What for?

Seems nice... or not :)?

 

About the indicators:

About (Aroon and bIsDescreteValues = true;) taken into account.


About RSI...

Miroslav - the construction you are looking for has confused you :). Don't be lazy to put comments around it once again and use the CORRECTLY WORKED indicator to get "matching" values :). Let me remind you - the classic formula for calculating RSI is based on the exponential variety of MA (smoothed, specifically). So, specify this mode of smoothing (smoothed) in the indicator parameters... and you will be "pleasantly surprised" by the results :) (by default, I remind you, Simple is used, which gives a divergence from the classic)! I can't do the above procedure myself - but I'm 100% sure of what I'm saying. Convince me :)?

As a result of tests we have the following suggestion, to remove the required code and make default value of maMethod parameter in Smoothed in all indicators, that use RSI (and RSI itself, respectively). That by default the users would not have such questions. But by doing so we will make the selection of this parameter in the indicators WORKABLE! (for example I have converted RSI MA Oscillator, which, based on the result of RSI calculations, also, with the current behavior of RSI itself - it does not matter what is specified in the appropriate parameter)

 
Miroslav_Popov >> :

"Use previous bar value"

I personally think that this is one of the most important features of FSB.

OH, YES!

It really is one of the most important features of FSB. And I've tried to pay proper attention to testing the correctness of indicator logic, considering this feature.

Thanks for the code showing the "default" value calculation! Will take it into account...

 
rider >> :

Why it can't work(?).

For a long time I've been using a single icustom call to get several values from different indicator buffers, it's too wasteful to use this function several times in the code, especially during optimization, and even with "heavy" indices. In fact, all we need (at most) is to get a trading direction and SL & TP..... levels the problem is solved by simple arithmetic.

...

The principle, I hope, is clear.




:), you will get it (I intentionally made my statement coarser), I know about problem with collapsing of values into one parameter :). And thanks for the cited code (quick question - have there ever been differences in original values and "subsequently expanded"? all the same double...)

The key question is... IS IT NECESSARY IN THIS PARTICULAR CASE.

There may be two reasons:

1. 1... The purpose of additional buffer utilization (it's important for me) - indicators do not have so many of them. I have enough of them BUT FOR now (i think it's time to use Ishimoku already - and everything will become clear :)))

2. The speed of calling the indicator from its code (your example). My answer is: Not essential! I declare it with all responsibility. Motivation:

With every new tick - you will have to (have to) look into the indicator anyway. Right? (for example - to take prices or something else) Even if not at every tick, but when you need it. The main hint, perhaps, is that a multiple call of iCustom within one iteration of the EA leads to multiple recalculation of the indicator? I'm forced to dissuade you! The key point is "a limit of one iteration of the Expert Advisor". So, within this range, the indicator is calculated ONE time (at its first call)! I declare this with 100% confidence. All subsequent calls don't start() it at all, but only take the necessary values from the necessary buffers. The condition is 100% if the input parameters remain unchanged (except for the buffer and offset). The rule is valid for calculations within the limits of one tool. But I think the principle holds even when iCustom refers to other TFs and tools.


Anyway, I will have a look at the Ishimoku tonight and decide for sure whether I will use two buffers for logic... or one :)

 

Anyway, see you all tonight (went to work).

About the problem.

We have to find solution to Bar Opening and Bar closing entry/exit points. They are vital for FSB -> MT integration.

I'll think about it.


But most likely (given the lack of signals from MT on this topic) - the above code (template on the previous page) is more or less optimal (may need a little fine-tuning... I'll try to "deepen" the problem in the evening)

Reason: