Phase Moon Indicator for ThinkorSwim?

tomsk

Well-known member
VIP
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
 

Similar threads

Top