Phase Moon Indicator for ThinkorSwim?

As requested


# Moon Phase
# By Scott Schulz: release 2/5/12

# Purpose: Plot Full Moon and New Moon on price chart

# Moon phase date calculation adapted from Tobias Foerster's
# Excel Funtion to determine Full and New Moon dates

# The Moon Cycle of Earth is approx 29.53 days (synodic month)
# The Moon cycle code is adapted from an Excel function
# TOS Date function starts at 1/1/1970
# Excel dates start at 1/1/1900, therefore a "BaseDayCount"
# is needed to calculate a Excel style serial date.
# "BaseDayCount" is the number of days between 1/1/1900 and 12/31/1969

declare once_per_bar;
declare upper;

# Inputs
input Show_Moons = Yes;
input Show_Date_Bubbles = No;
input Signal_Position = 0.5; #distance from bar where signal is plotted
input Plot_close_on_lower = No;

# Moon phase Constants
def SynodMonth = 29.530588; # original 29.530588
def SynodFullStart = 105.2330205; #original Excel 105.6213922
def SynoNewStart = 120; #original Excel 120.3866862
def BaseDayCount = 25569; # 25568 = 12/31/69, adding 1 (e.g. 25569) increases accuracy in ThinkScript, no idea why

# define week day number
def DayNum = GetDayOfWeek(GetYYYYMMDD()) ; #get weekday number 1-5

# define distance away from low/high to plot signal
def BarHeight = Power(Double.E, Average(Log(Max(high - low, TickSize())), 5));
def SignalLoc1 = BarHeight * Signal_Position;

# determine if today is the last bar plotted (e.g. hard right edge)
def isToday = IsNaN(close[-1]) and !IsNaN(close); # is current bar today, result is T/F

# ---------------------
# Plot close on lower
plot Price = if Plot_close_on_lower then close else Double.NaN;
Price.SetStyle(Curve.FIRM);
Price.SetLineWeight(1);
Price.SetDefaultColor(Color.BLACK);
Price.HideBubble();
Price.HideTitle();

# ---------------------
# Full Moon
# ---------------------
# Identify if FM date is a weekday
def FMTOSSerialDateWD = DaysFromDate(19700101) + BaseDayCount;
def FMserialDateWD = fold FMindexWD = 1237 to 2470 with FMtempWD = 0 while FMTOSSerialDateWD <> FMtempWD do if FMTOSSerialDateWD == Round(SynodFullStart + FMindexWD * SynodMonth, 0) then FMTOSSerialDateWD else 0 ;

# Plot FM weekday
plot FMWD = if Show_Moons and FMserialDateWD > 0 then low - SignalLoc1 else Double.NaN;
FMWD.SetStyle(Curve.POINTS);
FMWD.SetLineWeight(5);
FMWD.SetDefaultColor(Color.DARK_ORANGE);
FMWD.HideBubble();
FMWD.HideTitle();

#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and FMserialDateWD > 0, low - SignalLoc1, Concat(GetMonth(), Concat("/", GetDayOfMonth(GetYYYYMMDD()))), Color.DARK_ORANGE, 0);

# ---------------------
# Identify if FM date is a Saturday
# If FM on Saturday then plot will be on previous Friday
def FMTOSSerialDateSAT = DaysFromDate(19700101) + BaseDayCount + 1;
def FMserialDateSAT = fold FMindexSAT = 1237 to 2470 with FMtempSAT = 0 while FMTOSSerialDateSAT <> FMtempSAT do if FMTOSSerialDateSAT == Round(SynodFullStart + FMindexSAT * SynodMonth, 0) then FMTOSSerialDateSAT else 0;

# Plot FM Saturday
plot FMSAT = if Show_Moons and DayNum == 5 and FMserialDateSAT > 0 and FMserialDateWD <> FMserialDateSAT then low - SignalLoc1 else Double.NaN;
FMSAT.SetStyle(Curve.POINTS);
FMSAT.SetPaintingStrategy(PaintingStrategy.LINE_VS_TRIANGLES);
FMSAT.SetLineWeight(5);
FMSAT.SetDefaultColor(Color.DARK_ORANGE);
FMSAT.HideBubble();
FMSAT.HideTitle();
#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and DayNum == 5 and FMserialDateSAT > 0 and FMserialDateWD <> FMserialDateSAT, low - SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) + 1)), Color.DARK_ORANGE, 0);


# ---------------------
# Identify if FM date is a Sunday
# If FM on Sunday then plot will be on following Monday
# Sunday is tested on the Monday bar and plotted on Monday if True
def FMTOSSerialDateSUN = DaysFromDate(19700101) + BaseDayCount - 1;
def FMserialDateSUN = fold FMindexSUN = 1237 to 2470 with FMtempSUN = 0 while FMTOSSerialDateSUN <> FMtempSUN do if FMTOSSerialDateSUN == Round(SynodFullStart + FMindexSUN * SynodMonth, 0) then FMTOSSerialDateSUN else 0;

# Plot for FM Sunday
plot FMSUN = if Show_Moons and DayNum == 1 and FMserialDateSUN > 0 and FMserialDateWD <> FMserialDateSUN then low - SignalLoc1 else Double.NaN;
FMSUN.SetStyle(Curve.POINTS);
FMSUN.SetPaintingStrategy(PaintingStrategy.LINE_VS_SQUARES);
FMSUN.SetLineWeight(5);
FMSUN.SetDefaultColor(Color.DARK_ORANGE);
FMSUN.HideBubble();
FMSUN.HideTitle();

