Strategy Based on EMAs, TSI, MACD, and Premarket Highs/Lows For ThinkOrSwim

Awesome work again on this! I was flipping between a few stocks, including NVDA and NFLX. Although I did not trade either, I saw the opportunities and potential! Nice work again!!!

I usually trade futures, but this is definitely a great setup!!

Quick observation and was wondering if you considered renaming "BUY" signals as either LE (Long Entry or just Long) and SE (Short Entry or just Short)?

Your efforts have been amazing and thank you again!!
Changed and added to Version 7a which is posted in Post #1
 
Version 7a link and code just posted. No big changes. Just changed "Buy" to "Long" or "Short" depending on direction at user request. Also added the ability to turn off the Tk Pft Bubble at user request. No major changes if you want to stay with Version 7.
thank you I will try it tomorrow
Changed and added the ability to turn those off in Version 7a which is posted in Post #1
thanks for your awesome work most appreciated .
 
If anyone is still looking to setup their flexible grid, do this :)

While in single grid, I will start with the actual saving of the chart layout. To do this, go to Chart tab and choose Chart. First you will create the chart with the studies, aggregation, labels, etc. Then click on Style and choose to save that as your chart default. The next step is the creation of the grid layout. At the upper right, click the outline of the box image. Click here and you can hover to highlight the actual grid cell structure that you want. Once you have the multi cell grid set up, then populate the symbols you want. Since you saved the first chart with all the indicators on it, then each that you pull up will house the same information.
 
Can we please add SequenceCounter (13,9) to Flexible Grid. I see for profit if it is at 9 and never add over 9 until 13. Please review as to the label if possible. Thank you
 
I added another visual change. This will be called Version 7b and it is already posted in Post #1 along with an updated link.

I added the below code so you would get a background color change where you would also get a "Long", "Short", "Sell", or "Tk Pft" Bubble.

The default setting is off and I personally will only be using this on my Flex Grid, hence the name above the code.

Code:
##################################################################
#                BACKGROUND COLOR FOR FLEX GRID                  #
##################################################################
#BACKGROUND
input ShowFlexGridBackgroundColor = no;

AssignBackgroundColor(if ShowFlexGridBackgroundColor and CallBuyBub then GlobalColor("OpenLongPosition") else color.current);
AssignBackgroundColor(if ShowFlexGridBackgroundColor and PutBuyBub then GlobalColor("OpenShortPosition") else color.current);
AssignBackgroundColor(if ShowFlexGridBackgroundColor and (CallSellBub or PutSellBub) then GlobalColor("SellPosition") else color.current);
AssignBackgroundColor(if ShowFlexGridBackgroundColor and (TkPftBubCall or TkPftBubPut) then color.light_red else color.current);
 
Oh it is definitely very cool. I just don't know how to necessarily add that label at this time and I don't want to clutter up the chart any more than it already is. I actually just added it to my daily chart though so I will watch it and see if I can't decipher exactly what is going on. If I think it is useful on this particular study then I can add it, if I can figure out how, with the option to turn it off.
 
I need some feedback from those of you that are using this!!!

What do you love?
What do you hate?
What could be better?
What could be changed?
Do you think it is cluttered?
Do you prefer different colors over the ones I randomly picked?
Do you want the option to turn something off that I didn't code in already?
Is there an option that you want to change but can't because I didn't code it in?
Are you making money?!?!?
Do you like the time restrictions, did it save you from buying on the morning rug pull or the afternoon crash?

Give me some feedback so I can make this thing awesome for everyone!

I get nothing out of this code except the fun of doing it and seeing the positive reaction it is getting.

Something about me that you didn't know....I am a full-time firefighter/paramedic and part-time registered nurse. I had no coding experience whatsoever when I got on this site but combed through the site and figured it out. I literally couldn't code an EMA line even if I wanted to less than a year ago but having COVID twice and plenty of quarantine time to play with this stuff taught me enough to build the code I did. I am by far not a professional trader and struggle like everyone else to just stay above water. I barely get to trade 2-3 days a week and half the time I have to go on an "emergency" call in the middle of a dicey day-trade. Lets get this code perfected so we can all be multi-thousandairs!!!
 
Last edited:
I am getting an error that wont let me apply the changes for the newest updated script.

Adding this:
#TESTING
addchartbubble(if ShowTestBubbles and CallBuyInd == 1 then 1 else 0, SlowEMA2*0.995, "C-Ind", color.light_green, no);
addchartbubble(if ShowTestBubbles and PutBuyInd == 1 then 1 else 0, SlowEMA2*1.005, "P-Ind", color.light_green, yes);

Causes this for me:
com.devexperts.tos.thinkscript.runtime.TooComplexException: The complexity of the expression suggests that it may not be reliable with real-time data.
That error is mostly encountered when setting up a scan and the code is too lengthy or complex..... are you sure you are adding the code in the right place....
 
I need some feedback from those of you that are using this!!!

What do you love?
What do you hate?
What could be better?
What could be changed?
Do you think it is cluttered?
Do you prefer different colors over the ones I randomly picked?
Do you want the option to turn something off that I didn't code in already?
Is there an option that you want to change but can't because I didn't code it in?
Are you making money?!?!?
Do you like the time restrictions, did it save you from buying on the morning rug pull or the afternoon crash?

Give me some feedback so I can make this thing awesome for everyone!

I get nothing out of this code except the fun of doing it and seeing the positive reaction it is getting.

Something about me that you didn't know....I am a full-time firefighter/paramedic and part-time registered nurse. I had no coding experience whatsoever when I got on this site but combed through the site and figured it out. I literally couldn't code an EMA line even if I wanted to less than a year ago but having COVID twice and plenty of quarantine time to play with this stuff taught me enough to build the code I did. I am by far not a professional trader and struggle like everyone else to just stay above water. I barely get to trade 2-3 days a week and half the time I have to go on an "emergency" call in the middle of a dicey day-trade. Lets get this code perfected so we can all be multi-thousandairs!!!
thank you again for your awesome work, today I was able to buy SPY calls and it was win lol, but I have few things I notice,1) the long signal appears on every green candle, if there is away to eliminate the quantity of Long or sell signals on every candle, 2) is it possible to add label up for Premarket High/Low , Yesterday High/Low. it easier to look at these labels . I am trying to upload imagine it won't upload to show you my trades. thanks Sir for your services .
 
Today is the first time I ever notice any green candles on SPY so that is good to hear!

I will try to add your suggestions in the next update.

As far as the multiple buy signals I may be able to fix that but sometimes little changes like that will screw up the code but I will definitely try. (Now that I think of it, I think I left the multiple buy signals on purpose to reiterate only buying on the 5EMA or better. It’s not always the case that you get a buy on every green candle). I’ll look at SPY and see if I can’t clean it up without messing with my original plan.

I can most likely add labels up top that can be turned on/off for premarket and yesterdays highs/lows. Haven’t really perfected the date thing but I’m sure I can look it up.
 
Today is the first time I ever notice any green candles on SPY so that is good to hear!

I will try to add your suggestions in the next update.

As far as the multiple buy signals I may be able to fix that but sometimes little changes like that will screw up the code but I will definitely try. (Now that I think of it, I think I left the multiple buy signals on purpose to reiterate only buying on the 5EMA or better. It’s not always the case that you get a buy on every green candle). I’ll look at SPY and see if I can’t clean it up without messing with my original plan.

