Statalist


[Date Prev][Date Next][Thread Prev][Thread Next][Date index][Thread index]

RE: st: RE: Local macros and strings: yet another query...


From   "Nick Cox" <[email protected]>
To   <[email protected]>
Subject   RE: st: RE: Local macros and strings: yet another query...
Date   Tue, 24 Jun 2008 17:56:50 +0100

I don't want to sound stupid or repetitious, so I will say this just once more and then shut up on this point. 

I have exactly the same reaction to your latest code example. There is no reason visible to me why you can not define the local Loopstr just before you need it to use it, i.e. immediately after the locals Val1 and Val2 are defined. That definition could involve one or more other loops in principle, although that too seems unnecessary in this case. 
Indeed for your example the local is not needed. 

  sysuse sp500, clear
  
  gen Result = .
  forval t=2/`= _N' {
	local Val1 = close[`t']
    	local Val2 = volume[`t']
	// define and evaluate Loopstr here if needed 	
      myCommand, Opt1(`Val1') Opt(`Val2')
      replace Result = r(myResult) in `t'
      replace close = close[`t'-1] + Result - open  in `t'
      replace volume = volume[`t'-1] - Result + open in `t'
  }

In short, I see no problem here and thus no need for any kind of workaround. 
What is true I think that the peculiar characteristics of local macros have some implications for how best to program with them, which ironically can be most disconcerting to those with substantial experience of other kinds of programming. 

P.S. A small and completely separate issue is that -summarize- is not needed above. 

Nick 
[email protected] 

H�chle, Daniel (MI Switzerland)

Nick and Sergiy,

Thanks again for your help.

Finally, I found a workaround for my problem. The code now looks something like this:

-- snip --

  sysuse sp500, clear
  
  * This is the manual version of the string:
  local ManualStr "myCommand, Opt1(\`Val1') Opt2(\`Val2')"
  
  * Here, the string is replicated by looping through a forval loop:
  local LoopStr "myCommand,"
  forval j=1/2 {
      local LoopStr "`LoopStr' Opt`j'(qq_Val`j'')"        // <-- use qq_ (or another string) rather than \`
  }
  local LoopStr = subinstr("`LoopStr'", "qq_", "\`", .)   // <-- replace "qq_" by "\`". This works.

  * Here is the reason why values Val1 and Val2 cannot be defined in advance:
  gen Result = .
  sum date
  local N=r(N)
  forval t=2/`N' {
	local Val1 = close[`t']
    	local Val2 = volume[`t']
      `LoopStr'    // <-- Evaluation of LoopStr
      replace Result = r(myResult) in `t'
      replace close = close[`t'-1] + Result - open  in `t'
      replace volume = volume[`t'-1] - Result + open in `t'
  }
 
-- snip --

Like this it is sufficient to derive the "LoopStr" only once. Afterwards, "LoopStr" is evaluated for observations t=2,...,`N'.

What for do I need this? I am evaluating several investment strategies. These strategies basically consist of three parts: Trading signal (should I buy or sell a certain asset on a given day t), transaction size (how much to trade), and position size (how much is held by end of the day). The size of the position by end of day t-1 impacts on the trading signal which in turn determines the position size by end of day t. Since there are various signal and position sizing algorithms I am looking at, my backtesting procedure (an ado program) should allow for quite some flexibility. To me an evaluation string (i.e. the "LoopStr") seems like a good idea for implementing such a task. Of course I totally agree with Nick's claim that one should define inputs in advance. However, I could not figure out how to efficiently code this in this specific case.


*
*   For searches and help try:
*   http://www.stata.com/support/faqs/res/findit.html
*   http://www.stata.com/support/statalist/faq
*   http://www.ats.ucla.edu/stat/stata/



© Copyright 1996–2024 StataCorp LLC   |   Terms of use   |   Privacy   |   Contact us   |   What's new   |   Site index