# Add chart bubble with month / day text
# Becasue Sunday moons are confirmed and plotted on Mondays
# The day of month must be checked, If day = 1 then set month - 1 and
# select last day of previous month to disply in bubble
# Code to determine previous month and then last day of the previous
# month is commented out becasue I have not figured out how to calc
# the last day of the previous month.
#def PrevMonth = If getDayOfMonth(getYyyyMmDd()) == 1 then getLastMonth() else 0;
#def PrevDayPrevMonth = getDayofMonth(); # need to get last day of previous month
# Currently if Sunday is on then first of the month then the bubble will display a
# 0 for the day i.e. 3/0 instead of the desired 2/28
AddChartBubble(Show_Date_Bubbles and DayNum == 1 and FMserialDateSUN > 0 and FMserialDateWD <> FMserialDateSUN, low - SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) - 1)), Color.DARK_ORANGE, 0);

# ---------------------
# Estimate and plot 1 FM date in future
# Days since plot are tracked to estimate position of the
# future FM and NM plot from the last FM plotted
# reset count to 1 each time a FM is plotted and add to count each day not plotted
# the original plan was to plot the next FM using the index (e.g. [-X])
# however [index] does not accept variables, so a chart label
# has been used to state how many days remain until the next FM
# the error margin for this estimate is about +/- 2 days due to weekends
# and then slight error margin in the cycle calculation
rec FMDaysSincePlot = if FMserialDateWD > 0 or DayNum == 5 and FMserialDateSAT > 0 or DayNum == 1 and FMserialDateSUN > 0 then 1 else FMDaysSincePlot[1] + 1;

def FMdayInFut = 22 - FMDaysSincePlot; # number of days from last bar until next FM
AddLabel(yes, Concat (FMdayInFut, " bars until next FM ") , Color.DARK_ORANGE);





# ---------------------
# New Moon
# ---------------------
# Identify if NM date is a weekday
def NMTOSSerialDateWD = DaysFromDate(19700101) + BaseDayCount;
def NMserialDateWD = fold NMindexWD = 1237 to 2470 with NMtempWD = 0 while NMTOSSerialDateWD <> NMtempWD do if NMTOSSerialDateWD == Round(SynoNewStart + NMindexWD * SynodMonth, 0) then FMTOSSerialDateWD else 0 ;

# Plot FM weekday
plot NMWD = if Show_Moons and NMserialDateWD > 0 then high + SignalLoc1 else Double.NaN;
NMWD.SetStyle(Curve.POINTS);
NMWD.SetLineWeight(5);
NMWD.SetDefaultColor(Color.BLACK);
NMWD.HideBubble();
NMWD.HideTitle();

#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and NMserialDateWD > 0, high + SignalLoc1, Concat(GetMonth(), Concat("/", GetDayOfMonth(GetYYYYMMDD()))), Color.BLACK, 1);

# ---------------------
# Identify if NM date is a Saturday
# If NM on Saturday then plot will be on previous Friday
def NMTOSSerialDateSAT = DaysFromDate(19700101) + BaseDayCount + 1;
def NMserialDateSAT = fold NMindexSAT = 1237 to 2470 with NMtempSAT = 0 while NMTOSSerialDateSAT <> NMtempSAT do if NMTOSSerialDateSAT == Round(SynoNewStart + NMindexSAT * SynodMonth, 0) then NMTOSSerialDateSAT else 0;

# Plot FM Saturday
plot NMSAT = if Show_Moons and DayNum == 5 and NMserialDateSAT > 0 and NMserialDateWD <> NMserialDateSAT then high + SignalLoc1 else Double.NaN;
NMSAT.SetStyle(Curve.POINTS);
NMSAT.SetPaintingStrategy(PaintingStrategy.LINE_VS_TRIANGLES);
NMSAT.SetLineWeight(5);
NMSAT.SetDefaultColor(Color.BLACK);
NMSAT.HideBubble();
NMSAT.HideTitle();
#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and DayNum == 5 and NMserialDateSAT > 0 and NMserialDateWD <> NMserialDateSAT, high + SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) + 1)), Color.BLACK, 1);

# ---------------------
# Identify if NM date is a Sunday
# If NM on Sunday then plot will be on following Monday
# Sunday is tested on the Monday bar and plotted on Monday if True
def NMTOSSerialDateSUN = DaysFromDate(19700101) + BaseDayCount - 1;
def NMserialDateSUN = fold NMindexSUN = 1237 to 2470 with NMtempSUN = 0 while NMTOSSerialDateSUN <> NMtempSUN do if NMTOSSerialDateSUN == Round(SynoNewStart + NMindexSUN * SynodMonth, 0) then NMTOSSerialDateSUN else 0;

# Plot for NM Sunday
plot NMSUN = if Show_Moons and DayNum == 1 and NMserialDateSUN > 0 and NMserialDateWD <> NMserialDateSUN then high + SignalLoc1 else Double.NaN;
NMSUN.SetStyle(Curve.POINTS);
NMSUN.SetPaintingStrategy(PaintingStrategy.LINE_VS_SQUARES);
NMSUN.SetLineWeight(5);
NMSUN.SetDefaultColor(Color.BLACK);
NMSUN.HideBubble();
NMSUN.HideTitle();

# Add chart bubble with month / day text
# Becasue Sunday moons are confirmed and plotted on Mondays
# The day of month must be checked, If day = 1 then set month - 1 and
# select last day of previous month to disply in bubble
# Code to determine previous month and then last day of the previous
# month is commented out becasue I have not figured out how to calc
# the last day of the previous month.
#def PrevMonth = If getDayOfMonth(getYyyyMmDd()) == 1 then getLastMonth() else 0;
#def PrevDayPrevMonth = getDayofMonth(); # need to get last day of previous month
# Currently if Sunday is on then first of the month then the bubble will display a
# 0 for the day i.e. 3/0 instead of the desired 2/28
AddChartBubble(Show_Date_Bubbles and DayNum == 1 and NMserialDateSUN > 0 and NMserialDateWD <> NMserialDateSUN, high + SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) - 1)), Color.BLACK, 1);