I can most likely add labels up top that can be turned on/off for premarket and yesterdays highs/lows. Haven’t really perfected the date thing but I’m sure I can look it up.
Thanks a lot I appreciate your contribute. one more question which time frame is best to use, the one you tested 10 days 10min, or I can use it with different time frame. the end of the day I buy put and it dropped AH SPY.
 
Something about me that you didn't know....I am a full-time firefighter/paramedic and part-time registered nurse. I had no coding experience whatsoever when I got on this site but combed through the site and figured it out. I literally couldn't code an EMA line even if I wanted to less than a year ago but having COVID twice and plenty of quarantine time to play with this stuff taught me enough to build the code I did. I am by far not a professional trader and struggle like everyone else to just stay above water. I barely get to trade 2-3 days a week and half the time I have to go on an "emergency" call in the middle of a dicey day-trade. Lets get this code perfected so we can all be multi-thousandairs!!!
You are simply smart and intelligent. Bravo and wonderful. Your ability to analyze complex problems and find a solution is tremendous. and that means you have a much higher IQ - definitely. Like all of us here, I am very impressed for this useful work.
 
There is one setting that needs to be changed so I can maybe work on that later today. Will try to make it look good too. i.e. a drop down with a choice of time frame rather than a number that has to be changed from 0.7 to 0.03. That would be confusing to users, kinda like this comment, lol
I didn't trade this setup, but take a look at SHOP on the 5m. Looked like it worked out well this morning with an entry around 0845 - 0850 CDT. Personally, I always wait a minimum of 10 - 15 minutes before trading. I know you have a 30m rule for the 10m, but if the 5m is doable, maybe 15m rule for that time frame?

Just looked the SHOP 530PUT for 22APR Expiration. Price varied from a low 12.75 - 20.00. Hit a high so far of 30. Not bad and still no red candle on the 5m as 0947 CDT.

Red candle 1000 CDT.
 
Last edited:
Thanks for pointing that out. Although there are many trades in the morning there always seems to be that rug pull. Obviously SHOP didn’t have that. I think I will keep the times the way they are but you can always change it in the settings.

I am working on the different time frames now along with other stuff but if you want to change that setting on your 5 minute chart or any others than change it to 14. Not recommending it, lol. There are a lot of should've /could've that I have had in the past year or two but I am trying to remain strict on what I believe is true and I believe there is a rug pull 75% of the time, every time, lol.

I will try to get the different time frame edit out today if my 11 month old complies

gKFJE4c.png
No worries and as always, thank you!! Great work. I'm partial to the 10m overall, but did notice a few plays where the 5m could be beneficial. Not looking to mess with a great system!

I think having the user option for different time frames might be an "extra tool" in the box, but the 10m would be the standard for agreement against the other time frames.

Thanks and good luck with the 11 month old! I remember those days well!!
 
@MerryDay @halcyonguy @BenTen

Do you know if I can add a “choice” and based on that choice assign a value in a strategy?

for example:

def Choice = {default “10-Min”, “1-Min”, “15-Min”} etc for all intraday timeframes.

def EMASepThrHld = if Choice == “10-Min” then 0.3 else if Choice == “1-Min” then 0.1 else if Choice == “15-Min” then 0.7 else 0.3;

Tried a few versions of the above but none worked. Didn’t know if this was only for scans or if it works on studies/strategies as well.
 
No worries and as always, thank you!! Great work. I'm partial to the 10m overall, but did notice a few plays where the 5m could be beneficial. Not looking to mess with a great system!

I think having the user option for different time frames might be an "extra tool" in the box, but the 10m would be the standard for agreement against the other time frames.

Thanks and good luck with the 11 month old! I remember those days well!!
I’m trying @rfb Got the switch working and now trying to figure out the numbers but my sell signals are not showing up on the 1 hour chart. I think I know the problem but most likely going to take a lot more coding. Doubt it will be done before next week
 
  • Like
Reactions: rfb
Thanks again for all the hard work on this strategy. I've done well this week with it. I've noticed a few things back testing though.

1. I've removed CallBuy and PutBuy from the AddOrder to stop it from triggering a buy on the first red or blue candle to get a more accurate back test. Its like this now
#BUY ORDERS
AddOrder(OrderType.BUY_TO_OPEN, ShowOrders and (CallBuy[1] or CallBuy[2])or CallBuy[3] and low <= FastEMA1 and low >= FastEMA2, FastEMA1, 100, Color.GREEN, Color.LIGHT_GREEN);
AddOrder(OrderType.SELL_TO_OPEN, ShowOrders and (PutBuy[1] or PutBuy[2] or PutBuy[3]) and high >= FastEMA1 and high <=FastEMA2, FastEMA1, 100, Color.GREEN, Color.LIGHT_GREEN);
2. The AddOrder will trigger up to 3 candles after a Green or Blue candle even if a red candle appears. Can this be coded to reset once a red candle appears?
3. Also once a trade starts if the candle turn grey before red it will continue with a big loss. Can this be coded to sell on a grey candle as well?

Yxh4f2n.png


The labels above is for back testing. You can add it to your strategy. Its Extended Floating P/L and the link to it is https://usethinkscript.com/threads/...acktesting-data-utility-for-thinkorswim.1624/
Here you go. It’s the Extended Floating P/L pasted to the bottom of a1cturner's latest strategy.
Ruby:
#JT Newest Strategy Based on EMAs, TSI, Premarket Highs/Lows, and MACD
#VERSION 8 - 04/21/2022

#Notes
#Added The Ability to Turn Off PreMarket High/Low Cloud
#Added Labels for PreMarket High/Low with Ability to Turn On/Off
#Changed the Global Color of Tk Pft to Pink
#Added the ablity of Background Color Change to Match Bubble (Used in FlexGrid), Default if Off.
#Added different time frames. This controls the EMA Seperation Threshold and Last Sell Candle.

Declare Upper;

##################################################################
# TIMES #
##################################################################
#START AND END TIMES
input TimeFrame = {default "10-Min", "1-Min", "5-Min", "15-Min", "30-Min", "1-Hour"};
input PreMarketStart = 0730; #EST
input PreMarketEnd = 0929; #EST
input StartTime = 0930; #EST
input BuySignalDelay = 29;
input EndTime = 1600; #EST
input BuySignalStop = 60; #Minutes Before End of Day
def LastCandleStop; #Last Candle is Sell Candle

switch (TimeFrame) {
case "1-min": LastCandleStop = 1;
case "5-Min": LastCandleStop = 5;
case "15-Min": LastCandleStop = 15;
case "30-Min": LastCandleStop = 30;
case "1-Hour": LastCandleStop = 60;
default: LastCandleStop = 10;
}

def TradingDayStart= SecondsFromTime(StartTime);
def BuySignalDelaySeconds = BuySignalDelay * 60;
def SignalStart = TradingDayStart > BuySignalDelaySeconds;
def TradingDayEnd = SecondsTillTime(EndTime);
def EndSignalDelaySeconds = BuySignalStop * 60;
def SignalEnd = TradingDayEnd > EndSignalDelaySeconds;
def TradingDay = SignalStart and SignalEnd; #10:00EST - 1500EST
def LastStopDelaySeconds = LastCandleStop * 60;
def EndDay = TradingDayEnd == LastStopDelaySeconds; #1550EST
def TradingDayExt = TradingDayEnd > LastStopDelaySeconds;

