[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

GEN: Full Moon indicator (EL code) - BUG FIX



PureBytes Links

Trading Reference Links


[This is an update/bug fix to my original post.  Moondays was failing
in certain cases because Tradestation's "mod" function doesn't
handle negative numbers in a methematically correct way.  A new
user function, Modulus is introduced to work around that problem.

Thanks to Frank Chin for his help in beta testing these
functions, and Clyde Lee for pointing out the problem in the
calculation of the mod function.]

Traders, find below an Easy Language implementaiton of a calculation
that approximates the phase of the moon, and an associated indicator
and system.  This calculation isn't as accurate as the method used
by the authors of the TAS&C article, but has the advantages of being
simple and implemented completely in EL.

The Moonphase indicator is useful for giving a visual cue as to
where the market is in the current lunar cycle, and might be combined
with other indicators such as momemtum, or RSI to produce a useful
system.

Have fun with the code, and if you find any problems, or have
suggestions for improvement, I'd like to hear from you.  If
you want to avoid the cut/paste exercise, pick up the
EL archive at ftp://www.intrepid.com/pub/gary/MOON.ELA

howl on,

   - Gary

{
  Function Modulus - this function properly implements the
  modulus function, esp. for negative numbers.  The Tradestation
  "mod" function does not obey the well-accepted mathematical
  definition of modulus, and this function makes up for that.

   
  Author: Gary Funck, gary@xxxxxxxxxxxx, 7/15/97
  No restrictions on use/copying. No warranties, expressed/implied.

}
inputs: x(numericsimple), y(numericsimple);
    if x*y > 0 then Modulus = mod(x, y)
    else Modulus = mod(x,y) + y;

{
  Function Moondays returns the number of days since a new moon.
  The values returned range between 0 and 29.
  (0 = new, and 15 is a full moon to +/- 2 day accuracy.)
  
  Author: Gary Funck, gary@xxxxxxxxxxxx, 7/15/97
  No restrictions on use/copying. No warranties, expressed/implied.

  This code uses an approximation described in the the "Astro FAQ";
  summarized below:

  Subject: C.11  How do I calculate the phase of the moon?
  Author: Bill Jefferys <bill@xxxxxxxxxxxxxxxxxxx>
  
  John Horton Conway (the Princeton mathematician who is responsible for
  "the Game of Life") wrote a book with Guy and Berlekamp, _Winning
  Ways_, that describes in Volume 2 a number of useful calendrical
  rules.  One of these is an easy "in your head" algorithm for
  calculating the phase of the Moon, good to a day or better depending
  on whether you use his refinements or not.
  
  In the 20th century, calculate the remainder upon dividing the
  last two digits of the year by 19; if greater than 9, subtract
  19 from this to get a number between -9 and 9. 
  
  Multiply the result by 11 and reduce modulo 30 to obtain a
  number between -29 and +29.
  
  Add the day of the month and the number of the month (except
  for Jan and Feb use 3 and 4 for the month number instead of
  1 and 2).
  
  Subtract 4.
  
  Reduce modulo 30 to get a number between 0 and 29. This is
  the age of the Moon.
  
  Example: What was the phase of the Moon on D-Day (June 6,
  1944)?
  
  Answer: 44/19=2 remainder 6.
  
  6*11=66, reduce modulo 30 to get 6.
  
  Add 6+6 to this and subtract 4: 6+6+6-4=14; the Moon was (nearly)
  full. I understand that the planners of D-day did care about the phase
  of the Moon, either because of illumination or because of tides. I
  think that Don Olsen recently discussed this in _Sky and Telescope_
  (within the past several years).
  
  In the 21st century use -8.3 days instead of -4 for the last number.
  
  Conway also gives refinements for the leap year cycle and also
  for the slight variations in the lengths of months; what I have
  given should be good to +/- a day or so.
}
inputs: dt(numericsimple);
variables: x1(0), x2(0), x3(0), x4(0);
    x1 = Modulus(year(dt), 19);
    if x1 > 9 then x1 = x1 - 19;
    x2 = Modulus(x1 * 11, 30);
    x3 = month(dt);
    if month(dt) < 3 then x3 = x3 + 2;
    x4 = x2 + dayofmonth(dt) + x3 - 4;
    Moondays = Modulus(x4, 30);

{ 
  Indicator Moonphase, returns a value between 0..100, that
  indicates (approximately) the fullness of the moon, where
  0 is a new moon, and 100 is a full moon.  This indicator
  calls the Moondays function, and is accurate to +/- 2 days.
  
  Accepts an input, offset, which should be in the range -14..14.
  Generally, you will not need to change the offset value, unless
  for example, you want the display to agree with the offset
  value used by Moontrade.

  Author: Gary Funck, gary@xxxxxxxxxxxx, 7/15/97
  No restrictions on use/copying. No warranties, expressed/implied.

}
input: offset(0);
variables:  dt(0), phase(0), mday(0);
    dt = juliantodate(datetojulian(date) + offset);
    mday = Moondays(dt); 
    phase = 100*( mday / 15);
    if phase > 100 then phase = 200 - phase;
    plot1(phase, "moon phase");


{ 
  System Moontrade - buy the new moon, and sell the full moon.

  Accepts an input, offset,  which should be in the range -14..14.
  If the offset is +1, then the system buys at the open of the
  day of a new moon and sells at the open on the day of the full moon.

  Try optimizing the 'offset' (using a range -14..14 in steps
  of 1), or changing the system to only buy the new moon and
  go flat on the full moon, when trading decidedly bullish
  equity indexes.

  Author: Gary Funck, gary@xxxxxxxxxxxx, 7/15/97
  No restrictions on use/copying. No warranties, expressed/implied.

}
input: offset(0);
variables: dt(0), dtnxt(0), mday(0), mdaynxt(0);
variables: new_moon(true), full_moon(false);
    dt = juliantodate(datetojulian(date) + offset);
    dtnxt = juliantodate(datetojulian(date Tomorrow) + offset); 
    mday = Moondays(dt);
    mdaynxt = Moondays(dtnxt);
    new_moon = mdaynxt < mday;
    full_moon = mdaynxt >= 15 and mday < 15;
    if new_moon then buy at market;
    if full_moon then sell at market;

                             -- end --

-- 
--
| Gary Funck,  Intrepid Technology, gary@xxxxxxxxxxxx, (415) 964-8135