Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Repeatedly obtain values after a certain condition holds and ignore observations inbetween

    Hi all! I would really appreciate your help with the following:

    I have obtained buy signals from stock data close prices for every 5 minutes. If a buy signal is triggered, I want to retrieve a sell signal 4 periods later and ignore the signals in between (if at t=4 the signal is "BUY" it needs to be "SELL"). If after the sell signal directly the buy signal still holds, there should be a buy signal again and after 4 periods a sell signal etc. If directly after the buy signal there is (e.g. for a few periods) no buy signal I would want the next buy signal and then 4 periods after the sell signal etc. I have tried using the generate/replace commands, but that sadly doesn't work all the time (still some errors). Is there another way to do this? In addition, if I would want the buy signal to hold for 3 periods before the buy signal is triggered, how does that change the code?

    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input double CLOSE str3 buy_signal
    4346.03 ""
    4344.01 ""
    4360 "BUY"
    4377.84 "BUY"
    4377.59 "BUY"
    4340.01 ""
    4345.31 "BUY"
    4354.9 "BUY"
    4340 ""
    4340 ""
    4340 ""
    4345.95 "BUY"
    4337 ""
    4320.07 ""
    4344.95 "BUY"
    4320.03 ""
    4320.01 ""
    4320 ""
    4318.51 ""
    4325 "BUY"
    end

    Below shows an example how I suppose it would look like with the correct signals (after "//")
    Code:
    * Example generated by -dataex-. To install: ssc install dataex
    clear
    input double CLOSE str3 buy_signal
    4346.03 ""
    4344.01 ""
    4360 "BUY" // "BUY"
    4377.84 "BUY"
    4377.59 "BUY"
    4340.01 ""
    4345.31 "BUY" // "SELL"
    4354.9 "BUY" // "BUY"
    4340 ""
    4340 ""
    4340 ""
    4345.95 "BUY" // "SELL"
    4337 ""
    4320.07 ""
    4344.95 "BUY" // "BUY"
    4320.03 ""
    4320.01 ""
    4320 ""
    4318.51 "" // "SELL"
    4325 "BUY" // "BUY"
    end

    Thank you in advance!


  • #2
    I cannot come up with a solution that avoids looping, but the following should do it. Would be interested to see other suggestions.

    Code:
    * Example generated by -dataex-. For more info, type help dataex
    clear
    input double CLOSE str3 buy_signal
    4346.03 ""  
    4344.01 ""  
       4360 "BUY"
    4377.84 "BUY"
    4377.59 "BUY"
    4340.01 ""  
    4345.31 "BUY"
     4354.9 "BUY"
       4340 ""  
       4340 ""  
       4340 ""  
    4345.95 "BUY"
       4337 ""  
    4320.07 ""  
    4344.95 "BUY"
    4320.03 ""  
    4320.01 ""  
       4320 ""  
    4318.51 ""  
       4325 "BUY"
    end
    
    
    gen seq=sum(sum(buy_signal=="BUY"))==1
    replace seq= seq[_n-1]+1 if sum(sum(buy_signal=="BUY"))>1
    preserve
    keep if buy_signal=="BUY"
    gen s= seq
    gen keep=0
    forval i=1/`=_N'{
        bys keep (seq): replace s = seq- seq[1] if !keep
        keep if !inrange(s, 1, 4)
        replace keep=!s
    }
    tempfile keep
    save `keep'
    restore
    merge 1:1 * using `keep', nogen
    sort seq
    gen wanted= "BUY" if !s
    replace wanted= "SELL" if keep[_n-4]==1
    drop s keep
    Res.:

    Code:
    . l, sep(0)
    
         +-----------------------------------+
         |   CLOSE   buy_si~l   seq   wanted |
         |-----------------------------------|
      1. | 4344.01                0          |
      2. | 4346.03                0          |
      3. |    4360        BUY     1      BUY |
      4. | 4377.84        BUY     2          |
      5. | 4377.59        BUY     3          |
      6. | 4340.01                4          |
      7. | 4345.31        BUY     5     SELL |
      8. |  4354.9        BUY     6      BUY |
      9. |    4340                7          |
     10. |    4340                8          |
     11. |    4340                9          |
     12. | 4345.95        BUY    10     SELL |
     13. |    4337               11          |
     14. | 4320.07               12          |
     15. | 4344.95        BUY    13      BUY |
     16. | 4320.03               14          |
     17. | 4320.01               15          |
     18. |    4320               16          |
     19. | 4318.51               17     SELL |
     20. |    4325        BUY    18      BUY |
         +-----------------------------------+

    Comment


    • #3
      Originally posted by Andrew Musau View Post
      I cannot come up with a solution that avoids looping, but the following should do it. Would be interested to see other suggestions.

      Code:
      * Example generated by -dataex-. For more info, type help dataex
      clear
      input double CLOSE str3 buy_signal
      4346.03 ""
      4344.01 ""
      4360 "BUY"
      4377.84 "BUY"
      4377.59 "BUY"
      4340.01 ""
      4345.31 "BUY"
      4354.9 "BUY"
      4340 ""
      4340 ""
      4340 ""
      4345.95 "BUY"
      4337 ""
      4320.07 ""
      4344.95 "BUY"
      4320.03 ""
      4320.01 ""
      4320 ""
      4318.51 ""
      4325 "BUY"
      end
      
      
      gen seq=sum(sum(buy_signal=="BUY"))==1
      replace seq= seq[_n-1]+1 if sum(sum(buy_signal=="BUY"))>1
      preserve
      keep if buy_signal=="BUY"
      gen s= seq
      gen keep=0
      forval i=1/`=_N'{
      bys keep (seq): replace s = seq- seq[1] if !keep
      keep if !inrange(s, 1, 4)
      replace keep=!s
      }
      tempfile keep
      save `keep'
      restore
      merge 1:1 * using `keep', nogen
      sort seq
      gen wanted= "BUY" if !s
      replace wanted= "SELL" if keep[_n-4]==1
      drop s keep
      Res.:

      Code:
      . l, sep(0)
      
      +-----------------------------------+
      | CLOSE buy_si~l seq wanted |
      |-----------------------------------|
      1. | 4344.01 0 |
      2. | 4346.03 0 |
      3. | 4360 BUY 1 BUY |
      4. | 4377.84 BUY 2 |
      5. | 4377.59 BUY 3 |
      6. | 4340.01 4 |
      7. | 4345.31 BUY 5 SELL |
      8. | 4354.9 BUY 6 BUY |
      9. | 4340 7 |
      10. | 4340 8 |
      11. | 4340 9 |
      12. | 4345.95 BUY 10 SELL |
      13. | 4337 11 |
      14. | 4320.07 12 |
      15. | 4344.95 BUY 13 BUY |
      16. | 4320.03 14 |
      17. | 4320.01 15 |
      18. | 4320 16 |
      19. | 4318.51 17 SELL |
      20. | 4325 BUY 18 BUY |
      +-----------------------------------+
      Hi Andrew! Thank you so much for replying, your solution works! This has helped me a lot. Do you also know how the code changes if I want the "BUY" signal to remain for 2 periods and then the actual "BUY" signal is generated. A short example below:

      Code:
      * Example generated by -dataex-. For more info, type help dataex
      clear
      input double CLOSE str3 buy_signal
      4346.03 ""
      4344.01 ""
      4360 "BUY"
      4377.84 "BUY"
      4377.59 "BUY"    // "BUY" 
      4340.01 ""
      4345.31 "BUY"
      4354.9 "BUY"
      4340 ""             // "SELL"
      4340 ""
      4340 ""
      4345.95 "BUY"
      4337 ""
      4320.07 ""
      4344.95 "BUY"
      4320.03 ""
      4320.01 ""
      4320 ""
      4318.51 ""
      4325 "BUY"
      end

      Comment


      • #4
        Below, sum(buy_signal="BUY") =1 for the first buy signal, 2 for the second, and so on. If picking a particular start point, you need to reflect this in your condition as below. I also create a sorting variable that is different from the sequence variable so as to properly create the sell signal at the final stage. Changes are highlighted in red.


        Code:
        * Example generated by -dataex-. For more info, type help dataex
        clear
        input double CLOSE str3 buy_signal
        4346.03 ""  
        4344.01 ""  
           4360 "BUY"
        4377.84 "BUY"
        4377.59 "BUY"
        4340.01 ""  
        4345.31 "BUY"
         4354.9 "BUY"
           4340 ""  
           4340 ""  
           4340 ""  
        4345.95 "BUY"
           4337 ""  
        4320.07 ""  
        4344.95 "BUY"
        4320.03 ""  
        4320.01 ""  
           4320 ""  
        4318.51 ""  
           4325 "BUY"
        end
        
        gen order=_n
        gen seq= 1 if sum(buy_signal=="BUY")==3 & buy_signal=="BUY"
        replace seq= seq[_n-1]+1 if sum(sum(seq))>1 
        preserve
        keep if buy_signal=="BUY"
        gen s= seq
        gen keep=0
        forval i=1/`=_N'{
            bys keep (seq): replace s = seq- seq[1] if !keep
            keep if !inrange(s, 1, 4)
            replace keep=!s
        }
        tempfile keep
        save `keep'
        restore
        merge 1:1 * using `keep', nogen
        sort order
        gen wanted= "BUY" if !s
        replace wanted= "SELL" if keep[_n-4]==1
        drop s keep order
        Res.:

        Code:
        . l, sep(0)
        
             +-----------------------------------+
             |   CLOSE   buy_si~l   seq   wanted |
             |-----------------------------------|
          1. | 4346.03                .          |
          2. | 4344.01                .          |
          3. |    4360        BUY     .          |
          4. | 4377.84        BUY     .          |
          5. | 4377.59        BUY     1      BUY |
          6. | 4340.01                2          |
          7. | 4345.31        BUY     3          |
          8. |  4354.9        BUY     4          |
          9. |    4340                5     SELL |
         10. |    4340                6          |
         11. |    4340                7          |
         12. | 4345.95        BUY     8      BUY |
         13. |    4337                9          |
         14. | 4320.07               10          |
         15. | 4344.95        BUY    11          |
         16. | 4320.03               12     SELL |
         17. | 4320.01               13          |
         18. |    4320               14          |
         19. | 4318.51               15          |
         20. |    4325        BUY    16      BUY |
             +-----------------------------------+

        Comment


        • #5
          Originally posted by Andrew Musau View Post
          Below, sum(buy_signal="BUY") =1 for the first buy signal, 2 for the second, and so on. If picking a particular start point, you need to reflect this in your condition as below. I also create a sorting variable that is different from the sequence variable so as to properly create the sell signal at the final stage. Changes are highlighted in red.


          Code:
          * Example generated by -dataex-. For more info, type help dataex
          clear
          input double CLOSE str3 buy_signal
          4346.03 ""
          4344.01 ""
          4360 "BUY"
          4377.84 "BUY"
          4377.59 "BUY"
          4340.01 ""
          4345.31 "BUY"
          4354.9 "BUY"
          4340 ""
          4340 ""
          4340 ""
          4345.95 "BUY"
          4337 ""
          4320.07 ""
          4344.95 "BUY"
          4320.03 ""
          4320.01 ""
          4320 ""
          4318.51 ""
          4325 "BUY"
          end
          
          gen order=_n
          gen seq= 1 if sum(buy_signal=="BUY")==3 & buy_signal=="BUY"
          replace seq= seq[_n-1]+1 if sum(sum(seq))>1 
          preserve
          keep if buy_signal=="BUY"
          gen s= seq
          gen keep=0
          forval i=1/`=_N'{
          bys keep (seq): replace s = seq- seq[1] if !keep
          keep if !inrange(s, 1, 4)
          replace keep=!s
          }
          tempfile keep
          save `keep'
          restore
          merge 1:1 * using `keep', nogen
          sort order
          gen wanted= "BUY" if !s
          replace wanted= "SELL" if keep[_n-4]==1
          drop s keep order
          Res.:

          Code:
          . l, sep(0)
          
          +-----------------------------------+
          | CLOSE buy_si~l seq wanted |
          |-----------------------------------|
          1. | 4346.03 . |
          2. | 4344.01 . |
          3. | 4360 BUY . |
          4. | 4377.84 BUY . |
          5. | 4377.59 BUY 1 BUY |
          6. | 4340.01 2 |
          7. | 4345.31 BUY 3 |
          8. | 4354.9 BUY 4 |
          9. | 4340 5 SELL |
          10. | 4340 6 |
          11. | 4340 7 |
          12. | 4345.95 BUY 8 BUY |
          13. | 4337 9 |
          14. | 4320.07 10 |
          15. | 4344.95 BUY 11 |
          16. | 4320.03 12 SELL |
          17. | 4320.01 13 |
          18. | 4320 14 |
          19. | 4318.51 15 |
          20. | 4325 BUY 16 BUY |
          +-----------------------------------+
          Thank you again for helping me!! I tried running the code but the output is not what I had in mind. Maybe my explanation above wasn't clear, sorry! (The first BUY signal generated was correct in your code, but then a BUY signal is generated when there was only one BUY signal and it should be like the way the first BUY signal in your code output). The BUY signal should only occur when in the previous two periods there was a BUY signal, so there is a delay in when the BUY signal is triggered. If the BUY signal only lasts for 1 period it isn't enough to trigger the BUY signal. The second column in the code below (after //) is what should be the output.

          Code:
          * Example generated by -dataex-. To install: ssc install dataex
          clear
          input str3 buy_signal
           
          ""   
          ""   
          ""   
          ""   
          "BUY"
          ""   
          ""   
          ""   
          "BUY"
          ""   
          ""   
          ""   
          ""   
          "BUY"
          "BUY"
          "BUY"      // "BUY"
          "BUY"
          "BUY"
          "BUY"
          "BUY"        // "SELL" 
          "BUY"       
          ""   
          ""   
          "BUY"
          "BUY"
          "BUY"      // "BUY"
          "BUY"
          ""   
          ""   
          ""           // "SELL"
          ""   
          "BUY"
          ""   
          "BUY"   
          ""   
          end

          Comment


          • #6
            (The first BUY signal generated was correct in your code, but then a BUY signal is generated when there was only one BUY signal and it should be like the way the first BUY signal in your code output). The BUY signal should only occur when in the previous two periods there was a BUY signal, so there is a delay in when the BUY signal is triggered. If the BUY signal only lasts for 1 period it isn't enough to trigger the BUY signal. The second column in the code below (after //) is what should be the output.
            You can append the skipping conditions to the loop. Your example seems to start at the 5th buy signal, but you can adjust that easily in the code.

            Code:
            * Example generated by -dataex-. To install: ssc install dataex
            clear
            input str3 buy_signal
             
            ""  
            ""  
            ""  
            ""  
            "BUY"
            ""  
            ""  
            ""  
            "BUY"
            ""  
            ""  
            ""  
            ""  
            "BUY"
            "BUY"
            "BUY"      
            "BUY"
            "BUY"
            "BUY"
            "BUY"      
            "BUY"      
            ""  
            ""  
            "BUY"
            "BUY"
            "BUY"      
            "BUY"
            ""  
            ""  
            ""          
            ""  
            "BUY"
            ""  
            "BUY"  
            ""  
            end
            
            
            gen order=_n
            gen seq= 1 if sum(buy_signal=="BUY")==3 & buy_signal=="BUY"
            replace seq= seq[_n-1]+1 if sum(sum(seq))>1
            preserve
            keep if buy_signal=="BUY" & !missing(seq)
            gen s= seq
            gen keep=0
            forval i=1/`=_N'{
                bys keep (seq): replace s = seq- seq[1] if !keep
                keep if !inrange(s, 1, 4)
                replace keep=!s
                sort keep seq
                forval i=1/3{
                    drop in 1 if !keep
                } 
            }
            tempfile keep
            save `keep'
            restore
            merge 1:1 * using `keep', nogen
            sort order
            gen wanted= "BUY" if !s
            replace wanted= "SELL" if keep[_n-4]==1
            drop s keep order
            Res.:

            Code:
            . l, sep(0)
            
                 +-------------------------+
                 | buy_si~l   seq   wanted |
                 |-------------------------|
              1. |              .          |
              2. |              .          |
              3. |              .          |
              4. |              .          |
              5. |      BUY     .          |
              6. |              .          |
              7. |              .          |
              8. |              .          |
              9. |      BUY     .          |
             10. |              .          |
             11. |              .          |
             12. |              .          |
             13. |              .          |
             14. |      BUY     1      BUY |
             15. |      BUY     2          |
             16. |      BUY     3          |
             17. |      BUY     4          |
             18. |      BUY     5     SELL |
             19. |      BUY     6          |
             20. |      BUY     7          |
             21. |      BUY     8          |
             22. |              9          |
             23. |             10          |
             24. |      BUY    11      BUY |
             25. |      BUY    12          |
             26. |      BUY    13          |
             27. |      BUY    14          |
             28. |             15     SELL |
             29. |             16          |
             30. |             17          |
             31. |             18          |
             32. |      BUY    19          |
             33. |             20          |
             34. |      BUY    21          |
             35. |             22          |
                 +-------------------------+

            Comment


            • #7
              The BUY signal should only occur when in the previous two periods there was a BUY signal, so there is a delay in when the BUY signal is triggered. If the BUY signal only lasts for 1 period it isn't enough to trigger the BUY signal. The second column in the code below (after //) is what should be the output.
              I think I understand what you mean here - the first buy signal should occur in a block of at least 3 consecutive buy signals. Before I amend the code in #6, clarify whether this condition should be strict throughout the dataset or only for the first buy signal? That is, must subsequent buy signals occur in blocks of at least 3 consecutive buy signals?

              Comment


              • #8
                Originally posted by Andrew Musau View Post

                I think I understand what you mean here - the first buy signal should occur in a block of at least 3 consecutive buy signals. Before I amend the code in #6, clarify whether this condition should be strict throughout the dataset or only for the first buy signal? That is, must subsequent buy signals occur in blocks of at least 3 consecutive buy signals?
                Yes, that is correct! Throughout the dataset the buy signals should occur when there is a block of exactly 3 consecutive buy signals. Hence, in the result of your code in #6 the buy signals should be in 16 and 26. In addition, if a sell signal is generated and directly after there are again 3 consecutive buy signals then a buy signal should also occur (e.g. occurs when there is a super long period of consecutive buy signals). Once again, thank you for helping me.

                Comment


                • #9
                  Alright, thanks.

                  Code:
                  * Example generated by -dataex-. To install: ssc install dataex
                  clear
                  input str3 buy_signal
                   
                  ""  
                  ""  
                  ""  
                  ""  
                  "BUY"
                  ""  
                  ""  
                  ""  
                  "BUY"
                  ""  
                  ""  
                  ""  
                  ""  
                  "BUY"
                  "BUY"
                  "BUY"      
                  "BUY"
                  "BUY"
                  "BUY"
                  "BUY"      
                  "BUY"      
                  ""  
                  ""  
                  "BUY"
                  "BUY"
                  "BUY"      
                  "BUY"
                  ""  
                  ""  
                  ""          
                  ""  
                  "BUY"
                  ""  
                  "BUY"  
                  ""  
                  end
                  
                  
                  
                  gen tag= cond(buy_signal=="BUY" & missing(buy_signal[_n+1])  & (missing(buy_signal[_n-1]) |missing(buy_signal[_n-2])), 1, cond(buy_signal=="BUY" & missing(buy_signal[_n-1])  & (missing(buy_signal[_n+1]) |missing(buy_signal[_n+2])), 1, 0))
                  gen new_signal= cond(!tag, buy_signal, "")
                  gen seq= 1 if sum(new_signal=="BUY")==3 & new_signal=="BUY"
                  replace seq= seq[_n-1]+1 if sum(sum(seq))>1
                  gen order=_n
                  preserve
                  keep if new_signal=="BUY" & !missing(seq)
                  gen s= seq
                  gen keep=0
                  forval i=1/`=_N'{
                      bys keep (seq): replace s = seq- seq[1] if !keep
                      keep if !inrange(s, 1, 4)
                      replace keep=!s
                      sort keep seq
                      forval i=1/3{
                          drop in 1 if !keep
                      } 
                  }
                  tempfile keep
                  save `keep'
                  restore
                  merge 1:1 * using `keep', nogen
                  sort order
                  gen wanted= "BUY" if !s
                  replace wanted= "SELL" if keep[_n-4]==1
                  drop s keep order
                  Res.:

                  Code:
                  . l, sep(0)
                  
                       +------------------------------------------+
                       | buy_si~l   tag   new_si~l   seq   wanted |
                       |------------------------------------------|
                    1. |              0                .          |
                    2. |              0                .          |
                    3. |              0                .          |
                    4. |              0                .          |
                    5. |      BUY     1                .          |
                    6. |              0                .          |
                    7. |              0                .          |
                    8. |              0                .          |
                    9. |      BUY     1                .          |
                   10. |              0                .          |
                   11. |              0                .          |
                   12. |              0                .          |
                   13. |              0                .          |
                   14. |      BUY     0        BUY     .          |
                   15. |      BUY     0        BUY     .          |
                   16. |      BUY     0        BUY     1      BUY |
                   17. |      BUY     0        BUY     2          |
                   18. |      BUY     0        BUY     3          |
                   19. |      BUY     0        BUY     4          |
                   20. |      BUY     0        BUY     5     SELL |
                   21. |      BUY     0        BUY     6          |
                   22. |              0                7          |
                   23. |              0                8          |
                   24. |      BUY     0        BUY     9          |
                   25. |      BUY     0        BUY    10          |
                   26. |      BUY     0        BUY    11      BUY |
                   27. |      BUY     0        BUY    12          |
                   28. |              0               13          |
                   29. |              0               14          |
                   30. |              0               15     SELL |
                   31. |              0               16          |
                   32. |      BUY     1               17          |
                   33. |              0               18          |
                   34. |      BUY     1               19          |
                   35. |              0               20          |
                       +------------------------------------------+
                  
                  .

                  Comment


                  • #10
                    Originally posted by Andrew Musau View Post
                    Alright, thanks.

                    Code:
                    * Example generated by -dataex-. To install: ssc install dataex
                    clear
                    input str3 buy_signal
                    
                    ""
                    ""
                    ""
                    ""
                    "BUY"
                    ""
                    ""
                    ""
                    "BUY"
                    ""
                    ""
                    ""
                    ""
                    "BUY"
                    "BUY"
                    "BUY"
                    "BUY"
                    "BUY"
                    "BUY"
                    "BUY"
                    "BUY"
                    ""
                    ""
                    "BUY"
                    "BUY"
                    "BUY"
                    "BUY"
                    ""
                    ""
                    ""
                    ""
                    "BUY"
                    ""
                    "BUY"
                    ""
                    end
                    
                    
                    
                    gen tag= cond(buy_signal=="BUY" & missing(buy_signal[_n+1]) & (missing(buy_signal[_n-1]) |missing(buy_signal[_n-2])), 1, cond(buy_signal=="BUY" & missing(buy_signal[_n-1]) & (missing(buy_signal[_n+1]) |missing(buy_signal[_n+2])), 1, 0))
                    gen new_signal= cond(!tag, buy_signal, "")
                    gen seq= 1 if sum(new_signal=="BUY")==3 & new_signal=="BUY"
                    replace seq= seq[_n-1]+1 if sum(sum(seq))>1
                    gen order=_n
                    preserve
                    keep if new_signal=="BUY" & !missing(seq)
                    gen s= seq
                    gen keep=0
                    forval i=1/`=_N'{
                    bys keep (seq): replace s = seq- seq[1] if !keep
                    keep if !inrange(s, 1, 4)
                    replace keep=!s
                    sort keep seq
                    forval i=1/3{
                    drop in 1 if !keep
                    }
                    }
                    tempfile keep
                    save `keep'
                    restore
                    merge 1:1 * using `keep', nogen
                    sort order
                    gen wanted= "BUY" if !s
                    replace wanted= "SELL" if keep[_n-4]==1
                    drop s keep order
                    Res.:

                    Code:
                    . l, sep(0)
                    
                    +------------------------------------------+
                    | buy_si~l tag new_si~l seq wanted |
                    |------------------------------------------|
                    1. | 0 . |
                    2. | 0 . |
                    3. | 0 . |
                    4. | 0 . |
                    5. | BUY 1 . |
                    6. | 0 . |
                    7. | 0 . |
                    8. | 0 . |
                    9. | BUY 1 . |
                    10. | 0 . |
                    11. | 0 . |
                    12. | 0 . |
                    13. | 0 . |
                    14. | BUY 0 BUY . |
                    15. | BUY 0 BUY . |
                    16. | BUY 0 BUY 1 BUY |
                    17. | BUY 0 BUY 2 |
                    18. | BUY 0 BUY 3 |
                    19. | BUY 0 BUY 4 |
                    20. | BUY 0 BUY 5 SELL |
                    21. | BUY 0 BUY 6 |
                    22. | 0 7 |
                    23. | 0 8 |
                    24. | BUY 0 BUY 9 |
                    25. | BUY 0 BUY 10 |
                    26. | BUY 0 BUY 11 BUY |
                    27. | BUY 0 BUY 12 |
                    28. | 0 13 |
                    29. | 0 14 |
                    30. | 0 15 SELL |
                    31. | 0 16 |
                    32. | BUY 1 17 |
                    33. | 0 18 |
                    34. | BUY 1 19 |
                    35. | 0 20 |
                    +------------------------------------------+
                    
                    .
                    I've used your code on my data but unfortunately the correct 'buy' signals do not always occur. The main error is where there are 4 consecutive buy signals. Sometimes the 'buy' signal is triggered at the first (wrong), and sometimes there are 4 consecutive buy signals and the signal is generated at the 3rd buy signal (correct), so the same consecutive signals sometimes give the correct outcome and sometimes the exact same consecutive signals produce wrong signals. Also, where there are 3 consecutive buy signals, no buy signal is generated. I've tried adjusting the marked lines in your code, but can't figure out where the error is.

                    Comment


                    • #11
                      You need to present a data example that illustrates the problem using dataex as you have done in #1 and #5. If the number of observations required exceeds 100, use the -count()- option of dataex. See

                      Code:
                      help dataex

                      Comment


                      • #12
                        Originally posted by Andrew Musau View Post
                        You need to present a data example that illustrates the problem using dataex as you have done in #1 and #5. If the number of observations required exceeds 100, use the -count()- option of dataex. See

                        Code:
                        help dataex
                        The first block of buy signals generates the correct BUY signal. As you can see in the second block no BUY signal is generated and in the third block the BUY signal is generated on the first buy signal. Sometimes four consecutive blocks produce a BUY signal at the 4th, which should be the third (not in the data example below).

                        Code:
                        * Example generated by -dataex-. To install: ssc install dataex
                        clear
                        input float tag str3 new_signal float seq str4 wanted    
                        0 ""      . ""    
                        0 ""      . ""    
                        0 ""      . ""    
                        1 ""      . ""    
                        0 ""      . ""    
                        0 ""      . ""    
                        0 ""      . ""    
                        0 ""      . ""    
                        0 ""      . ""    
                        0 ""      . ""    
                        0 ""      . ""    
                        0 ""      . ""    
                        0 "BUY"   . ""    
                        0 "BUY"   . ""    
                        0 "BUY"   1 "BUY" 
                        0 "BUY"   2 ""    
                        0 "BUY"   3 ""    
                        0 ""      4 ""    
                        0 ""      5 "SELL"
                        0 ""      6 ""    
                        0 ""      7 ""    
                        0 ""      8 ""    
                        0 ""      9 ""    
                        0 ""     10 ""    
                        0 ""     11 ""    
                        0 ""     12 ""    
                        0 ""     13 ""    
                        0 ""     14 ""    
                        0 ""     15 ""    
                        0 ""     16 ""    
                        0 ""     17 ""    
                        0 ""     18 ""    
                        0 ""     19 ""    
                        0 ""     20 ""    
                        0 ""     21 ""    
                        [..]
                        0 ""    630 ""    
                        0 ""    631 ""    
                        0 ""    632 ""    
                        0 ""    633 ""    
                        0 ""    634 ""    
                        0 ""    635 ""    
                        0 ""    636 ""    
                        0 "BUY" 637 ""    
                        0 "BUY" 638 ""    
                        0 "BUY" 639 ""    
                        0 ""    640 ""    
                        0 ""    641 ""    
                        0 ""    642 ""    
                        0 ""    643 ""    
                        0 ""    644 ""     
                        [..]
                        0 ""    1248 ""    
                        0 ""    1249 ""    
                        0 ""    1250 ""    
                        0 ""    1251 ""    
                        0 ""    1252 ""    
                        0 ""    1253 ""    
                        0 ""    1254 ""    
                        0 ""    1255 ""    
                        0 ""    1256 ""    
                        0 ""    1257 ""    
                        0 ""    1258 ""    
                        0 "BUY" 1259 "BUY" 
                        0 "BUY" 1260 ""    
                        0 "BUY" 1261 ""    
                        0 ""    1262 ""    
                        0 ""    1263 "SELL"
                        0 ""    1264 ""    
                        1 ""    1265 ""    
                        1 ""    1266 ""    
                        0 ""    1267 ""    
                        end

                        Comment


                        • #13
                          I see what the issue is. My code assumes that 3 observations should be deleted immediately following the sell signal, whereas this should be the case only if we are within the same spell. Otherwise, you want the deletion to occur when a new spell begins. In this case, we can avoid looping.


                          Code:
                          * Example generated by -dataex-. For more info, type help dataex
                          clear
                          input str3 buy_signal
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          "BUY"
                          "BUY"
                          "BUY"
                          "BUY"
                          "BUY"
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          "BUY"
                          "BUY"
                          "BUY"
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          "BUY"
                          "BUY"
                          "BUY"
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          ""  
                          end
                          
                          
                          gen order=_n
                          preserve
                          tempfile wanted
                          gen tag=buy_signal=="BUY" & buy_signal[_n-1]==""
                          replace tag= tag[_n-1]+1 if !tag & buy_signal=="BUY"
                          gen group= sum(tag==1) if tag
                          bys group: drop if inlist(tag, 1, 2)
                          bys group (order): replace tag=_n-1
                          gen wanted="BUY" if (!tag|!mod(tag, 8)) &!missing(group)
                          save `wanted'
                          restore
                          merge 1:1 * using `wanted', nogen
                          sort order
                          replace wanted= "SELL" if wanted[_n-4]=="BUY"
                          Res.:

                          Code:
                          . l, sep(0)
                          
                               +-----------------------------------------+
                               | buy_si~l   order   tag   group   wanted |
                               |-----------------------------------------|
                            1. |                1     0       .          |
                            2. |                2     1       .          |
                            3. |                3     2       .          |
                            4. |                4     3       .          |
                            5. |                5     4       .          |
                            6. |                6     5       .          |
                            7. |                7     6       .          |
                            8. |                8     7       .          |
                            9. |                9     8       .          |
                           10. |               10     9       .          |
                           11. |               11    10       .          |
                           12. |               12    11       .          |
                           13. |      BUY      13     .       .          |
                           14. |      BUY      14     .       .          |
                           15. |      BUY      15     0       1      BUY |
                           16. |      BUY      16     1       1          |
                           17. |      BUY      17     2       1          |
                           18. |               18    12       .          |
                           19. |               19    13       .     SELL |
                           20. |               20    14       .          |
                           21. |               21    15       .          |
                           22. |               22    16       .          |
                           23. |               23    17       .          |
                           24. |               24    18       .          |
                           25. |               25    19       .          |
                           26. |               26    20       .          |
                           27. |               27    21       .          |
                           28. |               28    22       .          |
                           29. |               29    23       .          |
                           30. |               30    24       .          |
                           31. |               31    25       .          |
                           32. |               32    26       .          |
                           33. |               33    27       .          |
                           34. |               34    28       .          |
                           35. |               35    29       .          |
                           36. |               36    30       .          |
                           37. |               37    31       .          |
                           38. |               38    32       .          |
                           39. |               39    33       .          |
                           40. |               40    34       .          |
                           41. |               41    35       .          |
                           42. |               42    36       .          |
                           43. |      BUY      43     .       .          |
                           44. |      BUY      44     .       .          |
                           45. |      BUY      45     0       2      BUY |
                           46. |               46    37       .          |
                           47. |               47    38       .          |
                           48. |               48    39       .          |
                           49. |               49    40       .     SELL |
                           50. |               50    41       .          |
                           51. |               51    42       .          |
                           52. |               52    43       .          |
                           53. |               53    44       .          |
                           54. |               54    45       .          |
                           55. |               55    46       .          |
                           56. |               56    47       .          |
                           57. |               57    48       .          |
                           58. |               58    49       .          |
                           59. |               59    50       .          |
                           60. |               60    51       .          |
                           61. |               61    52       .          |
                           62. |      BUY      62     .       .          |
                           63. |      BUY      63     .       .          |
                           64. |      BUY      64     0       3      BUY |
                           65. |               65    53       .          |
                           66. |               66    54       .          |
                           67. |               67    55       .          |
                           68. |               68    56       .     SELL |
                           69. |               69    57       .          |
                           70. |               70    58       .          |
                               +-----------------------------------------+
                          Last edited by Andrew Musau; 09 Aug 2021, 06:23.

                          Comment


                          • #14
                            Originally posted by Andrew Musau View Post
                            I see what the issue is. My code assumes that 3 observations should be deleted immediately following the sell signal, whereas this should be the case only if we are within the same spell. Otherwise, you want the deletion to occur when a new spell begins. In this case, we can avoid looping.


                            Code:
                            * Example generated by -dataex-. For more info, type help dataex
                            clear
                            input str3 buy_signal
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            "BUY"
                            "BUY"
                            "BUY"
                            "BUY"
                            "BUY"
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            "BUY"
                            "BUY"
                            "BUY"
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            "BUY"
                            "BUY"
                            "BUY"
                            ""
                            ""
                            ""
                            ""
                            ""
                            ""
                            end
                            
                            
                            gen order=_n
                            preserve
                            tempfile wanted
                            gen tag=buy_signal=="BUY" & buy_signal[_n-1]==""
                            replace tag= tag[_n-1]+1 if !tag & buy_signal=="BUY"
                            gen group= sum(tag==1) if tag
                            bys group: drop if inlist(tag, 1, 2)
                            bys group (order): replace tag=_n-1
                            gen wanted="BUY" if (!tag|!mod(tag, 8)) &!missing(group)
                            save `wanted'
                            restore
                            merge 1:1 * using `wanted', nogen
                            sort order
                            replace wanted= "SELL" if wanted[_n-4]=="BUY"
                            Res.:

                            Code:
                            . l, sep(0)
                            
                            +-----------------------------------------+
                            | buy_si~l order tag group wanted |
                            |-----------------------------------------|
                            1. | 1 0 . |
                            2. | 2 1 . |
                            3. | 3 2 . |
                            4. | 4 3 . |
                            5. | 5 4 . |
                            6. | 6 5 . |
                            7. | 7 6 . |
                            8. | 8 7 . |
                            9. | 9 8 . |
                            10. | 10 9 . |
                            11. | 11 10 . |
                            12. | 12 11 . |
                            13. | BUY 13 . . |
                            14. | BUY 14 . . |
                            15. | BUY 15 0 1 BUY |
                            16. | BUY 16 1 1 |
                            17. | BUY 17 2 1 |
                            18. | 18 12 . |
                            19. | 19 13 . SELL |
                            20. | 20 14 . |
                            21. | 21 15 . |
                            22. | 22 16 . |
                            23. | 23 17 . |
                            24. | 24 18 . |
                            25. | 25 19 . |
                            26. | 26 20 . |
                            27. | 27 21 . |
                            28. | 28 22 . |
                            29. | 29 23 . |
                            30. | 30 24 . |
                            31. | 31 25 . |
                            32. | 32 26 . |
                            33. | 33 27 . |
                            34. | 34 28 . |
                            35. | 35 29 . |
                            36. | 36 30 . |
                            37. | 37 31 . |
                            38. | 38 32 . |
                            39. | 39 33 . |
                            40. | 40 34 . |
                            41. | 41 35 . |
                            42. | 42 36 . |
                            43. | BUY 43 . . |
                            44. | BUY 44 . . |
                            45. | BUY 45 0 2 BUY |
                            46. | 46 37 . |
                            47. | 47 38 . |
                            48. | 48 39 . |
                            49. | 49 40 . SELL |
                            50. | 50 41 . |
                            51. | 51 42 . |
                            52. | 52 43 . |
                            53. | 53 44 . |
                            54. | 54 45 . |
                            55. | 55 46 . |
                            56. | 56 47 . |
                            57. | 57 48 . |
                            58. | 58 49 . |
                            59. | 59 50 . |
                            60. | 60 51 . |
                            61. | 61 52 . |
                            62. | BUY 62 . . |
                            63. | BUY 63 . . |
                            64. | BUY 64 0 3 BUY |
                            65. | 65 53 . |
                            66. | 66 54 . |
                            67. | 67 55 . |
                            68. | 68 56 . SELL |
                            69. | 69 57 . |
                            70. | 70 58 . |
                            +-----------------------------------------+
                            This part of my data has lots of buy signals. I'm afraid that maybe looping is necessary (?) because in the data sample below in number 64 and 114 (not in 117) there should be a BUY signal. In these cases there should be a BUY signal directly after the SELL signal since there are three consecutive buy signals prior. E.g. 1-10 does that correctly but for 64 and 114 no BUY signal is generated directly after the SELL signal.

                            Code:
                            * Example generated by -dataex-. To install: ssc install dataex
                            clear
                            input float(order tag group) str3 buy_signal_4_001 str4 wanted
                              1  1  . ""    ""    
                              2  2  . ""    ""    
                              3  .  . "BUY" ""    
                              4  .  . "BUY" ""    
                              5  1  1 "BUY" "BUY" 
                              6  2  1 "BUY" ""    
                              7  3  . ""    ""    
                              8  .  . "BUY" ""    
                              9  .  . "BUY" "SELL"
                             10  1  2 "BUY" "BUY" 
                             11  4  . ""    ""    
                             12  5  . ""    ""    
                             13  6  . ""    ""    
                             14  .  . "BUY" "SELL"
                             15  .  . "BUY" ""    
                             16  7  . ""    ""    
                             17  8  . ""    ""    
                             18  .  . "BUY" ""    
                             19  .  . "BUY" ""    
                             20  9  . ""    ""    
                             21 10  . ""    ""    
                             22 11  . ""    ""    
                             23 12  . ""    ""    
                             24  .  . "BUY" ""    
                             25  .  . "BUY" ""    
                             26 13  . ""    ""    
                             27  .  . "BUY" ""    
                             28  .  . "BUY" ""    
                             29  1  6 "BUY" "BUY" 
                             30  2  6 "BUY" ""    
                             31  3  6 "BUY" ""    
                             32 14  . ""    ""    
                             33 15  . ""    "SELL"
                             34 16  . ""    ""    
                             35  .  . "BUY" ""    
                             36  .  . "BUY" ""    
                             37  1  7 "BUY" "BUY" 
                             38  2  7 "BUY" ""    
                             39  3  7 "BUY" ""    
                             40  4  7 "BUY" ""    
                             41 17  . ""    "SELL"
                             42 18  . ""    ""    
                             43  .  . "BUY" ""    
                             44  .  . "BUY" ""    
                             45 19  . ""    ""    
                             46 20  . ""    ""    
                             47 21  . ""    ""    
                             48  .  . "BUY" ""    
                             49  .  . "BUY" ""    
                             50  1  9 "BUY" "BUY" 
                             51  2  9 "BUY" ""    
                             52 22  . ""    ""    
                             53  .  . "BUY" ""    
                             54  .  . "BUY" "SELL"
                             55 23  . ""    ""    
                             56 24  . ""    ""    
                             57  .  . "BUY" ""    
                             58  .  . "BUY" ""    
                             59  1 11 "BUY" "BUY" 
                             60  2 11 "BUY" ""    
                             61  3 11 "BUY" ""    
                             62  4 11 "BUY" ""    
                             63  5 11 "BUY" "SELL"
                             64  6 11 "BUY" ""    
                             65 25  . ""    ""    
                             66 26  . ""    ""    
                             67 27  . ""    ""    
                             68 28  . ""    ""    
                             69  .  . "BUY" ""    
                             70  .  . "BUY" ""    
                             71 29  . ""    ""    
                             72  .  . "BUY" ""    
                             73 30  . ""    ""    
                             74 31  . ""    ""    
                             75  .  . "BUY" ""    
                             76  .  . "BUY" ""    
                             77 32  . ""    ""    
                             78  .  . "BUY" ""    
                             79 33  . ""    ""    
                             80 34  . ""    ""    
                             81  .  . "BUY" ""    
                             82  .  . "BUY" ""    
                             83  1 16 "BUY" "BUY" 
                             84  2 16 "BUY" ""    
                             85  3 16 "BUY" ""    
                             86  4 16 "BUY" ""    
                             87 35  . ""    "SELL"
                             88 36  . ""    ""    
                             89  .  . "BUY" ""    
                             90  .  . "BUY" ""    
                             91 37  . ""    ""    
                             92 38  . ""    ""    
                             93 39  . ""    ""    
                             94  .  . "BUY" ""    
                             95  .  . "BUY" ""    
                             96  1 18 "BUY" "BUY" 
                             97  2 18 "BUY" ""    
                             98  3 18 "BUY" ""    
                             99  4 18 "BUY" ""    
                            100 40  . ""    "SELL"
                            101 41  . ""    ""    
                            102 42  . ""    ""    
                            103 43  . ""    ""    
                            104 44  . ""    ""    
                            105 45  . ""    ""    
                            106 46  . ""    ""    
                            107  .  . "BUY" ""    
                            108  .  . "BUY" ""    
                            109  1 19 "BUY" "BUY" 
                            110  2 19 "BUY" ""    
                            111  3 19 "BUY" ""    
                            112  4 19 "BUY" ""    
                            113  5 19 "BUY" "SELL"
                            114  6 19 "BUY" ""    
                            115  7 19 "BUY" ""    
                            116  8 19 "BUY" ""    
                            117  9 19 "BUY" "BUY" 
                            118 10 19 "BUY" ""    
                            119 11 19 "BUY" ""    
                            120 12 19 "BUY" ""    
                            121 13 19 "BUY" "SELL"
                            122 47  . ""    ""    
                            123 48  . ""    ""    
                            124 49  . ""    ""    
                            125  .  . "BUY" ""    
                            126  .  . "BUY" ""    
                            127 50  . ""    ""    
                            128  .  . "BUY" ""    
                            129  .  . "BUY" ""    
                            130  1 21 "BUY" "BUY" 
                            131 51  . ""    ""    
                            132 52  . ""    ""    
                            133 53  . ""    ""    
                            134  .  . "BUY" "SELL"
                            135  .  . "BUY" ""    
                            136 54  . ""    ""    
                            137  .  . "BUY" ""    
                            138 55  . ""    ""    
                            139 56  . ""    ""    
                            140  .  . "BUY" ""    
                            141  .  . "BUY" ""    
                            142 57  . ""    ""    
                            143  .  . "BUY" ""    
                            144  .  . "BUY" ""    
                            145  1 25 "BUY" "BUY" 
                            146  2 25 "BUY" ""    
                            147  3 25 "BUY" ""    
                            148 58  . ""    ""    
                            149  .  . "BUY" "SELL"
                            150  .  . "BUY" ""    
                            end

                            Comment


                            • #15
                              This part of my data has lots of buy signals. I'm afraid that maybe looping is necessary (?) because in the data sample below in number 64 and 114 (not in 117) there should be a BUY signal.
                              It is not a problem with the code. Look at your example in #5

                              "BUY"
                              "BUY"
                              "BUY" // "BUY"
                              "BUY"
                              "BUY"
                              "BUY"
                              "BUY" // "SELL"
                              "BUY"
                              ""
                              ""
                              "BUY"
                              "BUY"
                              "BUY" // "BUY"
                              "BUY"
                              ""
                              ""
                              "" // "SELL"
                              ""
                              "BUY"
                              ""
                              There is no "BUY" signal for the observation highlighted in red. You need to specify your rules consistently. When do you want to skip 3 observations and when not? Also, what happens if you have the following scenario?

                              "BUY"
                              "BUY"
                              "BUY" // "BUY"
                              ""
                              "BUY"
                              "BUY"
                              "BUY" //= SELL & BUY
                              Notice that the sell and buy signals coincide at the 3rd observation of a new spell. How should this be resolved?

                              Comment

                              Working...
                              X