# ---------------------
# Estimate and plot 1 NM date in future
# Days since plot are tracked to estimate position of the
# future NM plot from the last NM plotted
# reset count to 1 each time a NM is plotted and add to count each day not plotted
# the original plan was to plot the next NM using the index (e.g. [-X])
# however [index] does not accept variables, so a chart label
# has been used to state how many days remain until the next NM
# the error margin for this is estimated about +/- 2 days due to weekends
# and then slight error margin in the cycle calculation
rec NMDaysSincePlot = if NMserialDateWD > 0 or DayNum == 5 and NMserialDateSAT > 0 or DayNum == 1 and NMserialDateSUN > 0 then 1 else NMDaysSincePlot[1] + 1;

def NMdayInFut = 22 - NMDaysSincePlot; # number of days from last bar until next NM
AddLabel(yes, Concat (NMdayInFut, " bars until next NM ") , Color.BLACK);





# ---------------------
# Original Excel function by Tobias Foerster
# ---------------------


#Full Moon Excel Function
# 'Moon Cycle um Erde is approx 29.53 days (synodischer Monat)

# Function IstVollmondtag(Datum As Date) As Boolean
# Const SynodMonat As Double = 29.530588
# Const SynodStart As Double = 105.6213922
# Dim OK As Boolean
# Dim DatumDbl As Double
# Dim DatumLng As Long
# Dim DatumHilf As Date
# Dim i As Long
# If Year(Datum) > 1900 And Year(Datum) < 2100 Then
# OK = False
# For i = 1 To 2470
# DatumDbl = SynodStart + i * SynodMonat
# DatumLng = Int(DatumDbl)
# DatumHilf = CDate(DatumLng)
# If DatumHilf = Datum Then
# OK = True
# Exit For
# End If
# Next i
# Else
# OK = ""
# End If
# IstVollmondtag = OK
# End Function

# New Moon Excel Funcion
# Function IstNeumondTag(Datum As Date) As Boolean
# Const SynodMonat As Double = 29.530588
# Const SynodStart As Double = 120.3866862
# Dim OK As Boolean
# Dim DatumDbl As Double
# Dim DatumLng As Long
# Dim DatumHilf As Date
# Dim i As Long
# If Year(Datum) > 1900 And Year(Datum) < 2100 Then
# OK = False
# For i = 1 To 2470
# DatumDbl = SynodStart + i * SynodMonat
# DatumLng = Int(DatumDbl)
# DatumHilf = CDate(DatumLng)
# If DatumHilf = Datum Then
# OK = True
# Exit For
# End If
# Next i
# Else
# OK = ""
# End If
# IstNeumondTag = OK
# End Function
 
How do you use it? Out of curiosity.
@tomsk
As requested


# Moon Phase
# By Scott Schulz: release 2/5/12

# Purpose: Plot Full Moon and New Moon on price chart

# Moon phase date calculation adapted from Tobias Foerster's
# Excel Funtion to determine Full and New Moon dates

# The Moon Cycle of Earth is approx 29.53 days (synodic month)
# The Moon cycle code is adapted from an Excel function
# TOS Date function starts at 1/1/1970
# Excel dates start at 1/1/1900, therefore a "BaseDayCount"
# is needed to calculate a Excel style serial date.
# "BaseDayCount" is the number of days between 1/1/1900 and 12/31/1969

declare once_per_bar;
declare upper;

# Inputs
input Show_Moons = Yes;
input Show_Date_Bubbles = No;
input Signal_Position = 0.5; #distance from bar where signal is plotted
input Plot_close_on_lower = No;

# Moon phase Constants
def SynodMonth = 29.530588; # original 29.530588
def SynodFullStart = 105.2330205; #original Excel 105.6213922
def SynoNewStart = 120; #original Excel 120.3866862
def BaseDayCount = 25569; # 25568 = 12/31/69, adding 1 (e.g. 25569) increases accuracy in ThinkScript, no idea why

# define week day number
def DayNum = GetDayOfWeek(GetYYYYMMDD()) ; #get weekday number 1-5

# define distance away from low/high to plot signal
def BarHeight = Power(Double.E, Average(Log(Max(high - low, TickSize())), 5));
def SignalLoc1 = BarHeight * Signal_Position;

# determine if today is the last bar plotted (e.g. hard right edge)
def isToday = IsNaN(close[-1]) and !IsNaN(close); # is current bar today, result is T/F

# ---------------------
# Plot close on lower
plot Price = if Plot_close_on_lower then close else Double.NaN;
Price.SetStyle(Curve.FIRM);
Price.SetLineWeight(1);
Price.SetDefaultColor(Color.BLACK);
Price.HideBubble();
Price.HideTitle();

# ---------------------
# Full Moon
# ---------------------
# Identify if FM date is a weekday
def FMTOSSerialDateWD = DaysFromDate(19700101) + BaseDayCount;
def FMserialDateWD = fold FMindexWD = 1237 to 2470 with FMtempWD = 0 while FMTOSSerialDateWD <> FMtempWD do if FMTOSSerialDateWD == Round(SynodFullStart + FMindexWD * SynodMonth, 0) then FMTOSSerialDateWD else 0 ;

# Plot FM weekday
plot FMWD = if Show_Moons and FMserialDateWD > 0 then low - SignalLoc1 else Double.NaN;
FMWD.SetStyle(Curve.POINTS);
FMWD.SetLineWeight(5);
FMWD.SetDefaultColor(Color.DARK_ORANGE);
FMWD.HideBubble();
FMWD.HideTitle();

#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and FMserialDateWD > 0, low - SignalLoc1, Concat(GetMonth(), Concat("/", GetDayOfMonth(GetYYYYMMDD()))), Color.DARK_ORANGE, 0);

