Support for custom processor and more threads

Another way to break your nested loop might be to do something similar to this:

if (NullCount(conditionMetaArray) == 0)
{
    break;
}

Or if the content of the condition array isn't sufficient to know when it's "done", you could add an output variable to the calculate() function that indicates completion.

Your suggestion is completely WRONG but hilarious.

if( array[ 5 ] ) break;

LOL. There is no way to know which bar to break. :joy:

 if( LastValue( Cum( array ) ) > 0 ) break; 

But that will break the loop for every bar even when that particular bar has not met the condition. :joy::joy:

Attempt at humour? Nice one. :partying_face:

did not know that by converting afl to dll will increase the execution speed

I used it rarely but to give you an idea about potential benefit, see the last post of mine of this old thread (discussing a nested loops solution).

Of course, the performance improvement may vary based on the complexity of your code.

It wasn't "attempt at humour". I was just trying to give you some hints, that it is ALWAYS possible to work with arrays. As in math book, you show simple cases that show the idea. So what was wrong is NOT my answer, but your assumption that "it is not possible". But obviously, if you want help that precisely addresses your problem, you need to describe exactly what you are after. Otherwise it is just guessing game.

Really that is not obstacle. To check if condition was met anywhere the code is equally simple, actually it is pretty the same that I already gave you, as array in previous code can be conditional/logical expression too.

Condition = ....array condition....
if( LastValue( Cum( Condition ) ) > 0 ) break; 

Laughing off help isn't going to get you anywhere nearer to the solution.

2 Likes

@Tomasz TomasZ, Your suggestion is WRONG and RIDICULOUS !!! :see_no_evil:
Give me a solution and I will buy an upgrade that very moment !! I challenge you !
I put my money where my mouth is. Prove it !!!
Below is my redacted code.