##################################################################
# INDICATORS #
##################################################################
input ShowTestBubbles = no;

#EMAS
input Ema1Length = 5;
input Ema2Length = 12;
input Ema3Length = 34;
input Ema4Length = 50;
#input Ema5Length = 8; #If Needed
#input Ema6LEngth = 9; #If Needed

plot FastEMA1 = ExpAverage(close, Ema1Length);
FastEMA1.SetDefaultColor(color.light_green);
FastEMA1.HideBubble();
plot FastEMA2 = ExpAverage(close, Ema2Length);
FastEMA2.SetDefaultColor(color.light_red);
FastEMA2.HideBubble();
AddCloud(FastEMA1, FastEMA2, createcolor(0, 255, 153), createcolor(0, 153, 255));
plot SlowEMA1 = ExpAverage(close, Ema3Length);
SlowEMA1.SetDefaultColor(color.light_green);
SlowEMA1.HideBubble();
plot SlowEMA2 = ExpAverage(close, Ema4Length);
SlowEMA2.SetDefaultColor(color.light_red);
SlowEMA2.HideBubble();
AddCloud(SlowEMA1, SlowEMA2, createcolor(0, 255, 0), createcolor(0, 0, 255));
#def FastEMA3 = ExpAverage(close, EMA5Length); #If Needed
#def FastEMA4 = ExpAverage(close, EMA6Length); #If Needed
#AddCloud(FastEMA3, FastEMA4, Color.light_gray, Color.light_gray); #If Needed

#EMAS BULLISH OR BEARISH
def FastEMABullish = FastEMA1 > FastEMA2;
def SlowEMABullish = SlowEMA1 > SlowEMA2;
def FastEMABearish = FastEMA1 < FastEMA2;
def SlowEMABearish = SlowEMA1 < SlowEMA2;
#EMA BUY SIGNAL
def BothEMASBullish = FastEMABullish and SlowEMABullish;
def BothEMASBearish = FastEMABearish and SlowEMABearish;

#EMA PERCENT SEPERATION
def FastEMAPctBull = ((FastEMA1 / FastEMA2) * 100) - 100; #Distance Between Fast EMA 1 and Fast EMA 2
def FastEMAPctBullRound = Round(FastEMAPctBull, 2);
def FastEMAPctBear = ((FastEMA2 / FastEMA1) * 100) - 100; #Distance Between Fast EMA 2 and Fast EMA 1
def FastEMAPctBearRound = Round(FastEMAPctBear, 2);

#FAST EMA PERCENT SEPERATION BUY SIGNAL
def EMASepThrHld;
switch (TimeFrame) {
case "1-min": EMASepThrHld = 0.1;
case "5-Min": EMASepThrHld = 0.2;
case "15-Min": EMASepThrHld = 0.3;
case "30-Min": EMASepThrHld = 0.4;
case "1-Hour": EMASepThrHld = 0.1;
default: EMASepThrHld = 0.25;
}

def FastEMAPctBullish = BothEMASBullish and FastEMAPctBullRound > EMASepThrHld and FastEMAPctBullRound >= FastEMAPctBullRound[1];
def FastEMAPctBearish = BothEMASBearish and FastEMAPctBearRound > EMASepThrHld and FastEMAPctBearRound >= FastEMAPctBearRound[1];
#TESTING
addchartbubble(if ShowTestBubbles and FastEMAPctBullish == 1 then 1 else 0, SlowEMA2*0.995, FastEMAPctBullRound, color.dark_green, no);
addchartbubble(if ShowTestBubbles and FastEMAPctBearish == 1 then 1 else 0, SlowEMA2*1.005, FastEMAPctBearRound, color.dark_green, yes);

def SlowEMAPctBull = ((SlowEMA1 / SlowEMA2) * 100) - 100; #Distance Between Slow EMA 1 and Slow EMA 2
def SlowEMAPctBullRound = Round(SlowEMAPctBull, 2);
def SlowEMAPctBear = ((SlowEMA2 / SlowEMA1) * 100) - 100; #Distance Between Slow EMA 1 and Slow EMA 2
def SlowEMAPctBearRound = Round(SlowEMAPctBear, 2);

#SLOW EMA PERCENT SEPERATION BULLISH
def SlowEMAPctBullish = BothEMASBullish and SlowEMAPctBullRound >= SlowEMAPctBullRound[1];
def SlowEMAPctBearish = BothEMASBearish and SlowEMAPctBearRound <= SlowEMAPctBearRound[1];

#EMA SELL SIGNALS
def FastEMACrossDown = FastEMA1 crosses below FastEMA2;
def FastEMACrossUp = FastEMA1 crosses above FastEMA2;
def FastEMAPctBullDecrease = if BothEMASBullish and FastEMAPctBullRound < (FastEMAPctBullRound[1] * 0.75) then 1 else 0;
def FastEMAPctBearDecrease = if BothEMASBearish and FastEMAPctBearRound < (FastEMAPctBearRound[1] * 0.75) then 1 else 0;
#TESTING
addchartbubble(if ShowTestBubbles and FastEMAPctBullDecrease == 1 then 1 else 0, SlowEMA2*0.995, FastEMAPctBullRound, color.dark_red, no);
addchartbubble(if ShowTestBubbles and FastEMAPctBearDecrease == 1 then 1 else 0, SlowEMA2*1.005, FastEMAPctBearRound, color.dark_red, yes);

#SLOWEMA2 SLOPE (NOT USING AT THIS TIME)
def Height = SlowEMA2 - SlowEMA2[11];
def SlopeDeg = Round((ATan(Height / 10) * 180 / Double.Pi), 0);
#SLOWEMA2 SLOPE SELL SIGNAL
def BullSlopeSell = BothEMASBullish and SlopeDeg < SlopeDeg[1];
def BearSlopeSell = BothEMASBearish and SlopeDeg > SlopeDeg[1];
#TESTING
#addchartbubble(if ShowTestBubbles and BullSlopeSell == 1 then 1 else 0, SlowEMA2*0.995, "Slope", color.dark_red, no);
#addchartbubble(if ShowTestBubbles and BearSlopeSell == 1 then 1 else 0, SlowEMA2*1.005, "Slope", color.dark_red, yes);

#MACD
input MACDFast = 10;
input MACDSlow = 22;
input MACDLength = 8;

def MACDValue = ExpAverage(close, MACDFast) - ExpAverage(close, MACDSlow);
def MACDAverage = ExpAverage(MACDValue, MACDLength);
def MACDDiff = MACDValue - MACDAverage;
def ZeroLine = 0;

#MACD BUY SIGNAL
def MACDBull = MACDDiff >= MACDDiff[1];
def MACDBear = MACDDiff <= MACDDiff[1];

#MACD SELL SIGNAL
#No Sell SIgnals At This Time

#TSI
input TSILongLength = 25;
input TSIShortLength = 13;
input TSISignalLength = 8;