# ---------------------
# Identify if FM date is a Saturday
# If FM on Saturday then plot will be on previous Friday
def FMTOSSerialDateSAT = DaysFromDate(19700101) + BaseDayCount + 1;
def FMserialDateSAT = fold FMindexSAT = 1237 to 2470 with FMtempSAT = 0 while FMTOSSerialDateSAT <> FMtempSAT do if FMTOSSerialDateSAT == Round(SynodFullStart + FMindexSAT * SynodMonth, 0) then FMTOSSerialDateSAT else 0;

# Plot FM Saturday
plot FMSAT = if Show_Moons and DayNum == 5 and FMserialDateSAT > 0 and FMserialDateWD <> FMserialDateSAT then low - SignalLoc1 else Double.NaN;
FMSAT.SetStyle(Curve.POINTS);
FMSAT.SetPaintingStrategy(PaintingStrategy.LINE_VS_TRIANGLES);
FMSAT.SetLineWeight(5);
FMSAT.SetDefaultColor(Color.DARK_ORANGE);
FMSAT.HideBubble();
FMSAT.HideTitle();
#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and DayNum == 5 and FMserialDateSAT > 0 and FMserialDateWD <> FMserialDateSAT, low - SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) + 1)), Color.DARK_ORANGE, 0);


# ---------------------
# Identify if FM date is a Sunday
# If FM on Sunday then plot will be on following Monday
# Sunday is tested on the Monday bar and plotted on Monday if True
def FMTOSSerialDateSUN = DaysFromDate(19700101) + BaseDayCount - 1;
def FMserialDateSUN = fold FMindexSUN = 1237 to 2470 with FMtempSUN = 0 while FMTOSSerialDateSUN <> FMtempSUN do if FMTOSSerialDateSUN == Round(SynodFullStart + FMindexSUN * SynodMonth, 0) then FMTOSSerialDateSUN else 0;

# Plot for FM Sunday
plot FMSUN = if Show_Moons and DayNum == 1 and FMserialDateSUN > 0 and FMserialDateWD <> FMserialDateSUN then low - SignalLoc1 else Double.NaN;
FMSUN.SetStyle(Curve.POINTS);
FMSUN.SetPaintingStrategy(PaintingStrategy.LINE_VS_SQUARES);
FMSUN.SetLineWeight(5);
FMSUN.SetDefaultColor(Color.DARK_ORANGE);
FMSUN.HideBubble();
FMSUN.HideTitle();

# Add chart bubble with month / day text
# Becasue Sunday moons are confirmed and plotted on Mondays
# The day of month must be checked, If day = 1 then set month - 1 and
# select last day of previous month to disply in bubble
# Code to determine previous month and then last day of the previous
# month is commented out becasue I have not figured out how to calc
# the last day of the previous month.
#def PrevMonth = If getDayOfMonth(getYyyyMmDd()) == 1 then getLastMonth() else 0;
#def PrevDayPrevMonth = getDayofMonth(); # need to get last day of previous month
# Currently if Sunday is on then first of the month then the bubble will display a
# 0 for the day i.e. 3/0 instead of the desired 2/28
AddChartBubble(Show_Date_Bubbles and DayNum == 1 and FMserialDateSUN > 0 and FMserialDateWD <> FMserialDateSUN, low - SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) - 1)), Color.DARK_ORANGE, 0);

# ---------------------
# Estimate and plot 1 FM date in future
# Days since plot are tracked to estimate position of the
# future FM and NM plot from the last FM plotted
# reset count to 1 each time a FM is plotted and add to count each day not plotted
# the original plan was to plot the next FM using the index (e.g. [-X])
# however [index] does not accept variables, so a chart label
# has been used to state how many days remain until the next FM
# the error margin for this estimate is about +/- 2 days due to weekends
# and then slight error margin in the cycle calculation
rec FMDaysSincePlot = if FMserialDateWD > 0 or DayNum == 5 and FMserialDateSAT > 0 or DayNum == 1 and FMserialDateSUN > 0 then 1 else FMDaysSincePlot[1] + 1;

def FMdayInFut = 22 - FMDaysSincePlot; # number of days from last bar until next FM
AddLabel(yes, Concat (FMdayInFut, " bars until next FM ") , Color.DARK_ORANGE);





# ---------------------
# New Moon
# ---------------------
# Identify if NM date is a weekday
def NMTOSSerialDateWD = DaysFromDate(19700101) + BaseDayCount;
def NMserialDateWD = fold NMindexWD = 1237 to 2470 with NMtempWD = 0 while NMTOSSerialDateWD <> NMtempWD do if NMTOSSerialDateWD == Round(SynoNewStart + NMindexWD * SynodMonth, 0) then FMTOSSerialDateWD else 0 ;

# Plot FM weekday
plot NMWD = if Show_Moons and NMserialDateWD > 0 then high + SignalLoc1 else Double.NaN;
NMWD.SetStyle(Curve.POINTS);
NMWD.SetLineWeight(5);
NMWD.SetDefaultColor(Color.BLACK);
NMWD.HideBubble();
NMWD.HideTitle();

#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and NMserialDateWD > 0, high + SignalLoc1, Concat(GetMonth(), Concat("/", GetDayOfMonth(GetYYYYMMDD()))), Color.BLACK, 1);

# ---------------------
# Identify if NM date is a Saturday
# If NM on Saturday then plot will be on previous Friday
def NMTOSSerialDateSAT = DaysFromDate(19700101) + BaseDayCount + 1;
def NMserialDateSAT = fold NMindexSAT = 1237 to 2470 with NMtempSAT = 0 while NMTOSSerialDateSAT <> NMtempSAT do if NMTOSSerialDateSAT == Round(SynoNewStart + NMindexSAT * SynodMonth, 0) then NMTOSSerialDateSAT else 0;