swtf_Matrix= MxFromString("{{1, 2, 3, 5, 6, 7, 9, 11, 13, 15, 18, 22, 25, 30, 35}}");

		for( swtf_counter_Matrix=0 ; swtf_counter_Matrix<MxGetSize( swtf_Matrix, 1 )-1 ; swtf_counter_Matrix++ )
        //for( swtf_counter = swtf_counterStartValue; swtf_counter >= swtf_counterEndValue; swtf_counter = swtf_counter - step )
        {
			thisSWTF=swtf_Matrix[0][swtf_counter_Matrix];
            timeIntervalForThisSubwaveForThisIteration =  in1Minute * thisSWTF;
			//swtf_counter=thisSWTF;
            _TRACE( "swtf_counter=" + thisSWTF );
     
            
            //timeIntervalForThisSubwaveForThisIteration = swtf_counter * in1Minute * ;
            timeIntervalForThisSubwaveForThisIterationInSeconds = thisSWTF * 60;
            patternFound_Parent_CompressedToSWTF=TimeFrameCompress( patternFound_Parent_Expanded, timeIntervalForThisSubwaveForThisIteration, compresslast );
            
            //keep the value of last bar in range (because the expanded array 'executeOrNot_Expanded' will have the required value on the very last bar of the range)
			
			
            if( timeIntervalForThisSubwaveForThisIteration < timeframeBaseInSeconds )
            {

                _TRACE( "thisSWTF=" + thisSWTF + ", timeIntervalForThisSubwaveForThisIterationInSeconds" + timeIntervalForThisSubwaveForThisIterationInSeconds + " was less than timeframeBaseInSeconds=" + timeframeBaseInSeconds + ". Hence breaking sw loop" );
                break;

            }

            parentAndSWTFMultiplicationFactor = timeIntervalOfParentPatternInSeconds / timeIntervalForThisSubwaveForThisIteration;


            TimeFrameSet( timeIntervalForThisSubwaveForThisIterationInSeconds );                       
            calculateBarScore();
            //In This SubWave Timeframe

			DateTimeOfThisBarMatchForThisSWForAnySW=DateTimeOfThisBarMatchForThisSW1=DateTimeOfThisBarMatchForThisSW3=DateTimeOfThisBarMatchForThisSW5=0;    
            for(swCounter=swCounterStartValue;swCounter<=swCounterMaxValue;swCounter=swCounter+swCounterStep)
			{


            VarSet("patternFound_SW", Nz(find5LeggedPattern( subwavePatternTypeToFindArray, swlookbackbarsCounterMinValue, swlookbackbarsRange, discoveryModeFindSubWave, DateTimeOfThisBarMatchForThisSWForAnySW)));


            for(swCounter=swCounterStartValue;swCounter<=swCounterMaxValue;swCounter=swCounter+swCounterStep)
			{			
			VarSet("patternFound_SW"+swCounter, VarGet("DateTimeOfThisBarMatchForThisSW"+swCounter) && VarGet("patternFound_SW"));
			fillWaveValues( swCounter,  1);

            timeframerestore();
            //In Base-TimeFrame
            
            VarSet("DateTimeOfThisBarMatchForThisSW"+swCounter+"Expanded", TimeFrameExpand( VarGet("DateTimeOfThisBarMatchForThisSW"+swCounter), timeIntervalForThisSubwaveForThisIteration ));       
            VarSet("DateTimeOfThisBarMatchForThisSWForAnySWExpanded", TimeFrameExpand( DateTimeOfThisBarMatchForThisSWForAnySW, timeIntervalForThisSubwaveForThisIteration ));
            VarSet("subwavePatternTypeToFindArrayExpanded", TimeFrameExpand( subwavePatternTypeToFindArray, timeIntervalForThisSubwaveForThisIteration ));

            VarSet("patternFound_SW"+swCounter+"Expanded", TimeFrameExpand( VarGet("patternFound_SW"+swCounter), timeIntervalForThisSubwaveForThisIteration ));
            VarSet("patternFound_SW"+swCounter+"CompressedToParentTF", TimeFrameCompress( VarGet("patternFound_SW"+swCounter+"Expanded"), timeIntervalOfParentPatternInSeconds, compressHigh ));

            VarSet("Point0_SW"+swCounter+"Expanded", TimeFrameExpand( VarGet("Point0_SW"+swCounter), timeIntervalForThisSubwaveForThisIteration ));
            VarSet("Point0_SW"+swCounter+"ExpandedAndPruned", IIf( VarGet("patternFound_SW"+swCounter+"Expanded"), VarGet("Point0_SW"+swCounter+"Expanded"), Null ));
            VarSet("Point0_SW"+swCounter+"CompressedToParentTF", TimeFrameCompress( VarGet("Point0_SW"+swCounter+"ExpandedAndPruned"), timeIntervalOfParentPatternInSeconds, compressHigh ));

            VarSet("barRefPoint0_SW"+swCounter+"Expanded", TimeFrameExpand( barRefPoint0, timeIntervalForThisSubwaveForThisIteration ));
            VarSet("barRefPoint0_SW"+swCounter+"ExpandedAndPruned", IIf( VarGet("patternFound_SW"+swCounter+"Expanded"), VarGet("barRefPoint0_SW"+swCounter+"Expanded"), Null ));
            VarSet("barRefPoint0_SW"+swCounter+"CompressedToParentTF", TimeFrameCompress( VarGet("barRefPoint0_SW"+swCounter+"ExpandedAndPruned"), timeIntervalOfParentPatternInSeconds, compressHigh ));

            VarSet("winnerLookbackbar_SW"+swCounter+"Expanded", TimeFrameExpand( winnerLookbackbar, timeIntervalForThisSubwaveForThisIteration ));
            VarSet("winnerLookbackbar_SW"+swCounter+"ExpandedAndPruned", IIf( VarGet("patternFound_SW"+swCounter+"Expanded"), VarGet("winnerLookbackbar_SW"+swCounter+"Expanded"), Null ));
            VarSet("winnerLookbackbar_SW"+swCounter+"CompressedToParentTF", TimeFrameCompress( VarGet("winnerLookbackbar_SW"+swCounter+"ExpandedAndPruned"), timeIntervalOfParentPatternInSeconds, compressHigh ));
 

            //determination of ImpulseEndingWithVerifiedSubwave will be done in Parent TF
            TimeFrameSet( timeIntervalOfParentPatternInSeconds );
            effStartBarIndex = getEffectiveStartBarIndx();           



            VarSet("DistanceOfP0OfCorrect_SW"+swCounter, IIf(  VarGet("executeForSW"+swCounter+"InParentTF") , VarGet("DistanceOfCorrect_SW"+swCounter) + Ref( round( VarGet("barRefPoint0_SW"+swCounter+"CompressedToParentTF") / parentAndSWTFMultiplicationFactor ), -1 * VarGet("DistanceOfCorrect_SW"+swCounter) ), VarGet("DistanceOfP0OfCorrect_SW"+swCounter) ));

            VarSet("ParentSubwavePLRatioForSW_"+swCounter, IIf(  VarGet("executeForSW"+swCounter+"InParentTF"), Ref(  VarGet("PriceLength05_SW"+swCounter+"CompressedToParentTF"), -1 * VarGet("DistanceOfCorrect_SW"+swCounter) ) / IIf(swCounter==5, VarGet( "PriceLengthWave5_Parent" ), IIf(swCounter==3, VarGet( "PriceLengthWave3_Parent" ), VarGet( "PriceLengthWave1_Parent" ))), VarGet("ParentSubwavePLRatioForSW_"+swCounter) ) );
            VarSet("ParentBSubwavePLRatioForSW_"+swCounter, IIf(  VarGet("executeForSW"+swCounter+"InParentTF"), Ref( VarGet("PriceLength05_SW"+swCounter+"CompressedToParentTF"), -1 * VarGet("DistanceOfCorrect_SW"+swCounter) ) / IIf(swCounter==5, VarGet( "PriceLengthWave54b_Parent" ), IIf(swCounter==3, VarGet( "PriceLengthWave32b_Parent" ), VarGet( "PriceLengthWave1Nominal_Parent" ))), VarGet("ParentBSubwavePLRatioForSW_"+swCounter) ) );


            VarSet("ImpulseEndingWithVerifiedSubWave"+swCounter+"Found", IIf(  VarGet("executeForSW"+swCounter+"InParentTF"), patternFound_Parent && VarGet("DistanceOfCorrect_SW"+swCounter) <= IIf(swCounter==5, VarGet( "barRefWave5_Parent" ), IIf(swCounter==3, VarGet( "barRefWave3_Parent" ), VarGet( "barRefWave1_Parent" ))) && !IsNull( VarGet("DistanceOfCorrect_SW"+swCounter) ) && IIf( swCounter==5 && VarGet("DistanceOfCorrect_SW"+swCounter) < 0, abs( VarGet("DistanceOfCorrect_SW"+swCounter) ) <= VarGet( "barlength05_Parent" ) / 5, 1 ) && VarGet("ParentBSubwavePLRatioForSW_"+swCounter) >= 5 / 10, VarGet("ImpulseEndingWithVerifiedSubWave"+swCounter+"Found" )));
            


           

            VarSet("ImpulseEndingWithVerifiedSubWave"+swCounter+"FoundExpanded", TimeFrameExpand( VarGet("ImpulseEndingWithVerifiedSubWave"+swCounter+"Found" ), timeIntervalOfParentPatternInSeconds ));
            
            //CODE below is NOT POSSIBLE because VarGet("ImpulseEndingWithVerifiedSubWave"+swCounter+"FoundExpanded") is array and NOT a Scalar. In afl loops can be broken based on scalar NOT based on array
            //For argument lets assume that the concerned array is true at swtf_counter_Matrix=1 (first loop counter) ideally i should come out of the loop but that is not possible due to amibroker architecture And I have to loop through till the very end
            //of the swtf_counter_Matrix i.e swtf_counter_Matrix=35 even though execution till swtf_counter_Matrix=1 was adequate for THAT bar. THIS IS A MAJOR DRAWBACK OF AFL AMIBROKER ARCHITECTURE but one that i have to live with because thats the 
            //way parallelism is achieved. It is not a drawback but a tradeoff.
            
            if(VarGet("ImpulseEndingWithVerifiedSubWave"+swCounter+"FoundExpanded"))
            break;
            
           
			}//sw loop

        }//sw tf loop

I am not here for "challenges" and custom programming is way more costly than price of upgrade. One hour of custom programming costs more than the license upgrade.

What I can do for you is to EXPLAIN how AFL works and HELP you writing your own code correctly. But I don't have time to read spaghetti code. Describe the GOAL and what you have problems with.

Please follow this advice: How to ask a good question

Minimize your code to "Minimum Viable Code" that shows the problem you are having.

General rule for control-flow statements like if/else/switch/break is that decision has to be made as to where code needs to flow. It is like a switch that can be either "on" or "off" . It cannot be in two positions at once. Array on the other hand has multiple values. If it is array of logical values (true/false), it has multiple values and to be able to use it in control flow statement you either need to iterate elements or you have to come up with the rule that makes it possible to make single control flow decision (to go say "left" or "right"). There are many possible transformations that can reduce array to single decision point and it is entirely up to you to use it. So in principle as long as you can reduce array to true/false value using any kind of transformation (as shown in examples above), you can use such reduced value in conditional statement, or you can iterate. On the other hand there is a IIF() function that works entirely on arrays and does not need reduction as it is a kind of "multi-way if-else".

The choice whenever use control-flow statements or array functions like IIF is left to the user as no-one else is able to decide what is best in given case. In AmiBroker you can combine mix/match various programing paradigms. You can use array processing but you can use sequential processing too. Some problems are better solved one way, some another way.

More about that can be read in the manual here:

https://www.amibroker.com/guide/a_mistakes.html

Last but not least, don't use "wrong" and "ridiculous" in the context of somebody trying to help you to understand how the program works because it is rude. You are here to learn, aren't you?

4 Likes

trust me, converting to dll does not solve this

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.