def TSIDiff = close - close[1];
def DoubleSmoothedAbsDiff = ExpAverage(ExpAverage(AbsValue(TSIDiff), TSILongLength), TSIShortLength);
def TSIRound = Round((100 * (ExpAverage(ExpAverage(TSIDiff, TSILongLength), TSIShortLength)) / DoubleSmoothedAbsDiff), 2);

#TSI BUY SIGNAL
def TSIBull = (TSIRound > 10) and (TSIRound >= TSIRound[1]);
def TSIBear = (TSIRound < -10) and (TSIRound <= TSIRound[1]);

#TSI SELL SIGNAL
def TSICrossDown = TSIRound < (TSIRound[1] * 0.91);
def TSICrossUp = TSIRound > (TSIRound[1] * 0.91);

#TSI TAKE PROFIT
#No TSI Take Profit At This Time

#PREMARKET HIGHS AND LOWS
input ShowPreMarketCloud = yes;
input ShowPreMarketLabel = yes;

def PreMarketTimeRange = secondsFromTime(PreMarketStart) >= 0 and secondsTillTime(PreMarketEnd) >= 0;
def PreMarket = PreMarketTimeRange and !PremarketTimeRange[1];
def Pre_Market_High = compoundValue(1, if((high > Pre_Market_High[1] and PremarketTimeRange) or PreMarket, high, Pre_Market_High[1]), high);
def Pre_Market_Low = compoundValue(1, if((low < Pre_Market_Low[1] and PremarketTImeRange) or PreMarket, low, Pre_Market_Low[1]), low);

plot PreMarketHigh = if ShowPreMarketCloud then Pre_Market_High else double.nan;
PreMarketHigh.SetStyle(curve.short_dash);
PreMarketHigh.SetDefaultColor(color.light_gray);
PreMarketHigh.setLineWeight(1);
plot PreMarketLow = if ShowPreMarketCloud then Pre_Market_Low else double.nan;
PreMarketLow.SetStyle(curve.short_dash);
PreMarketLow.SetDefaultColor(color.light_gray);
PreMarketLow.setLineWeight(1);
AddCloud (PreMarketHigh, PreMarketLow, color.light_gray, color.light_gray);

AddLabel(if ShowPreMarketLabel then yes else no, " ", color.black);
AddLabel(if ShowPreMarketLabel then yes else no, " PM High - $" + PreMarketHigh, color.gray);
AddLabel(if ShowPreMArketLabel then yes else no, " PM Low - $" + PreMarketLow, color.gray);

#PREMARKET HIGH/LOW BUY SIGNAL
def PreMarketBull = low > Pre_Market_High;
def PreMarketBear = high < Pre_Market_Low;
#TESTING
addchartbubble(if ShowTestBubbles and PreMarketBull == 1 then 1 else 0, SlowEMA2*0.995, "Pre", color.dark_green, no);
addchartbubble(if ShowTestBubbles and PreMarketBear == 1 then 1 else 0, SlowEMA2*1.005, "Pre", color.dark_green, yes);

#PREMARKET HIGH/LOW SELL SIGNAL
def PreMarketBullSell = PreMarketBull[1] and low < Pre_Market_High;
def PreMarketBearSell = PreMarketBear[1] and high > Pre_Market_Low;
#TESTING
addchartbubble(if ShowTestBubbles and PreMarketBullSell == 1 then 1 else 0, SlowEMA2*0.995, "Pre", color.dark_red, no);
addchartbubble(if ShowTestBubbles and PreMarketBearSell == 1 then 1 else 0, SlowEMA2*1.005, "Pre", color.dark_red, yes);

##################################################################
# SIGNALS #
##################################################################
#GET READY
def GetReadyBull = TradingDay and BothEMASBullish and PreMarketBull;
def GetReadyBear = TradingDay and BothEMASBearish and PreMarketBear;

#INDICATOR BUY SIGNALS
def CallBuyInd = BothEMASBullish and FastEMAPctBullish and MACDBull and TSIBull and PreMarketBull;
def PutBuyInd = BothEMASBearish and FastEMAPctBearish and MACDBear and TSIBear and PreMarketBear;
#TESTING
addchartbubble(if ShowTestBubbles and CallBuyInd == 1 then 1 else 0, SlowEMA2*0.995, "C-Ind", color.light_green, no);
addchartbubble(if ShowTestBubbles and PutBuyInd == 1 then 1 else 0, SlowEMA2*1.005, "P-Ind", color.light_green, yes);

##################################################################
# ADDED FAST EMA PCT HERE BASED OFF BUY SIGNAL #
##################################################################
def EMAPctAtCallBuy = if CallBuyInd then FastEMAPctBullRound else EMAPctAtCallBuy[1]; #Used to Calculate Sell Trigger
def EMAPctAtPutBuy = if PutBuyInd then FastEMAPctBearRound else EMAPctAtPutBuy[1]; #Used to Calculate Sell Trigger

#FAST EMA CLOUD SELL TRIGGER BASED OFF BUY INDICATOR
def CallEMAPctSell = FastEMAPctBullRound < EMAPctAtCallBuy * 0.65;
def PutEMAPctSell = FastEMAPctBearRound < EMAPctAtPutBuy * 0.65;

##################################################################
# SIGNALS CONT. #
##################################################################
#INDICATOR HOLD SIGNALS
def CallHoldInd = BothEMASBullish and PreMarketBull;
def PutHoldInd = BothEMASBearish and PreMarketBear;
#TESTING
addchartbubble(if ShowTestBubbles and CallHoldInd == 1 then 1 else 0, SlowEMA2*0.995, "CH_Ind", color.light_green, no);
addchartbubble(if ShowTestBubbles and PutHoldInd == 1 then 1 else 0, SlowEMA2*1.005, "PH-Ind", color.light_green, yes);

##################################################################
# EMA TAKE PROFIT CLOUD (IDENTIFY IF PRICE IS EXTENDED FROM EMAS)#
##################################################################
input ShowOverExtCloud = yes;

def OvrExtUp1 = if ShowOverExtCloud and SignalStart and TradingDayExt and (CallBuyInd or CallHoldInd) then FastEMA1 * 1.01 else Double.NaN;
#addchartbubble(if High > OvrExtUp1 == 1 then 1 else 0, OvrExtUp1*1.005, "TkPft1", color.light_green, yes);
def OvrExtUp2 = if ShowOverExtCloud and SignalStart and TradingDayExt and (CallBuyInd or CallHoldInd) then FastEMA1 * 1.02 else Double.NaN;
#addchartbubble(if High > OvrExtUp2 == 1 then 1 else 0, OvrExtUp2*1.005, "TkPft2", color.light_green, yes);
AddCloud(OvrExtUp1, OvrExtUp2, color.light_green, color.light_green);
def OvrExtDn1 = if ShowOverExtCloud and SignalStart and TradingDayExt and (PutBuyInd or PutHoldInd) then FastEMA1 * 0.99 else Double.NaN;
#addchartbubble(if Low < OvrExtDn1 == 1 then 1 else 0, OvrExtDn1*0.995, "TkPft1", color.light_green, no);
def OvrExtDn2 = if ShowOverExtCloud and SignalStart and TradingDayExt and (PutBuyInd or PutHoldInd) then FastEMA1 * 0.98 else Double.NaN;
#addchartbubble(if Low < OvrExtDn2 == 1 then 1 else 0, OvrExtDn2*0.995, "TkPft2", color.light_green, no);
AddCloud(OvrExtDn1, OvrExtDn2, color.light_green, color.light_green);