# Plot FM Saturday
plot NMSAT = if Show_Moons and DayNum == 5 and NMserialDateSAT > 0 and NMserialDateWD <> NMserialDateSAT then high + SignalLoc1 else Double.NaN;
NMSAT.SetStyle(Curve.POINTS);
NMSAT.SetPaintingStrategy(PaintingStrategy.LINE_VS_TRIANGLES);
NMSAT.SetLineWeight(5);
NMSAT.SetDefaultColor(Color.BLACK);
NMSAT.HideBubble();
NMSAT.HideTitle();
#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and DayNum == 5 and NMserialDateSAT > 0 and NMserialDateWD <> NMserialDateSAT, high + SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) + 1)), Color.BLACK, 1);

# ---------------------
# Identify if NM date is a Sunday
# If NM on Sunday then plot will be on following Monday
# Sunday is tested on the Monday bar and plotted on Monday if True
def NMTOSSerialDateSUN = DaysFromDate(19700101) + BaseDayCount - 1;
def NMserialDateSUN = fold NMindexSUN = 1237 to 2470 with NMtempSUN = 0 while NMTOSSerialDateSUN <> NMtempSUN do if NMTOSSerialDateSUN == Round(SynoNewStart + NMindexSUN * SynodMonth, 0) then NMTOSSerialDateSUN else 0;

# Plot for NM Sunday
plot NMSUN = if Show_Moons and DayNum == 1 and NMserialDateSUN > 0 and NMserialDateWD <> NMserialDateSUN then high + SignalLoc1 else Double.NaN;
NMSUN.SetStyle(Curve.POINTS);
NMSUN.SetPaintingStrategy(PaintingStrategy.LINE_VS_SQUARES);
NMSUN.SetLineWeight(5);
NMSUN.SetDefaultColor(Color.BLACK);
NMSUN.HideBubble();
NMSUN.HideTitle();

# Add chart bubble with month / day text
# Becasue Sunday moons are confirmed and plotted on Mondays
# The day of month must be checked, If day = 1 then set month - 1 and
# select last day of previous month to disply in bubble
# Code to determine previous month and then last day of the previous
# month is commented out becasue I have not figured out how to calc
# the last day of the previous month.
#def PrevMonth = If getDayOfMonth(getYyyyMmDd()) == 1 then getLastMonth() else 0;
#def PrevDayPrevMonth = getDayofMonth(); # need to get last day of previous month
# Currently if Sunday is on then first of the month then the bubble will display a
# 0 for the day i.e. 3/0 instead of the desired 2/28
AddChartBubble(Show_Date_Bubbles and DayNum == 1 and NMserialDateSUN > 0 and NMserialDateWD <> NMserialDateSUN, high + SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) - 1)), Color.BLACK, 1);

# ---------------------
# Estimate and plot 1 NM date in future
# Days since plot are tracked to estimate position of the
# future NM plot from the last NM plotted
# reset count to 1 each time a NM is plotted and add to count each day not plotted
# the original plan was to plot the next NM using the index (e.g. [-X])
# however [index] does not accept variables, so a chart label
# has been used to state how many days remain until the next NM
# the error margin for this is estimated about +/- 2 days due to weekends
# and then slight error margin in the cycle calculation
rec NMDaysSincePlot = if NMserialDateWD > 0 or DayNum == 5 and NMserialDateSAT > 0 or DayNum == 1 and NMserialDateSUN > 0 then 1 else NMDaysSincePlot[1] + 1;

def NMdayInFut = 22 - NMDaysSincePlot; # number of days from last bar until next NM
AddLabel(yes, Concat (NMdayInFut, " bars until next NM ") , Color.BLACK);





# ---------------------
# Original Excel function by Tobias Foerster
# ---------------------


#Full Moon Excel Function
# 'Moon Cycle um Erde is approx 29.53 days (synodischer Monat)

# Function IstVollmondtag(Datum As Date) As Boolean
# Const SynodMonat As Double = 29.530588
# Const SynodStart As Double = 105.6213922
# Dim OK As Boolean
# Dim DatumDbl As Double
# Dim DatumLng As Long
# Dim DatumHilf As Date
# Dim i As Long
# If Year(Datum) > 1900 And Year(Datum) < 2100 Then
# OK = False
# For i = 1 To 2470
# DatumDbl = SynodStart + i * SynodMonat
# DatumLng = Int(DatumDbl)
# DatumHilf = CDate(DatumLng)
# If DatumHilf = Datum Then
# OK = True
# Exit For
# End If
# Next i
# Else
# OK = ""
# End If
# IstVollmondtag = OK
# End Function

# New Moon Excel Funcion
# Function IstNeumondTag(Datum As Date) As Boolean
# Const SynodMonat As Double = 29.530588
# Const SynodStart As Double = 120.3866862
# Dim OK As Boolean
# Dim DatumDbl As Double
# Dim DatumLng As Long
# Dim DatumHilf As Date
# Dim i As Long
# If Year(Datum) > 1900 And Year(Datum) < 2100 Then
# OK = False
# For i = 1 To 2470
# DatumDbl = SynodStart + i * SynodMonat
# DatumLng = Int(DatumDbl)
# DatumHilf = CDate(DatumLng)
# If DatumHilf = Datum Then
# OK = True
# Exit For
# End If
# Next i
# Else
# OK = ""
# End If
# IstNeumondTag = OK
# End Function
Thanks @tomsk. Is there any instructions or how to apply this indicator
 
As requested


# Moon Phase
# By Scott Schulz: release 2/5/12

# Purpose: Plot Full Moon and New Moon on price chart

