// signal-audit-tool.afl // Part 9 - Challenge: State or Event? // // A diagnosis instrument, not a trading system. Paste the rules under test into // the marked block and it answers the questions that separate a state bug from // an event bug: // // How many bars is each array true? // What is the longest unbroken run of true bars? // Does the array ever become true at all? // How many bars at the left edge are empty rather than false? // // The decisive column is the longest unbroken run. A Buy array whose longest run // is 1 is event-shaped. A Buy array whose longest run is 60 is state-shaped. Two // of the six broken formulas in this challenge are identified by that column // alone, and two more by the "ever true" column. // // Assumptions: // - Replace only the marked block. Everything below it is measurement. // - Counts cover the bars delivered to this run; SetBarsRequired( sbrAll ) // asks for the whole history. // - Run length is measured as "bars since the array was last false". On a // symbol whose Buy array is true from the very first delivered bar, that // count has never been reset, so treat a run length equal to the bar count // as "always true" rather than as a precise measurement. // - The tool describes the arrays. It has no opinion on whether the rule is // a good idea. SetBarsRequired( sbrAll ); // =========================================================================== // The formula under test - replace this block // =========================================================================== Average = MA( Close, 50 ); Buy = Close > Average; Sell = Close < Average; // =========================================================================== // Measurement - leave this alone // =========================================================================== // IsTrue() maps Null to 0 and any non-zero value to 1, so a warm-up Null cannot // poison the counts the way a raw AND would. BuyTrue = IsTrue( Buy ); SellTrue = IsTrue( Sell ); // Bars since the array was last false. On a false bar this is zero, so the // running maximum of it is the longest unbroken true run so far. BuyRun = BarsSince( NOT BuyTrue ); SellRun = BarsSince( NOT SellTrue ); BarsInRange = Cum( 1 ); BuyBars = Cum( BuyTrue ); SellBars = Cum( SellTrue ); LongestBuyRun = Highest( BuyRun ); LongestSellRun = Highest( SellRun ); // How much of the left edge is empty rather than false? A long leading Null run // means a warm-up dependency you may not have noticed. BuyNulls = NullCount( Buy, 1 ); SellNulls = NullCount( Sell, 1 ); Filter = Status( "lastbarinrange" ); AddColumn( BarsInRange, "Bars in range", 1.0 ); AddColumn( BuyBars, "Bars where Buy is true", 1.0 ); AddColumn( LongestBuyRun, "Longest unbroken Buy run", 1.0 ); AddColumn( SellBars, "Bars where Sell is true", 1.0 ); AddColumn( LongestSellRun, "Longest unbroken Sell run", 1.0 ); AddColumn( BuyNulls, "Leading Nulls in Buy", 1.0 ); AddColumn( SellNulls, "Leading Nulls in Sell", 1.0 ); AddColumn( 100 * BuyBars / BarsInRange, "Buy true, % of bars", 1.2 );