##################################################################
# SIGNALS CONT. #
##################################################################
#INDICATOR SELL SIGNALS
def CallSellInd = FastEMACrossDown or TSICrossDown or CallEMAPctSell;
def PutSellInd = FastEMACrossUp or TSICrossUp or PutEMAPctSell;
#TESTING
addchartbubble(if ShowTestBubbles and CallSellInd == 1 then 1 else 0, SlowEMA2*0.995, "CS-Ind", color.light_red, no);
addchartbubble(if ShowTestBubbles and PutSellInd == 1 then 1 else 0, SlowEMA2*1.005, "PS-Ind", color.light_red, yes);

#BUY SIGNALS
def CallBuy = TradingDay and CallBuyInd;
def PutBuy = TradingDay and PutBuyInd;
#TESTING
addchartbubble(if ShowTestBubbles and CallBuy == 1 then 1 else 0, SlowEMA2*0.995, "Call", color.green, no);
addchartbubble(if ShowTestBubbles and PutBuy == 1 then 1 else 0, SlowEMA2*1.005, "Put", color.green, yes);

#HOLD SIGNALS
def CallHold = TradingDayExt and CallHoldInd and (CallBuy[1] or CallHold[1]);
def PutHold = TradingDayExt and PutHoldInd and (PutBuy[1] or PutHold[1]);
#TESTING
addchartbubble(if ShowTestBubbles and CallHold == 1 then 1 else 0, SlowEMA2*0.995, "C-Hold", color.green, no);
addchartbubble(if ShowTestBubbles and PutHold == 1 then 1 else 0, SlowEMA2*1.005, "P-Hold", color.green, yes);

#SELL SIGNALS
def CallSell = TradingDayExt and CallSellInd and !CallSellInd[1] and (CallBuy[1] or CallHold[1]);
def PutSell = TradingDayExt and PutSellInd and !PutSellInd[1] and (PutBuy[1] or PutHold[1]);
#TESTING
addchartbubble(if ShowTestBubbles and CallSell == 1 then 1 else 0, SlowEMA2*0.995, "C-Sell", color.red, no);
addchartbubble(if ShowTestBubbles and PutSell == 1 then 1 else 0, SlowEMA2*1.005, "P-Sell", color.red, yes);

##################################################################
# BARS #
##################################################################
DefineGlobalColor("OpenLongPosition", createcolor (0, 255, 0));
DefineGlobalColor("OpenShortPosition", createcolor (0, 0, 255));
DefineGlobalColor("HoldLongPosition", createcolor (204, 255, 204));
DefineGlobalColor("HoldShortPosition", createcolor (102, 255, 255));
DefineGlobalColor("GetReady", createcolor (204, 153, 0));
DefineGlobalColor("SellPosition", createcolor (255, 0, 0));
DefineGlobalColor("TakeProfit", createcolor (255, 0, 255));
DefineGlobalColor("CriteriaNotMet", createcolor (102, 102, 102));

#COLOR BARS
AssignPriceColor(if CallSell then GlobalColor("SellPosition") else if CallBuy then GlobalColor("OpenLongPosition") else if CallHold then GlobalColor("HoldLongPosition") else if PutSell then GlobalColor("SellPosition") else if PutBuy then GlobalColor("OpenShortPosition") else if PutHold then GlobalColor("HoldShortPosition") else if EndDay then GlobalColor("SellPosition") else if GetReadyBull then GlobalColor("GetReady") else if GetReadyBear then GlobalColor("GetReady") else GlobalColor("CriteriaNotMet"));

##################################################################
# LABELS #
##################################################################
#LABELS
AddLabel(yes, " ", color.black);
AddLabel(yes, "PREMKT", if PreMarketBull then GlobalColor("OpenLongPosition") else if PreMarketBear then GlobalColor("OpenShortPosition") else color.gray);
AddLabel(yes, "CLOUDS", if BothEMASBullish then GlobalColor("OpenLongPosition") else if BothEMASBearish then GlobalColor("OpenShortPosition") else color.gray);
AddLabel(yes, "EMA SEP", if FastEMAPctBullish then GlobalColor("OpenLongPosition") else if FastEMAPctBearish then GlobalColor("OpenShortPosition") else color.gray);
AddLabel(yes, "TSI", if TSIBull then GlobalColor("OpenLongPosition") else if TSIBear then GlobalColor("OpenShortPosition") else color.gray);
AddLabel(yes, "MACD", if MACDBull then GlobalColor("OpenLongPosition") else if MACDBear then GlobalColor("OpenShortPosition") else color.gray);

##################################################################
# CHART BUBBLES FOR BUY/SELL #
##################################################################
input ShowBuySellBubbles = Yes;
input ShowTkPftBubble = Yes;

#BUY
def CallBuyBub = TradingDay and !CallSell and (CallBuy[1] or CallBuy[2] or CallBuy[3]) and low <= FastEMA1 and low >= FastEMA2;
addchartbubble(ShowBuySellBubbles and CallBuybub, low * 0.999, "Long", GlobalColor("OpenLongPosition"), no);
def PutBuyBub = TradingDay and !PutSell and (PutBuy[1] or PutBuy[2] or PutBuy[3]) and high >= FastEMA1 and high <=FastEMA2;
addchartbubble(ShowBuySellBubbles and PutBuyBub, high * 1.001, "Short", GlobalColor("OpenShortPosition"), yes);

#SELL
def CallSellBub = TradingDayExt and (CallBuy[1] or CallHold[1]) and CallSell;
addchartbubble(ShowBuySellBubbles and CallSellBub, low * 0.999, "Sell", GlobalColor("SellPosition"), no);
def PutSellBub = TradingDayExt and (PutBuy[1] or PutHold[1]) and PutSell;
addchartbubble(ShowBuySellBubbles and PutSellBub, high * 1.001, "Sell", GlobalColor("SellPosition"), yes);

#TAKE PROFIT
def TkPftBubCall = TradingDayExt and (CallBuyInd or CallHoldInd) and high > FastEMA1 * 1.01;
addchartbubble(ShowBuySellBubbles and ShowTkPftBubble and TkPftBubCall, high * 1.001, "Tk Pft", GlobalColor("TakeProfit"), yes);
def TkPftBubPut = TradingDayExt and (PutBuyInd or PutHoldInd) and low < FastEMA1 * 0.99;
addchartbubble(ShowBuySellBubbles and ShowTkPftBubble and TkPftBubPut, low * 0.999, "Tk Pft", GlobalColor("TakeProfit"), no);

##################################################################
# ORDERS #
##################################################################
#ORDERS
input ShowOrders = no;

#BUY ORDERS
AddOrder(OrderType.BUY_TO_OPEN, ShowOrders and (CallBuy[1] or CallBuy[2])or CallBuy[3] and low <= FastEMA1 and low >= FastEMA2, FastEMA1, 100, Color.GREEN, Color.LIGHT_GREEN);
AddOrder(OrderType.SELL_TO_OPEN, ShowOrders and (PutBuy[1] or PutBuy[2] or PutBuy[3]) and high >= FastEMA1 and high <=FastEMA2, FastEMA1, 100, Color.GREEN, Color.LIGHT_GREEN);