# Moon phase date calculation adapted from Tobias Foerster's
# Excel Funtion to determine Full and New Moon dates

# The Moon Cycle of Earth is approx 29.53 days (synodic month)
# The Moon cycle code is adapted from an Excel function
# TOS Date function starts at 1/1/1970
# Excel dates start at 1/1/1900, therefore a "BaseDayCount"
# is needed to calculate a Excel style serial date.
# "BaseDayCount" is the number of days between 1/1/1900 and 12/31/1969

declare once_per_bar;
declare upper;

# Inputs
input Show_Moons = Yes;
input Show_Date_Bubbles = No;
input Signal_Position = 0.5; #distance from bar where signal is plotted
input Plot_close_on_lower = No;

# Moon phase Constants
def SynodMonth = 29.530588; # original 29.530588
def SynodFullStart = 105.2330205; #original Excel 105.6213922
def SynoNewStart = 120; #original Excel 120.3866862
def BaseDayCount = 25569; # 25568 = 12/31/69, adding 1 (e.g. 25569) increases accuracy in ThinkScript, no idea why

# define week day number
def DayNum = GetDayOfWeek(GetYYYYMMDD()) ; #get weekday number 1-5

# define distance away from low/high to plot signal
def BarHeight = Power(Double.E, Average(Log(Max(high - low, TickSize())), 5));
def SignalLoc1 = BarHeight * Signal_Position;

# determine if today is the last bar plotted (e.g. hard right edge)
def isToday = IsNaN(close[-1]) and !IsNaN(close); # is current bar today, result is T/F

# ---------------------
# Plot close on lower
plot Price = if Plot_close_on_lower then close else Double.NaN;
Price.SetStyle(Curve.FIRM);
Price.SetLineWeight(1);
Price.SetDefaultColor(Color.BLACK);
Price.HideBubble();
Price.HideTitle();

# ---------------------
# Full Moon
# ---------------------
# Identify if FM date is a weekday
def FMTOSSerialDateWD = DaysFromDate(19700101) + BaseDayCount;
def FMserialDateWD = fold FMindexWD = 1237 to 2470 with FMtempWD = 0 while FMTOSSerialDateWD <> FMtempWD do if FMTOSSerialDateWD == Round(SynodFullStart + FMindexWD * SynodMonth, 0) then FMTOSSerialDateWD else 0 ;

# Plot FM weekday
plot FMWD = if Show_Moons and FMserialDateWD > 0 then low - SignalLoc1 else Double.NaN;
FMWD.SetStyle(Curve.POINTS);
FMWD.SetLineWeight(5);
FMWD.SetDefaultColor(Color.DARK_ORANGE);
FMWD.HideBubble();
FMWD.HideTitle();

#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and FMserialDateWD > 0, low - SignalLoc1, Concat(GetMonth(), Concat("/", GetDayOfMonth(GetYYYYMMDD()))), Color.DARK_ORANGE, 0);

# ---------------------
# Identify if FM date is a Saturday
# If FM on Saturday then plot will be on previous Friday
def FMTOSSerialDateSAT = DaysFromDate(19700101) + BaseDayCount + 1;
def FMserialDateSAT = fold FMindexSAT = 1237 to 2470 with FMtempSAT = 0 while FMTOSSerialDateSAT <> FMtempSAT do if FMTOSSerialDateSAT == Round(SynodFullStart + FMindexSAT * SynodMonth, 0) then FMTOSSerialDateSAT else 0;

# Plot FM Saturday
plot FMSAT = if Show_Moons and DayNum == 5 and FMserialDateSAT > 0 and FMserialDateWD <> FMserialDateSAT then low - SignalLoc1 else Double.NaN;
FMSAT.SetStyle(Curve.POINTS);
FMSAT.SetPaintingStrategy(PaintingStrategy.LINE_VS_TRIANGLES);
FMSAT.SetLineWeight(5);
FMSAT.SetDefaultColor(Color.DARK_ORANGE);
FMSAT.HideBubble();
FMSAT.HideTitle();
#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and DayNum == 5 and FMserialDateSAT > 0 and FMserialDateWD <> FMserialDateSAT, low - SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) + 1)), Color.DARK_ORANGE, 0);


# ---------------------
# Identify if FM date is a Sunday
# If FM on Sunday then plot will be on following Monday
# Sunday is tested on the Monday bar and plotted on Monday if True
def FMTOSSerialDateSUN = DaysFromDate(19700101) + BaseDayCount - 1;
def FMserialDateSUN = fold FMindexSUN = 1237 to 2470 with FMtempSUN = 0 while FMTOSSerialDateSUN <> FMtempSUN do if FMTOSSerialDateSUN == Round(SynodFullStart + FMindexSUN * SynodMonth, 0) then FMTOSSerialDateSUN else 0;

# Plot for FM Sunday
plot FMSUN = if Show_Moons and DayNum == 1 and FMserialDateSUN > 0 and FMserialDateWD <> FMserialDateSUN then low - SignalLoc1 else Double.NaN;
FMSUN.SetStyle(Curve.POINTS);
FMSUN.SetPaintingStrategy(PaintingStrategy.LINE_VS_SQUARES);
FMSUN.SetLineWeight(5);
FMSUN.SetDefaultColor(Color.DARK_ORANGE);
FMSUN.HideBubble();
FMSUN.HideTitle();

# Add chart bubble with month / day text
# Becasue Sunday moons are confirmed and plotted on Mondays
# The day of month must be checked, If day = 1 then set month - 1 and
# select last day of previous month to disply in bubble
# Code to determine previous month and then last day of the previous
# month is commented out becasue I have not figured out how to calc
# the last day of the previous month.
#def PrevMonth = If getDayOfMonth(getYyyyMmDd()) == 1 then getLastMonth() else 0;
#def PrevDayPrevMonth = getDayofMonth(); # need to get last day of previous month
# Currently if Sunday is on then first of the month then the bubble will display a
# 0 for the day i.e. 3/0 instead of the desired 2/28
AddChartBubble(Show_Date_Bubbles and DayNum == 1 and FMserialDateSUN > 0 and FMserialDateWD <> FMserialDateSUN, low - SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) - 1)), Color.DARK_ORANGE, 0);

