Announcement

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

  • Programme error

    Dear All,

    I am trying to write a programme to automatize the trading between two assets. At a certain point the programme is suppose to generate a new variable, "position", which will be different, depending on an option being specified.

    Specifically:

    [CODE]
    capture program drop trading

    program define trading, rclass
    version 15

    syntax varlist(min=2 max=2 numeric) [if], [stop(numlist int max=1)]

    tokenize `varlist'
    local var1="`1'"
    local var2="`2'"

    if "`stop'" != "." {
    tokenize `stop'
    local S="`1'"
    }

    gen spread = ln(`var1') - ln(`var2')
    su spread
    gen z_score = (spread - r(mean)) / r(sd)
    local long_threshold = 1.96
    local short_threshold = -1.96

    gen position = .

    replace position = 1 if z_score > `long_threshold'
    replace position = -1 if z_score < `short_threshold'

    if "`stop'" == "." {
    replace position = 0 if abs(z_score) < 0.05 | sign(z_score) != sign(z_score[_n-1])
    }


    else if "`stop'" != "." {
    replace position = 0 if abs(z_score) < 0.05 | sign(z_score) != sign(z_score[_n-1]) | `stop' > = `S'
    }

    end
    [\CLOSE]

    So if the option stop is not specified, position should be determined by the portion in red. Instead, if the option stop is specified, position should be defined according to the portion of code in green. However I keep receiving an error message, saying that stop is not found. Do you have any suggestion about how to fix this?

    Thanks for any help you may provide.

    Dario



  • #2
    Code:
    . sysuse auto
    (1978 Automobile Data)
    
    . trading price weight
    
        Variable |        Obs        Mean    Std. Dev.       Min        Max
    -------------+---------------------------------------------------------
          spread |         74    .6618814     .346586   .1078574   1.334539
    (74 missing values generated)
    (0 real changes made)
    (0 real changes made)
    invalid syntax
    r(198);
    
    
    . drop spread -poistion
    
    . set trace on
    
    . trading price weight
    ----------------------------------------------------------------------------------------------- begin trading ---
    - version 15
    - syntax varlist(min=2 max=2 numeric) [if], [stop(numlist int max=1)]
    - tokenize `varlist'
    = tokenize price weight
    - local var1="`1'"
    = local var1="price"
    - local var2="`2'"
    = local var2="weight"
    - if "`stop'" != "." {
    = if "" != "." {
    - tokenize `stop'
    = tokenize 
    - local S="`1'"
    = local S=""
    - }
    - gen spread = ln(`var1') - ln(`var2')
    = gen spread = ln(price) - ln(weight)
    - su spread
    
        Variable |        Obs        Mean    Std. Dev.       Min        Max
    -------------+---------------------------------------------------------
          spread |         74    .6618814     .346586   .1078574   1.334539
    - gen z_score = (spread - r(mean)) / r(sd)
    - local long_threshold = 1.96
    - local short_threshold = -1.96
    - gen position = .
    (74 missing values generated)
    - replace position = 1 if z_score > `long_threshold'
    = replace position = 1 if z_score > 1.96
    (0 real changes made)
    - replace position = -1 if z_score < `short_threshold'
    = replace position = -1 if z_score < -1.96
    (0 real changes made)
    - if "`stop'" == "." {
    = if "" == "." {
      replace position = 0 if abs(z_score) < 0.05 | sign(z_score) != sign(z_score[_n-1])
      }
    - else if "`stop'" != "." {
    = else if "" != "." {
    - replace position = 0 if abs(z_score) < 0.05 | sign(z_score) != sign(z_score[_n-1]) | `stop' > = `S'
    = replace position = 0 if abs(z_score) < 0.05 | sign(z_score) != sign(z_score[_n-1]) |  > = 
    invalid syntax
      }
    ------------------------------------------------------------------------------------------------- end trading ---
    r(198);

    Comment


    • #3
      Chen Samulsion Thanks for your reply. Yes, it was clear to me that stop was not found when the code run. But how can I fix this. Stop is just an option that can be included or not. Can you offer me some suggestions about how to fix it?

      Thanks for any help you may provide.

      Dario

      Comment


      • #4
        In the if statement, you will just need to remove the period, i.e. replace with

        Code:
        if "`stop'"  == "" {
        and actually you can just omit the if statement from the else entirely, since the two if statements are mutually exclusive and exhaustive.

        However, you will still get an error from the line
        Code:
        replace position = 0 if abs(z_score) < 0.05 | sign(z_score) != sign(z_score[_n-1]) | `stop' > = `S'
        because of the last condition not evaluating correctly. Could you explain what that last condition is supposed to do?

        Comment


        • #5
          Hemanshu Kumar Thanks for your reply. As I mentioned above, I am using this programme to trade some stocks. The idea of the last condition is to close a trading position if the spread is above a certain treeshold. Just to clarify:

          1) I open the position if spread is larger than +/- 1.96
          2) I close the position if either the spread is lower than 0.05 (1st condition) or the spread changes sign (2nd condition) or the spread is above the value specified in the last condition (say if the spread is +4)- The last condition (and therefore the stop option) may not necessarily be specified.

          Dario

          Comment


          • #6
            Perhaps this:

            Code:
            capture program drop trading
            program define trading, rclass
                version 15
            
                syntax varlist(min=2 max=2 numeric) [if] [in], [STop(numlist int max=1)] SPreadvar(name) Zscore(name) POSvar(name)
            
                marksample touse
                
                tokenize `varlist'
                local var1 = "`1'"
                local var2 = "`2'"
            
                confirm new variable `spreadvar' `zscore' `posvar'
                
                gen `spreadvar' = ln(`var1') - ln(`var2') if `touse'
                su `spreadvar' if `touse'
                gen `zscore' = (`spreadvar' - r(mean)) / r(sd) if `touse'
            
                local long_threshold = 1.96
                local short_threshold = -1.96
            
                gen byte `posvar' = .
            
                replace `posvar' = 1 if `zscore' > `long_threshold' & `touse'
                replace `posvar' = -1 if `zscore' < `short_threshold' & `touse'
            
                if "`stop'" != "" local or_stop_cond " | `zscore' > `stop' "
            
                replace `posvar' = 0 if `touse' & ///
                    (abs(`zscore') < 0.05 | sign(`zscore') != sign(`zscore'[_n-1]) `or_stop_cond')
            end
            You would invoke the program like this:

            Code:
            sysuse auto, clear
            trading price weight, sp(spread) z(z_score) pos(position) stop(4)
            Edit: you may need to decide whether you want the spread, or the absolute value of the spread, to exceed the stop condition. If the latter, you will need to change the local or_stop_cond accordingly.
            Last edited by Hemanshu Kumar; 11 Mar 2025, 07:24.

            Comment


            • #7
              I can't follow what the goal is here. There seems to be some confusion or conflation of z-scores and associated probabilities above and below.

              z-scores more than 1.96 in absolute value are expected to occur 5% of the time in a normal distribution, but z scores less than 0.05 are something else altogether.

              .
              Code:
               mata :  invnormal((0.025, 0.975))
                                1              2
                  +-------------------------------+
                1 |  -1.959963985    1.959963985  |
                  +-------------------------------+
              Last edited by Nick Cox; 11 Mar 2025, 07:29.

              Comment


              • #8
                Detail:

                Code:
                tokenize `varlist'
                local var1 = "`1'"
                local var2 = "`2'"
                can be simplified to


                Code:
                  
                tokenize `varlist'
                args var1 var2      

                Comment


                • #9
                  Originally posted by Nick Cox View Post
                  I can't follow what the goal is here. There seems to be some confusion or conflation of z-scores and associated probabilities above and below.

                  z-scores more than 1.96 in absolute value are expected to occur 5% of the time in a normal distribution, but z scores less than 0.05 are something else altogether.

                  .
                  Code:
                   mata : invnormal((0.025, 0.975))
                  1 2
                  +-------------------------------+
                  1 | -1.959963985 1.959963985 |
                  +-------------------------------+
                  Nick Cox; Hemanshu Kumar Thank you very much for your help. Regarding the point above, basically the idea is that if the spread is larger than +/- 1.96 (but someone suggests even +/-2 or even a lower value) I open the trading position. In In principle the position should be closed when the spread is zero. However it is unlikely that I can observe a spread = 0 using daily data (I would need higher frequency data). Therefore, I set a value of 0.05 (but it could be even lower) to close the trading position. Basically the position is closed when the value of the spread is below 0.05 or the sign of the spread changes, which implies that the spread crossed the 0 line, or when a spread is above/below +/-4, since in that case the position is too risky.

                  Comment

                  Working...
                  X