#SELL ORDERS
AddOrder(OrderType.SELL_TO_CLOSE, ShowOrders and TkPftBubCall, high * 0.999, 100, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.SELL_TO_CLOSE, ShowOrders and CallSellBub or EndDay[-1], close, 100, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, ShowOrders and TkPftBubPut, low * 1.001, 100, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, ShowOrders and PutSellBub or EndDay[-1], close, 100, Color.RED, Color.LIGHT_RED);

##################################################################
# ALERTS #
##################################################################
#ALERTS
input AlertOn = yes;

Alert(AlertOn and (CallSellBub or PutSellBub or TkPftBubCall or TkPftBubPut), "SELL", Alert.BAR, Sound.Bell);
Alert(AlertOn and (CallBuyBub or PutBuyBub), "BUY", Alert.BAR, Sound.Chimes);

##################################################################
# PROFIT/LOSS LABEL #
##################################################################
input ShowPLLabel = Yes;

#CALL
AddLabel(if ShowPLLabel then yes else no, " ", color.black);
def CallOpen = if CallBuy and !CallHold then FastEMA1 else CallOpen[1];
def CallEnd = if TkPftBubCall then high * 0.999 else if CallSellBub then close else CallEnd[1];
def CallOpenCost = CallOpen * 100;
def CallCloseCost = CallEnd * 100;
def CallDiff = round(CallCloseCost - CallOpenCost, 2);
AddLabel(if ShowPLLabel then yes else no, "Long Trade P/L - $ " + CallDiff + " ", if CallDiff > 0 then color.light_green else if CallDiff < 0 then color.light_red else color.gray);

#PUT
def PutOpen = if PutBuy and !PutHold then FastEMA1 else PutOpen[1];
def PutEnd = if TkPftBubPut then low * 1.001 else if PutSellBub then close else PutEnd[1];
def PutOpenCost = PutOpen * 100;
def PutCloseCost = PutEnd * 100;
def PutDiff = round(PutOpenCost - PutCloseCost, 2);
AddLabel(if ShowPLLabel then yes else no, "Short Trade P/L - $ " + PutDiff + " ", if PutDiff > 0 then color.light_green else if PutDiff < 0 then color.light_red else color.gray);

##################################################################
# CANDLE COLOR LABEL #
##################################################################
#LABELS
input ShowColorDefLabels = yes;

AddLabel(if ShowColorDefLabels == 1 then yes else no, " ", color.black);
AddLabel(if ShowColorDefLabels == 1 then yes else no, "Long Ind", GlobalColor("OpenLongPosition"));
AddLabel(if ShowColorDefLabels == 1 then yes else no, "Long Hld", GlobalColor("HoldLongPosition"));
AddLabel(if ShowColorDefLabels == 1 then yes else no, "Short Ind", GlobalColor("OpenShortPosition"));
AddLabel(if ShowColorDefLabels == 1 then yes else no, "Short Hld", GlobalColor("HoldShortPosition"));
AddLabel(if ShowColorDefLabels == 1 then yes else no, "Get Ready", GlobalColor("GetReady"));
AddLabel(if ShowColorDefLabels == 1 then yes else no, "Sell", GlobalColor("SellPosition"));
AddLabel(if ShowColorDefLabels == 1 then yes else no, "Tk Pft", GlobalColor("TakeProfit"));
AddLabel(if ShowColorDefLabels == 1 then yes else no, "No Criteria", GlobalColor("CriteriaNotMet"));

##################################################################
# BACKGROUND COLOR FOR FLEX GRID #
##################################################################
#BACKGROUND
input ShowFlexGridBackgroundColor = no;

AssignBackgroundColor(if ShowFlexGridBackgroundColor and (CallSellBub or PutSellBub) then GlobalColor("SellPosition") else if CallBuyBub then GlobalColor("OpenLongPosition") else if PutBuyBub then GlobalColor("OpenShortPosition") else if ShowFlexGridBackgroundColor and TradingDayExt and (CallBuyInd or CallHoldInd) and (TkPftBubCall or TkPftBubPut) then GlobalColor("TakeProfit") else color.current);

############################
# FPL Extended
# Extended Floating P&L study.
# Author: Eddielee394
# Version: 1.2
# inspired by FPL Dashboard script developed by Mobius
#
############################

#Hint: An extended floating P&L study to be used alongside TOS strategies for measuring hypothetical strategy performance.\nThis is a work in progress. And may contain some bugs or other programming issues.

############################
# Instructions
# - Due to limitations with the thinkscript public api, this specific script must be added to a "strategy" study.
# Generally best practice is to append this script to the end of your custom strategy (ensuring it runs AFTER the
# AddOrder() function is called from the strategy). A better method would be to use as a lower study but unless
# a workaround is implemented to handle the Entry() function in a lower study, it can only be applied to upper strategies.
#
# - the script uses the HidePrice() function which will hide the actual price candles within the upper study,
# only displaying the FPL histogram.
#
############################


############################
# Metrics
# - Active Trade return %
# - Entry Count
# - Winning Entry Count
# - Win rate
# - Avg return
# - avg win
# - avg loss
# - peak to valley dd
# - largest equity dd
# - P&L low
# - P&L high
# - Highest return
# - Lowest return
############################

############################
# Todo:
# - Sharpe Ratio
# - Sortino Ratio
# - Calmar Ratio
# - Avg trade
# duration
# -Buy/hold comparison
############################


#Globals
def nan = Double.NaN;
def bn = if !IsNaN(close) and !IsNaN(close[1]) and !IsNaN(close[-1]) then BarNumber() else bn[1];

#Inputs
input fplBegin = 0000;
#hint fplBegin: start time: the time in which then dailyHighLow profit should consider the day start. Recommended value is 0000.

input fplTargetWinLoss = .50;
#hint fplTargetWinLoss: sets the target winlossRatio (in percent) which determines display colors of the W/L label.

input fplTargetWinRate = 1;
#hint fplTargetWinRate: sets the target winRate (float) which determines display colors of the WinRate label;

input fplHidePrice = no;
#hint fplHidePrice: hide's the underlying price graph. \nDefault is no.

input fplHideFPL = yes;
#hint fplHideFPL: hide's the underlying P&L graph.\nDefault is yes.

input fplShowEntryBubbles = no;
#hint fplShowEntryBubbles: display bubbles on the FPL showing the entry and exit P&L values

input fplEnableDebugging = no;
#hint fplEnableDebugging: displays various debugging labels and chart bubbles. \nIt's recommended to hide the price chart & set the fpl hide fpl setting to yes, when enabling.


#temp input var references
def begin = fplBegin;
def targetWinLoss = fplTargetWinLoss;
def targetWinRate = fplTargetWinRate;
def hidePrice = fplHidePrice;
def hideFPL = fplHideFPL;
def showEntryBubbles = fplShowEntryBubbles;
def enableDebugging = fplEnableDebugging;

#hide chart candles
HidePricePlot(hidePrice);