# ---------------------
# Estimate and plot 1 FM date in future
# Days since plot are tracked to estimate position of the
# future FM and NM plot from the last FM plotted
# reset count to 1 each time a FM is plotted and add to count each day not plotted
# the original plan was to plot the next FM using the index (e.g. [-X])
# however [index] does not accept variables, so a chart label
# has been used to state how many days remain until the next FM
# the error margin for this estimate is about +/- 2 days due to weekends
# and then slight error margin in the cycle calculation
rec FMDaysSincePlot = if FMserialDateWD > 0 or DayNum == 5 and FMserialDateSAT > 0 or DayNum == 1 and FMserialDateSUN > 0 then 1 else FMDaysSincePlot[1] + 1;

def FMdayInFut = 22 - FMDaysSincePlot; # number of days from last bar until next FM
AddLabel(yes, Concat (FMdayInFut, " bars until next FM ") , Color.DARK_ORANGE);





# ---------------------
# New Moon
# ---------------------
# Identify if NM date is a weekday
def NMTOSSerialDateWD = DaysFromDate(19700101) + BaseDayCount;
def NMserialDateWD = fold NMindexWD = 1237 to 2470 with NMtempWD = 0 while NMTOSSerialDateWD <> NMtempWD do if NMTOSSerialDateWD == Round(SynoNewStart + NMindexWD * SynodMonth, 0) then FMTOSSerialDateWD else 0 ;

# Plot FM weekday
plot NMWD = if Show_Moons and NMserialDateWD > 0 then high + SignalLoc1 else Double.NaN;
NMWD.SetStyle(Curve.POINTS);
NMWD.SetLineWeight(5);
NMWD.SetDefaultColor(Color.BLACK);
NMWD.HideBubble();
NMWD.HideTitle();

#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and NMserialDateWD > 0, high + SignalLoc1, Concat(GetMonth(), Concat("/", GetDayOfMonth(GetYYYYMMDD()))), Color.BLACK, 1);

# ---------------------
# Identify if NM date is a Saturday
# If NM on Saturday then plot will be on previous Friday
def NMTOSSerialDateSAT = DaysFromDate(19700101) + BaseDayCount + 1;
def NMserialDateSAT = fold NMindexSAT = 1237 to 2470 with NMtempSAT = 0 while NMTOSSerialDateSAT <> NMtempSAT do if NMTOSSerialDateSAT == Round(SynoNewStart + NMindexSAT * SynodMonth, 0) then NMTOSSerialDateSAT else 0;

# Plot FM Saturday
plot NMSAT = if Show_Moons and DayNum == 5 and NMserialDateSAT > 0 and NMserialDateWD <> NMserialDateSAT then high + SignalLoc1 else Double.NaN;
NMSAT.SetStyle(Curve.POINTS);
NMSAT.SetPaintingStrategy(PaintingStrategy.LINE_VS_TRIANGLES);
NMSAT.SetLineWeight(5);
NMSAT.SetDefaultColor(Color.BLACK);
NMSAT.HideBubble();
NMSAT.HideTitle();
#Add chart bubble with month / day text
AddChartBubble(Show_Date_Bubbles and DayNum == 5 and NMserialDateSAT > 0 and NMserialDateWD <> NMserialDateSAT, high + SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) + 1)), Color.BLACK, 1);

# ---------------------
# Identify if NM date is a Sunday
# If NM on Sunday then plot will be on following Monday
# Sunday is tested on the Monday bar and plotted on Monday if True
def NMTOSSerialDateSUN = DaysFromDate(19700101) + BaseDayCount - 1;
def NMserialDateSUN = fold NMindexSUN = 1237 to 2470 with NMtempSUN = 0 while NMTOSSerialDateSUN <> NMtempSUN do if NMTOSSerialDateSUN == Round(SynoNewStart + NMindexSUN * SynodMonth, 0) then NMTOSSerialDateSUN else 0;

# Plot for NM Sunday
plot NMSUN = if Show_Moons and DayNum == 1 and NMserialDateSUN > 0 and NMserialDateWD <> NMserialDateSUN then high + SignalLoc1 else Double.NaN;
NMSUN.SetStyle(Curve.POINTS);
NMSUN.SetPaintingStrategy(PaintingStrategy.LINE_VS_SQUARES);
NMSUN.SetLineWeight(5);
NMSUN.SetDefaultColor(Color.BLACK);
NMSUN.HideBubble();
NMSUN.HideTitle();

# Add chart bubble with month / day text
# Becasue Sunday moons are confirmed and plotted on Mondays
# The day of month must be checked, If day = 1 then set month - 1 and
# select last day of previous month to disply in bubble
# Code to determine previous month and then last day of the previous
# month is commented out becasue I have not figured out how to calc
# the last day of the previous month.
#def PrevMonth = If getDayOfMonth(getYyyyMmDd()) == 1 then getLastMonth() else 0;
#def PrevDayPrevMonth = getDayofMonth(); # need to get last day of previous month
# Currently if Sunday is on then first of the month then the bubble will display a
# 0 for the day i.e. 3/0 instead of the desired 2/28
AddChartBubble(Show_Date_Bubbles and DayNum == 1 and NMserialDateSUN > 0 and NMserialDateWD <> NMserialDateSUN, high + SignalLoc1, Concat(GetMonth(), Concat ("/", GetDayOfMonth(GetYYYYMMDD()) - 1)), Color.BLACK, 1);

