Announcement

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

  • How to clear preserve? "Already preserve error"

    Hi,

    I have been running a piece of code through various universe of assets and I am getting the "already preserved" error only in that 1 dataset. How can I "clear" preserve once restored and avoid this error?


    Here are the 2 datasets I am considering here:

    This is "Current_orders_M1.dta":
    Code:
     
     * Example generated by -dataex-. To install: ssc install dataex clear input float M str31 Name str6 Code float(date crisis) double P float(F1_P rank_long rank_short) str4 order 1 "KOHL'S"                     "325849" 667 1    19.04 .   1 487 "BUY"  1 "RALPH LAUREN CL.A"          "894145" 667 1     71.3 .   2 486 "BUY"  1 "NORWEGIAN CRUISE LINE HDG." "77444J" 667 1    13.64 .   3 485 "BUY"  1 "CARNIVAL"                   "755695" 667 1    13.88 .   4 484 "BUY"  1 "MARATHON OIL"               "544682" 667 1     5.49 .   5 483 "BUY"  1 "COTY CL.A"                  "87310L" 667 1     3.71 .   6 482 "BUY"  1 "ROYAL CARIBBEAN CRUISES"    "322549" 667 1    48.71 .   7 481 "BUY"  1 "NATIONAL OILWELL VARCO"     "884383" 667 1    11.51 .   8 480 "BUY"  1 "H&R BLOCK"                  "905596" 667 1     14.5 .   9 479 "BUY"  1 "DELTA AIR LINES"            "50469N" 667 1    24.97 .  10 478 "BUY"  1 "DEXCOM"                     "30241D" 667 1   435.54 . 478  10 "SELL" 1 "LAM RESEARCH"               "946387" 667 1 377.1599 . 479   9 "SELL" 1 "GLOBAL PAYMENTS"            "13471D" 667 1   178.02 . 480   8 "SELL" 1 "NVIDIA"                     "694405" 667 1 424.5901 . 481   7 "SELL" 1 "CENTENE"                    "14863U" 667 1    65.25 . 482   6 "SELL" 1 "PAYPAL HOLDINGS"            "9801CK" 667 1   196.07 . 483   5 "SELL" 1 "BRISTOL MYERS SQUIBB"       "905080" 667 1    58.66 . 484   4 "SELL" 1 "T-MOBILE US"                "50394K" 667 1   107.38 . 485   3 "SELL" 1 "APPLE"                      "992816" 667 1   425.04 . 486   2 "SELL" 1 "NEWMONT"                    "912160" 667 1     69.2 . 487   1 "SELL" end format %tm date
    This is the second:
    "Current_orders_M2.dta"
    Code:
     
     * Example generated by -dataex-. To install: ssc install dataex clear input float M str31 Name str6 Code float(date crisis) double P float(F1_P rank_long rank_short) str4 order 2 "H&R BLOCK"              "905596" 667 1     14.5 .   1 487 "BUY"  2 "NORTONLIFELOCK"         "541900" 667 1    21.45 .   2 486 "BUY"  2 "RALPH LAUREN CL.A"      "894145" 667 1     71.3 .   3 485 "BUY"  2 "MARATHON OIL"           "544682" 667 1     5.49 .   4 484 "BUY"  2 "CABOT OIL & GAS 'A'"    "542823" 667 1     18.7 .   5 483 "BUY"  2 "CARNIVAL"               "755695" 667 1    13.88 .   6 482 "BUY"  2 "LIVE NATION ENTM."      "32521X" 667 1    46.81 .   7 481 "BUY"  2 "FORD MOTOR"             "902230" 667 1     6.61 .   8 480 "BUY"  2 "ROLLINS"                "905652" 667 1     52.4 .   9 479 "BUY"  2 "FLIR SYSTEMS"           "329097" 667 1    41.66 .  10 478 "BUY"  2 "MARRIOTT INTL.'A'"      "677631" 667 1   83.825 . 478  10 "SELL" 2 "FEDEX"                  "951849" 667 1    168.4 . 479   9 "SELL" 2 "BROADCOM"               "54332K" 667 1   316.75 . 480   8 "SELL" 2 "APACHE"                 "921983" 667 1    15.35 . 481   7 "SELL" 2 "BERKSHIRE HATHAWAY 'B'" "874227" 667 1   195.78 . 482   6 "SELL" 2 "VIACOMCBS B"            "32480Q" 667 1    26.07 . 483   5 "SELL" 2 "LAM RESEARCH"           "946387" 667 1 377.1599 . 484   4 "SELL" 2 "ABBVIE"                 "87851X" 667 1    94.91 . 485   3 "SELL" 2 "PHILIP MORRIS INTL."    "51605D" 667 1    76.81 . 486   2 "SELL" 2 "COLGATE-PALM."          "906148" 667 1     77.2 . 487   1 "SELL" end format %tm date
    The piece of code I am running is a bit long, sorry about that:

    Code:
    forvalues t = 1 (1) 2 {
            use Current_orders_M`t'.dta, clear
            di `t'
            
            *local t=1
            *use Current_orders_M1.dta, clear
    
            *** Need to incorporate the actual price here ***
            egen P_max = max(P), by(order)
            * Minimum qty to buy of each stock to have a $ equally weighted portf
            gen qty_min = P_max/P
            gen dol_val_min=qty_min*P
            egen dol_sum_min = sum(dol_val), by(order)
    
            * Actual number of stocks to BUY/SELL depending on the $ amount invested:
            gen portf_val=1000
            gen portf_val_half=portf_val/2
            gen qty_sc =  (portf_val/2)/dol_sum_min
            gen qty_actual= qty_min*qty_sc
            ** Adjust weight actual portfolio
            gen qty_actual_rd=floor(qty_min*qty_sc) if qty_min>15
            replace qty_actual_rd=round(qty_min*qty_sc) if (qty_min>3 & qty_actual_rd==.)
            replace qty_actual_rd=ceil(qty_min*qty_sc) if (qty_actual_rd==.)
            replace qty_actual_rd=1 if qty_actual_rd==0
            gen dol_actual_rd = qty_actual_rd*P
            * Check that the long and short leg add up approximativelly to portf_val
            egen sum_dol_actual_rd = sum(dol_actual_rd), by(order)
    
            * Qty with mg:
            gen mg= 0.5 if order=="BUY"
            replace mg=0.5 if order=="SELL"
            browse Name order P dol_sum_min portf_val_half
            gen mg_dol_sum_min=mg*dol_sum_min
            gen qty_sc_mg = (portf_val/2)/mg_dol_sum_min
            gen qty_mg=qty_min*qty_sc_mg
            gen qty_mg_rd=floor(qty_mg) if qty_mg>15
            replace qty_mg_rd=round(qty_mg) if (qty_mg>3 & qty_mg_rd==.)
            replace qty_mg_rd=ceil(qty_mg) if (qty_mg_rd==.)
            replace qty_mg_rd=1 if qty_mg_rd==0
            gen dol_mg_rd = qty_mg_rd*P
            egen sum_dol_mg_rd=sum(dol_mg_rd), by(order)
            replace sum_dol_mg_rd=sum_dol_mg_rd*mg
    
            di `t'
            di "before preserve"
            preserve
            di "after preserve"
            di `t'
            keep if order=="SELL"
    
    
            * If ACTUAL PORTFOLIO larger than the portfolio half:
            local sum_dol_actual_round = sum_dol_actual_rd[1]
            display `sum_dol_actual_round'
            while (`sum_dol_actual_round' > portf_val_half) {
                foreach n_stocks in 100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10 5 {
                    replace qty_actual_rd=qty_actual_rd-1 if (sum_dol_actual_rd>portf_val_half & qty_actual_rd>`n_stocks')
                    replace dol_actual_rd = qty_actual_rd*P
                    drop sum_dol_actual_rd
                    egen sum_dol_actual_rd=sum(dol_actual_rd), by(order)
                    
                }
                local sum_dol_actual_round = sum_dol_actual_rd[1]
                egen max_qty_actual_rd=max(qty_actual_rd)
                if (sum_dol_actual_rd>portf_val_half & max_qty_actual_rd<6) exit
                drop max_qty_actual_rd
            }
            
            save SELL.dta, replace
            di `t'
            di "before restore"
            restore
            di `t'
            di "after restore"
            ****
            keep if order=="BUY"
    
            append using SELL.dta
    
            
            *** Save the data here in my actual code ***
    }
    This post is related to the following. I have removed undefined macro:
    https://www.statalist.org/forums/for...reserved-error

    Thanks a lot for your help in advance.


  • #2
    In order to make your program run, I replaced the single reference to the variable dol_val - which was missing in both of your example datasets - with the constant value 1 in the single expression in which it appeared. That value was chosen after several other values which did not cause the program to exhibit the problem.

    In the future, please provide fully tested reproducible examples that actually reproduce the problem you are having without requiring further work on the part of those whose help you seek. With 571 posts you should have realized by now that most questions are answered with the hard work of testing and correcting your incorrect code.

    If you look at the output of your program, you will see that the preserved dataset from the t=1 iteration was never restored. Your exit command was run, but rather than cause your do-file to terminate, it seems to simply end the current iteration of the outermost loop. (This is not well documented in [P] exit unfortunately.)

    Place a nonzero return code of your choice on the exit command, and the Stata will exit the do-file with and report the return code.
    Code:
                if (sum_dol_actual_rd>portf_val_half & max_qty_actual_rd<6) {
                    display "bad news"
                    exit 666
                }
    Code:
    bad news
    r(666);
    
    end of do-file
    
    r(666);
    
    .

    Comment


    • #3
      Thanks a lot for looking at the problem William and sorry if the problem was not easy to replicate enough. I am still trying to implement the solution you provided in my actual code.

      "dol_val" should actually be "dol_va_min" in the first part of the code (4th line below):
      Code:
              * Minimum qty to buy of each stock to have a $ equally weighted portf
              gen qty_min = P_max/P
              gen dol_val_min=qty_min*P
              egen dol_sum_min = sum(dol_val_min), by(order)
      I did not see this mistake before because Stata understood (and was right) to interpret it as a shortcut for "dol_val_min" create right above. I am not entirely sure if the problem was from there

      Thanks for suggesting "display "bad news"", that is helpful. I am also trying to rewrite the code in a way that if I exit the while loop , Stata continues to execute the next lines (below) and restore to prevent the "already preserved" error to occur:
      Code:
         
       save SELL.dta, replace         di `t'         di "before restore"         restore
      Would you be able to help me modify the code this way? Thanks, again.

      Comment


      • #4
        Code:
        continue , break
        break execution of the while loop and resume with the following command, see
        Code:
        help continue


        I did not see this mistake before because Stata understood (and was right) to interpret it as a shortcut for "dol_val_min" create right above.
        Always turning off varabbrev will avoid this and other problems
        Code:
        set varabbrev off, permanently

        Comment


        • #5
          William Lisowski
          Your exit command was run, but rather than cause your do-file to terminate, it seems to simply end the current iteration of the outermost loop. (This is not well documented in [P] exit unfortunately.)
          Loops in Stata are very nearly unnamed programs, so the -exit- is exiting the (unnamed) program, namely the loop. This unnamed-program property also explains why loops do not echo their commands even when they are in do-files. The one place where they deviate from this unnamed-program status is that local macros defined outside the loop are known inside the loop, and local macros defined in the body of the loop are known outside the loop.

          This could use some clarification in the official Stata documentation.

          Comment


          • #6
            Thank you so much for the solution Bjarte, it works now!

            And thanks for the clarification Bill.

            Comment

            Working...
            X