#Plot default Floating P&L
plot FPL = FPL();
FPL.SetPaintingStrategy(PaintingStrategy.SQUARED_HISTOGRAM);
FPL.DefineColor("Positive and Up", Color.GREEN);
FPL.DefineColor("Positive and Down", Color.DARK_GREEN);
FPL.DefineColor("Negative and Down", Color.RED);
FPL.DefineColor("Negative and Up", Color.DARK_RED);
FPL.AssignValueColor(if FPL >= 0
then if FPL > FPL[1]
then FPL.Color("Positive and Up")
else FPL.Color("Positive and Down")
else if FPL < FPL[1]
then FPL.Color("Negative and Down")
else FPL.Color("Negative and Up"));
FPL.SetHiding(hideFPL);

plot ZeroLine1 = if IsNaN(close)
then nan
else 0;
ZeroLine1.SetDefaultColor(Color.GRAY);
ZeroLine1.SetHiding(hideFPL);

#Global Scripts
script calculateDrawdown {
input plLow = 1;
input plHigh = 1;

def _drawdown = if plHigh == 0
then 0 #handles the divide by zero error
else (plLow - plHigh) / plHigh;
plot calculateDrawdown = _drawdown;
}

script incrementValue {
input condition = yes;
input increment = 1;
input startingValue = 0;

def _value = CompoundValue(1,
if condition
then _value[1] + increment
else _value[1], startingValue);

plot incrementValue = _value;
}
;

script getDurationInMins {
input gdimBarCount = 1;

#get the aggregation period (MS per bar)
def aggPeriod = GetAggregationPeriod();

#multiply length of bars by aggPeriod to determine total milliseconds then convert to minutes
def _getDurationInMins = Floor((gdimBarCount * aggPeriod) / 60000);
plot getDurationInMins = _getDurationInMins;
}

script formatDuration {
input fdBarCount = 1;
def _fdDuration = getDurationInMins(fdBarCount);
def _formatDuration = if _fdDuration >= 60 and _fdDuration < 1440 #hours but not days
then 1
else if _fdDuration >= 1440 #days
then 2
else 0;

plot formatDuration = _formatDuration;
}

script calculateDuration {
input cdBarCount = 1;
def _cdDurationFormat = formatDuration(cdBarCount);
def _cdDuration = getDurationInMins(cdBarCount);

#if minutes > hour convert to hour, else if minutes > day, then convert to days
def _calculateDuration = if _cdDurationFormat == 1
then _cdDuration / 60 #convert to hours if greater than 60min but less than a day (1440)
else if _cdDurationFormat == 2
then Ceil(_cdDuration / 1440) #convert to days if greater than 1440mins
else _cdDuration; #fallback to minutes

plot calculateDuration = _calculateDuration;
}

# Entry Calculations. Note: Only parses on a Strategy Chart
def entry = round (EntryPrice(),2);

def entryPrice = if !IsNaN(entry)
then entry
else entryPrice[1];

def hasEntry = !IsNaN(entry);

def isNewEntry = entryPrice != entryPrice[1];

#is active trade
def Active = if SecondsTillTime(begin) == 0 and
SecondsFromTime(begin) == 0
then 1
else 0;

def highFPL = HighestAll(FPL);
def lowFPL = LowestAll(FPL);

def fplreturn = (FPL - FPL[1]) / FPL[1];
def cumsum = Sum(fplreturn);

def highBarNumber = CompoundValue(1, if FPL == highFPL
then bn
else highBarNumber[1], 0);

def lowBarNumber = CompoundValue(1, if FPL == lowFPL
then bn
else lowBarNumber[1], 0);


#Win/Loss ratios
def entryBarsTemp = if hasEntry
then bn
else nan;

def entryBarNum = if hasEntry and isNewEntry
then bn
else entryBarNum[1];

def isEntryBar = entryBarNum != entryBarNum[1];

def entryBarPL = if isEntryBar
then FPL
else entryBarPL[1];

def exitBarsTemp = if !hasEntry
and bn > entryBarsTemp[1]
then bn
else nan;

def exitBarNum = if !hasEntry and !IsNaN(exitBarsTemp[1])
then bn
else exitBarNum[1];

def isExitBar = exitBarNum != exitBarNum[1];

def exitBarPL = if isExitBar
then FPL
else exitBarPL[1];

def entryReturn = if isExitBar then exitBarPL - exitBarPL[1] else entryReturn[1];
def isWin = if isExitBar and entryReturn >= 0 then 1 else 0;
def isLoss = if isExitBar and entryReturn < 0 then 1 else 0;
def entryReturnWin = if isWin then entryReturn else entryReturnWin[1];
def entryReturnLoss = if isLoss then entryReturn else entryReturnLoss[1];
def entryFPLWins = if isWin then entryReturn else 0;
def entryFPLLosses = if isLoss then entryReturn else 0;
def entryFPLAll = if isLoss or isWin then entryReturn else 0;


#Counts
def entryCount = incrementValue(entryFPLAll);
def winCount = incrementValue(isWin);
def lossCount = incrementValue(isLoss);

def highestReturn = if entryReturnWin[1] > highestReturn[1]
then entryReturnWin[1]
else highestReturn[1];

def lowestReturn = if entryReturnLoss[1] < lowestReturn[1]
then entryReturnLoss[1]
else lowestReturn[1];


def winRate = round ( winCount / lossCount,2);
def winLossRatio = winCount / entryCount;
def avgReturn = TotalSum(entryFPLAll) / entryCount;
def avgWin = TotalSum(entryFPLWins) / winCount;
def avgLoss = TotalSum(entryFPLLosses) / lossCount;

#Drawdown
def lowestLowBarNumber = HighestAll(if FPL == lowFPL then bn else 0);
def highestHighBarNumber = HighestAll(if FPL == highFPL and FPL != FPL[1] then bn else 0);
def hasPrevLow = lowestLowBarNumber < highestHighBarNumber;

def isPeak = FPL > Highest(FPL[1], 12) and FPL > Highest(FPL[-12], 12);
def isTrough = FPL < Lowest(FPL[1], 12) and FPL < Lowest(FPL[-12], 12);
def _peak = if isPeak then FPL else nan;
def _trough = if isTrough then FPL else nan;
def peak = if !IsNaN(_peak) then FPL else peak[1];
def trough = if !IsNaN(_trough) then FPL else trough[1];
def peakBN = if isPeak then bn else peakBN[1];
def troughBN = if isTrough then bn else troughBN[1];

def ptvDrawdown = if !hasPrevLow then calculateDrawdown(lowFPL, highFPL) else ptvDrawdown[1];
def equityDrawdown = if isTrough and trough < peak then trough - peak else equityDrawdown[1];
def equityDrawdownPercent = if isTrough and trough < peak then calculateDrawdown(trough, peak) else equityDrawdownPercent[1];
def largestEquityDrawdown = LowestAll(equityDrawdown);
def largestEquityDrawdownPercent = LowestAll(equityDrawdownPercent);

def drawdown = if hasPrevLow
then largestEquityDrawdownPercent
else ptvDrawdown;

# Drawdown Durations
def equityDrawdownLength = if bn >= peakBN and bn <= troughBN
then troughBN - peakBN
else equityDrawdownLength[1];

def ptvDrawdownLength = if bn >= highestHighBarNumber and bn <= lowestLowBarNumber
then lowestLowBarNumber - highestHighBarNumber
else ptvDrawdownLength[1];

def equityDrawdownDuration = calculateDuration(HighestAll(equityDrawdownLength));
def equityDrawdownDurationFormat = formatDuration(HighestAll(equityDrawdownLength));
def ptvDrawdownDuration = calculateDuration(ptvDrawdownLength);