# ---------------------
# Estimate and plot 1 NM date in future
# Days since plot are tracked to estimate position of the
# future NM plot from the last NM plotted
# reset count to 1 each time a NM is plotted and add to count each day not plotted
# the original plan was to plot the next NM using the index (e.g. [-X])
# however [index] does not accept variables, so a chart label
# has been used to state how many days remain until the next NM
# the error margin for this is estimated about +/- 2 days due to weekends
# and then slight error margin in the cycle calculation
rec NMDaysSincePlot = if NMserialDateWD > 0 or DayNum == 5 and NMserialDateSAT > 0 or DayNum == 1 and NMserialDateSUN > 0 then 1 else NMDaysSincePlot[1] + 1;

def NMdayInFut = 22 - NMDaysSincePlot; # number of days from last bar until next NM
AddLabel(yes, Concat (NMdayInFut, " bars until next NM ") , Color.BLACK);





# ---------------------
# Original Excel function by Tobias Foerster
# ---------------------


#Full Moon Excel Function
# 'Moon Cycle um Erde is approx 29.53 days (synodischer Monat)

# Function IstVollmondtag(Datum As Date) As Boolean
# Const SynodMonat As Double = 29.530588
# Const SynodStart As Double = 105.6213922
# Dim OK As Boolean
# Dim DatumDbl As Double
# Dim DatumLng As Long
# Dim DatumHilf As Date
# Dim i As Long
# If Year(Datum) > 1900 And Year(Datum) < 2100 Then
# OK = False
# For i = 1 To 2470
# DatumDbl = SynodStart + i * SynodMonat
# DatumLng = Int(DatumDbl)
# DatumHilf = CDate(DatumLng)
# If DatumHilf = Datum Then
# OK = True
# Exit For
# End If
# Next i
# Else
# OK = ""
# End If
# IstVollmondtag = OK
# End Function

# New Moon Excel Funcion
# Function IstNeumondTag(Datum As Date) As Boolean
# Const SynodMonat As Double = 29.530588
# Const SynodStart As Double = 120.3866862
# Dim OK As Boolean
# Dim DatumDbl As Double
# Dim DatumLng As Long
# Dim DatumHilf As Date
# Dim i As Long
# If Year(Datum) > 1900 And Year(Datum) < 2100 Then
# OK = False
# For i = 1 To 2470
# DatumDbl = SynodStart + i * SynodMonat
# DatumLng = Int(DatumDbl)
# DatumHilf = CDate(DatumLng)
# If DatumHilf = Datum Then
# OK = True
# Exit For
# End If
# Next i
# Else
# OK = ""
# End If
# IstNeumondTag = OK
# End Function
I copied and pasted this study in to Think or Swim and am encountering some difficulties. If I am looking at a chart from a custom time frame, for example 01/01/2008 to 09/01/2008, aggregating at the daily intervals; I am able to see the moon phases on my chart. However; If I am looking at the standard 1Y : 1D format for the present time period the moon phases do not appear. Any ideas on how to fix this? I have a notification saying "Too many iterations in folding: 1233" when I attempt to view the standard 1Y:1D format in the present day.
 
# Full Moon Indicator
# Juan Flores 02/27/2021


input targetDate1 = 20210226;
def targetBar1 = DaysTillDate(targetDate1) == 0;
AddVerticalLine(targetBar1, "Target Bar1", Color.blue, curve.firm);

input targetDate2 = 20210329;
def targetBar2 = DaysTillDate(targetDate2) == 0;
AddVerticalLine(targetBar2, "Target Bar2", Color.yellow, curve.firm);

input targetDate3 = 20210426;
def targetBar3 = DaysTillDate(targetDate3) == 0;
AddVerticalLine(targetBar3, "Target Bar3", Color.green, curve.firm);

input targetDate4 = 20210526;
def targetBar4 = DaysTillDate(targetDate4) == 0;
AddVerticalLine(targetBar4, "Target Bar4", Color.red, curve.firm);

input targetDate5 = 20210624;
def targetBar5 = DaysTillDate(targetDate5) == 0;
AddVerticalLine(targetBar5, "Target Bar5", Color.blue, curve.firm);

input targetDate6 = 20210723;
def targetBar6 = DaysTillDate(targetDate6) == 0;
AddVerticalLine(targetBar6, "Target Bar6", Color.yellow, curve.firm);

input targetDate7 = 20210823;
def targetBar7 = DaysTillDate(targetDate7) == 0;
AddVerticalLine(targetBar7, "Target Bar7", Color.green, curve.firm);

input targetDate8 = 20210920;
def targetBar8 = DaysTillDate(targetDate8) == 0;
AddVerticalLine(targetBar8, "Target Bar8", Color.red, curve.firm);

input targetDate9 = 20211020;
def targetBar9 = DaysTillDate(targetDate9) == 0;
AddVerticalLine(targetBar9, "Target Bar9", Color.blue, curve.firm);

input targetDate10 = 20211119;
def targetBar10 = DaysTillDate(targetDate10) == 0;
AddVerticalLine(targetBar10, "Target Bar10", Color.yellow, curve.firm);

input targetDate11 = 20211220;
def targetBar11 = DaysTillDate(targetDate11) == 0;
AddVerticalLine(targetBar11, "Target Bar11", Color.green, curve.firm);

input targetDate12 = 20220118;
def targetBar12 = DaysTillDate(targetDate12) == 0;
AddVerticalLine(targetBar12, "Target Bar12", Color.red, curve.firm);


Here's basic script. Works well on daily chart. You can finesse it when full moon falls on weekend...just copy the 3 lines for the next date. If someone can simplify it, plus add code for plotting line at certain time of day, be my guest.
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
255 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top