def ptvDrawdownDurationFormat = formatDuration(ptvDrawdownLength);

#Daily profit
def Midnight = if Active then FPL else Midnight[1];
def DaysProfit = Round(FPL - Midnight,2);

#Plots

AddChartBubble(!hideFPL and showEntryBubbles and isEntryBar, FPL, "Entry: " + entryBarPL + " | " + bn, Color.WHITE);
AddChartBubble(!hideFPL and showEntryBubbles and isExitBar, FPL, "Exit: " + exitBarPL,
color = if isWin
then Color.LIGHT_GREEN
else if isLoss
then Color.DARK_RED
else Color.GRAY,
up = no
);

#Labels

# test -----------------------------------------
def tmpMaxLossCount = if isLoss then tmpMaxLossCount[1] + 1 else 0;
#def maxLossCount = if tmpMaxLossCount > maxLossCount[1] then tmpMaxLossCount else MaxLossCount[1];
def maxLossCount = if iswin then 0 else if tmpMaxLossCount > maxLossCount[1] then tmpMaxLossCount else MaxLossCount[1];
AddLabel(yes,
text = "MaxLossCount " + maxLossCount,
color.ORANGE
);
# End test -------------------------------------


AddLabel(yes,
text = "LastEntry: " + AsPrice(entryPrice)
);

AddLabel(hasEntry,
text = "Current Trade % Return: " + AsPercent(cumsum),
color = if cumsum > 0
then Color.GREEN
else Color.RED
);

AddLabel(yes,
text = "Total Trades: " + entryCount,
color = Color.WHITE
);

AddLabel(yes,
text = "WinCount: " + winCount +
" | LossCount: " + lossCount +
" | WinRate: " + winRate,
color = if winRate >= targetWinRate
then Color.GREEN
else Color.RED
);

AddLabel(yes,
text = "W/L: " + AsPercent(winLossRatio),
color = if winLossRatio > targetWinLoss
then Color.GREEN
else Color.RED
);

AddLabel(yes,
text = "HighestReturn: " + AsDollars(highestReturn),
color = if highestReturn > 0
then Color.GREEN
else Color.RED
);

AddLabel(yes,
text = "LowestReturn: " + AsDollars(lowestReturn),
color = if lowestReturn > 0
then Color.GREEN
else Color.RED
);

AddLabel(yes,
text = "AvgReturn: " + AsDollars(avgReturn) +
" | AvgWin: " + AsDollars(avgWin) +
" | AvgLoss: " + AsDollars(avgLoss),
color = if avgReturn >= 0
then Color.LIGHT_GREEN
else Color.RED
);

AddLabel(yes,
text = "PeakToValley DD: " + AsPercent(drawdown) +
" | Duration: " + ptvDrawdownDuration +
if ptvDrawdownDurationFormat == 1
then " hours"
else if ptvDrawdownDurationFormat == 2
then " days"
else " mins" ,
color = if drawdown > 0
then Color.GREEN
else Color.RED
);


AddLabel(largestEquityDrawdown < 0,
text = "Largest Equity DD: " + AsDollars(largestEquityDrawdown) +
" | Duration: " + equityDrawdownDuration +
if equityDrawdownDurationFormat == 1
then " hours"
else if equityDrawdownDurationFormat == 2
then " days"
else " mins",
color = if largestEquityDrawdown > 0
then Color.GREEN
else Color.Dark_ORANGE
);

AddLabel(yes,
text = "P&L High" +
(if enableDebugging
then " at bar " + highBarNumber
else "") +
": " + AsDollars(highFPL),
color = Color.GREEN
);

AddLabel(yes,
text = "P&L Low" +
(if enableDebugging
then " at bar " + lowBarNumber
else "") +
": " + AsDollars(lowFPL),
color = Color.RED
);

AddLabel(yes,
text = "Days Profit: $" + DaysProfit,
color = if DaysProfit > 0
then Color.GREEN
else Color.RED
);

AddLabel(yes,
text = "Total Profit: " + AsDollars(FPL),
color = if FPL > 0
then Color.GREEN
else Color.RED
);

#debugging

#peaks & troughs
AddChartBubble(enableDebugging and isPeak, FPL,
text = "FPL: " + FPL
+ " | Peak: " + peak
+ " | Trough: " + trough[-1]
+ " | Drawdown: " + AsPercent(calculateDrawdown(trough, peak))
+ " | PeakBN: " + peakBN
+ " | BarNumber: " + bn,
color = Color.LIME
);

AddChartBubble(enableDebugging and isTrough, FPL,
text = "FPL: " + FPL
+ " | Peak: " + peak
+ " | Trough: " + trough
+ " | Drawdown: " + AsPercent(calculateDrawdown(trough, peak))
+ " | TroughBN: " + troughBN
+ " | BarNumber: " + bn,
color = Color.LIGHT_RED,
up = no
);

AddVerticalLine(enableDebugging and isEntryBar,
text = "EntryBarNum: " + entryBarNum
+ " | ExitBarNum: " + exitBarNum[-1]
+ " | BarNumber: " + bn,
color = Color.WHITE
);

AddVerticalLine(enableDebugging and isExitBar,
text = "EntryBarNum: " + entryBarNum[1]
+ " | ExitbarNum: " + exitBarNum
+ " | BarNumber: " + bn
+ " | EntryReturn: " + entryReturn,
color = if isWin
then Color.LIGHT_GREEN
else if isLoss
then Color.LIGHT_RED
else Color.LIGHT_GREEN
);
 
Last edited by a moderator:
Thanks again for all the hard work on this strategy. I've done well this week with it. I've noticed a few things back testing though.

1. I've removed CallBuy and PutBuy from the AddOrder to stop it from triggering a buy on the first red or blue candle to get a more accurate back test. Its like this now
#BUY ORDERS
AddOrder(OrderType.BUY_TO_OPEN, ShowOrders and (CallBuy[1] or CallBuy[2])or CallBuy[3] and low <= FastEMA1 and low >= FastEMA2, FastEMA1, 100, Color.GREEN, Color.LIGHT_GREEN);
AddOrder(OrderType.SELL_TO_OPEN, ShowOrders and (PutBuy[1] or PutBuy[2] or PutBuy[3]) and high >= FastEMA1 and high <=FastEMA2, FastEMA1, 100, Color.GREEN, Color.LIGHT_GREEN);
2. The AddOrder will trigger up to 3 candles after a Green or Blue candle even if a red candle appears. Can this be coded to reset once a red candle appears?
3. Also once a trade starts if the candle turn grey before red it will continue with a big loss. Can this be coded to sell on a grey candle as well?

Yxh4f2n.png


The labels above is for back testing. You can add it to your strategy. Its Extended Floating P/L and the link to it is https://usethinkscript.com/threads/...acktesting-data-utility-for-thinkorswim.1624/

You can probably add “ !CallSell “ in the code and it will not buy on that red candle with the big losing trade. Obviously!PutSell on the other buy order.

I don’t think the order will continue if you add the above. I’ll play with it in a minute

I honestly haven’t spent a whole lot of time on the backtesting portion as I can see the strategy itself works. Any other findings you have will be helpful!
 

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
372 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