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

The up arrow is a different strategy. @chasebank the green bar you circled looks like it pulled back to the 5 EMA where the buy signal starts. Are you saying the buy signal triggered before it touched the 5 EMA?

I wouldn’t say it’s a different strategy per se. I think what happens is that the strategy triggers a buy and for some reason it plots the arrow for the entry on the next bar. I don’t know if this is so you can see it better, because I don’t know how to code it correctly or something else. The entry is correct. You can barely see his arrow pointing to the arrow of the entry which happened one bar before. If the trader knows the strategy and is following it correctly than they would have been in by the time they got the order entry line.

I think what he is saying is that the entry is impossible because the entry arrow is not even within the bar he circled, it is well below it.

Again, I don’t use the orders to trade, I just use them to backtest. You can even see the long bubble on the bar before.

@Fluideng i know you already know this. Just reiterating for future readers.
 
The up arrow is a different strategy. @chasebank the green bar you circled looks like it pulled back to the 5 EMA where the buy signal starts. Are you saying the buy signal triggered before it touched the 5 EMA?
I'm just trying to figure out why the strategy cannot enter at the open price of the bar following the signal.

@a1cturner @Fluideng FYI, i'm running the strategy live on a few tickers and it seems to be behaving exactly like the back tests on entry. I cannot say for exits quite yet as none of them have exited. Also note, I've turned off the take profit orders as well as I want to deal with one thing at a time.
 
I'm just trying to figure out why the strategy cannot enter at the open price of the bar following the signal.

@a1cturner @Fluideng FYI, i'm running the strategy live on a few tickers and it seems to be behaving exactly like the back tests on entry. I cannot say for exits quite yet as none of them have exited. Also note, I've turned off the take profit orders as well as I want to deal with one thing at a time.

Hopefully I’ll have Version 10 up no later than tomorrow. I think it will be a little better but we will see. The orders will most likely still be an issue for some but it will trade accurately
 
Hopefully I’ll have Version 10 up no later than tomorrow. I think it will be a little better but we will see. The orders will most likely still be an issue for some but it will trade accurately
So, this is definitely repainting on the sell bubble / order, I can't say for the buy quite yet. It received a sell signal, then it disappeared and switched to a go short signal on the same bar there after. In that case, the order cannot be placed until the painted bar is set and entry should be on the new bar opening price.
 
So, this is definitely repainting on the sell bubble / order, I can't say for the buy quite yet. It received a sell signal, then it disappeared and switched to a go short signal on the same bar there after. In that case, the order cannot be placed until the painted bar is set and entry should be on the new bar opening price.
I am addressing this in the new version. It won’t trigger a buy unless the buy criteria is met on the current bar and prior bar
 
Gotcha. I'll keep my eye out for the new version!

@chasebank The new version is posted above. If you want to code this somewhere else and want the buy orders to be 100% accurate but not trade the strategy as intended you can change the buy orders to open the trade at open[-1]. I think this reduces the profit to $22k in 90 days on TSLA last time I looked. Could be off on that number. Probably larger draw downs as well. This does not include any take profit orders. Still not shabby.

Maybe you could backtest entering the trade as soon as you get a buy trigger regardless of repainting. Maybe it’ll work out well 🤷🏻‍♂️
 
Alright Boys. Here is Version 10. I have made SIGNIFICANT changes which is why I am posting here first. I have changed, moved, deleted, added etc but the general idea is the same.

Some things to be aware of!!
#Default TimeFrame is now 5 Minutes​
#Green is Long and Red is Short​
#Added some wiggle room for the price getting to the 5EMA. This allows for more entries and hopefully a little earlier.​
#Cleaned up the chart a lot to only show what you need, the 5EMA. Everything is still there in the background and can be turned on as needed.​
#If you get a white arrow and the price is at, OR CLOSE, to the 5EMA than buy. If you get a Boolean Wedge than you are in the over extended area, consider selling. If you get a square than sell at the open of the next bar. Easy as that!​
#Due to the nature of this strategy, the orders are not going to be perfect but they are as perfect as they can be. 90 Day Back-Testing on TSLA showed a $67,627 Profit and this does not include selling at the take profit zone.​
Who knows what else I changed, lol.

My personal preferences. If I get a sell signal, I will wait a few seconds into the open of the following candle, where you would normally close. If the candle is green (for long) or red (for short) than don't sell. Also, if the price enters the over extended area before you have entered the trade than be very careful, especially in the mornings. I have seen the price enter that area in the morning and then shortly after, reverse the opposite direction. It does this more often than not from what I have seen (TSLA on 5/17/22).

Let me know what problems you encounter if any. I will update post 1 once I am comfortable replacing the old strategy.

http://tos.mx/s8GVFmP

d9I8SDF.png


Code:
#JT Newest Strategy Based on EMAs, TSI, Premarket Highs/Lows, and MACD
#VERSION 10 - 05/19/2022

#Notes

Declare Upper;

##################################################################
#                                OPTIONS                         #
##################################################################
input ShowTestBubbles = no;
input ShowFlexGridBackgroundColor = no;
input ShowColorDefLabels = yes;
input AlertOn = yes;
input Show200EMA = no;
input ShowEMACloud = no;
input ShowPreMarketCloud = no;
input ShowPreMarketLabel = yes;
input ShowPrevHighLowLabel = no;
input ShowBuySellBubbles = no;
input ShowOverExtCloud = no;
input ShowTkPftBubble = no;
input ShowOrders = no;
input ShowTkPftOrders = no;

##################################################################
#                                COLORS                          #
##################################################################
DefineGlobalColor("200EMA", createcolor (255, 255, 255));
DefineGlobalColor("CloudUp", createcolor (102, 255, 102));
DefineGlobalColor("CloudDown", createcolor (255, 102, 102));
DefineGlobalColor("OpenLongPosition", createcolor (0, 255, 0));
DefineGlobalColor("OpenShortPosition", createcolor (255, 0, 0));
DefineGlobalColor("HoldLongPosition", createcolor (153, 255, 153));
DefineGlobalColor("HoldShortPosition", createcolor (255, 153, 153));
DefineGlobalColor("SellPosition", createcolor (255, 0, 0));
DefineGlobalColor("TakeProfit", createcolor (255, 0, 255));
DefineGlobalColor("CriteriaNotMet", createcolor (102, 102, 102)); #(255, 255, 0)

##################################################################
#                                 TIMES                          #
##################################################################
#START AND END TIMES
input TimeFrame = {default "5-Min", "1-Min", "10-Min", "15-Min", "30-Min", "1-Hour"};
input PreMarketStart = 0700; #EST
input PreMarketEnd = 0929; #EST
input StartTime = 0930; #EST
input BuySignalDelay = 0;
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 "10-Min": LastCandleStop = 10;
        case "15-Min": LastCandleStop = 15;
        case "30-Min": LastCandleStop = 30;
        case "1-Hour": LastCandleStop = 60;
        default: LastCandleStop = 5;
        }

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                        #
##################################################################
#200 EMA
plot EMA200 = ExpAverage(HL2, 200);
EMA200.SetDefaultColor(globalcolor("200EMA"));
EMA200.HideBubble();
EMA200.sethiding(!Show200EMA);

#EMAS
input Ema1Length = 5;
input Ema2Length = 12;

plot EMA1 = ExpAverage(close, Ema1Length);
EMA1.SetStyle(Curve.Short_Dash);
EMA1.SetDefaultColor(globalcolor("CloudUp"));
EMA1.HideBubble();
plot EMA2 = ExpAverage(close, Ema2Length);
EMA2.SetDefaultColor(globalcolor("CloudDown"));
EMA2.HideBubble();
EMA2.sethiding(!ShowEMACloud);
AddCloud(if ShowEMACloud then EMA1 else double.nan, if ShowEMACloud then EMA2 else double.nan, globalcolor("CloudUp"), globalcolor("CloudDown"));

    #EMAS BULLISH OR BEARISH
    def EMABullish = EMA1 > EMA2;
    def EMABearish = EMA1 < EMA2;

        #EMA PERCENT SEPERATION
        def EMAPctBull = ((EMA1 / EMA2) * 100) - 100; #Distance Between EMA1 and EMA2
        def EMAPctBullRound = Round(EMAPctBull, 2);
        def EMAPctBear = ((EMA2 / EMA1) * 100) - 100; #Distance Between EMA2 and EMA1
        def EMAPctBearRound = Round(EMAPctBear, 2);

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

        def EMAPctBullish = EMAPctBullRound > EMASepThrHld and EMAPctBullRound >= EMAPctBullRound[1];
        def EMAPctBearish = EMAPctBearRound > EMASepThrHld and EMAPctBearRound >= EMAPctBearRound[1];
        #TESTING
        addchartbubble(ShowTestBubbles and EMAPctBullish, High * 1.005, EMAPctBullRound, color.dark_green, yes);
        addchartbubble(ShowTestBubbles and EMAPctBearish, Low * 0.995, EMAPctBearRound, color.dark_red, no);

            #EMA SELL SIGNALS
            def EMACrossDown = EMA1 crosses below EMA2;
            def EMACrossUp = EMA1 crosses above EMA2;

#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 = (MACDAverage > MACDAverage[1]) within 3 bars;
    def MACDBear = (MACDAverage < MACDAverage[1]) within 3 bars;

#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 > TSIRound[2]); #(TSIRound > 10)
    def TSIBear = (TSIRound < TSIRound[2]); #(TSIRound < -10)

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

##################################################################
#                          PREMARKET                             #
##################################################################
#PREMARKET HIGHS AND LOWS
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 = Pre_Market_High;
PreMarketHigh.SetStyle(curve.short_dash);
PreMarketHigh.SetDefaultColor(color.light_gray);
PreMarketHigh.Sethiding(!ShowPreMarketCloud);
plot PreMarketLow = Pre_Market_Low;
PreMarketLow.SetStyle(curve.short_dash);
PreMarketLow.SetDefaultColor(color.light_gray);
PreMarketLow.Sethiding(!ShowPreMarketCloud);
AddCloud(if ShowPreMarketCloud then PreMarketHigh else double.nan, if ShowPreMarketCloud then PreMarketLow else double.nan, 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 = close > Pre_Market_High;
    def PreMarketBear = close < Pre_Market_Low;

        #PREMARKET HIGH/LOW SELL SIGNAL
        def PreMarketBullSell = PreMarketBull[1] and low < Pre_Market_High;
        def PreMarketBearSell = PreMarketBear[1] and high > Pre_Market_Low;

##################################################################
#                      YESTERDAY HIGH/LOW                        #
##################################################################
def PrevHigh = high(period = "day")[1];
def PrevLow = low(period = "day")[1];

AddLabel(if ShowPrevHighLowLabel then 1 else 0, "   ", color.black);
AddLabel(if ShowPrevHighLowLabel then 1 else 0, "Prev High " + "$ " + PrevHigh + " ", color.gray);
AddLabel(if ShowPrevHighLowLabel then 1 else 0, "Prev Low " + "$ " + PrevLow + " ", color.gray);

##################################################################
#                               SIGNALS                          #
##################################################################
#INDICATOR BUY SIGNALS
def LongBuyInd = TradingDay and EMABullish and EMAPctBullish and MACDBull and TSIBull and PreMarketBull;
def ShortBuyInd = TradingDay and EMABearish and EMAPctBearish and MACDBear and TSIBear and PreMarketBear;

#INDICATOR ENTRY SIGNALS
def LongEntryInd = (LongBuyInd[1] or LongBuyInd[2]) and LongBuyInd and low <= (EMA1 * 1.0025);
def ShortEntryInd = (ShortBuyInd[1] or ShortBuyInd[2]) and ShortBuyInd and high >= (EMA1 * 0.9975);

#INDICATOR HOLD SIGNALS
def LongHoldInd = TradingDayExt and (LongBuyInd[1] or LongHoldInd[1]);
def ShortHoldInd = TradingDayExt and (ShortBuyInd[1] or ShortHoldInd[1]);

##################################################################
#         ADDED FAST EMA PCT HERE BASED OFF BUY SIGNAL           #
##################################################################
            def EMAPctAtLongBuy = if LongEntryInd then EMAPctBullRound else EMAPctAtLongBuy[1];
            def EMAPctAtShortBuy = if ShortEntryInd then EMAPctBearRound else EMAPctAtShortBuy[1];

                #FAST EMA CLOUD SELL TRIGGER BASED OFF BUY INDICATOR
                input EMAPctDecFromBuy = 0.6;
                def LongEMAPctSell = EMAPctBullRound < (EMAPctAtLongBuy * EMAPctDecFromBuy);
                def ShortEMAPctSell = EMAPctBearRound < (EMAPctAtShortBuy * EMAPctDecFromBuy);

##################################################################
#                         SIGNALS CONT.                          #
##################################################################
    #SELL SIGNALS
    def LongPriceActSell = low < low[4];
    def ShortPriceActSell = high > high[4];
    def LongSellInd = TradingDayExt and (EMACrossDown or TSICrossDown or LongEMAPctSell or LongPriceActSell);
    def ShortSellInd = TradingDayExt and (EMACrossUp or TSICrossUp or ShortEMAPctSell or ShortPriceActSell);
        #TESTING
        addchartbubble(ShowTestBubbles and TSICrossDown, High * 1.005, "T-Dn", color.dark_green, yes);
        addchartbubble(ShowTestBubbles and TSICrossUp, Low * 0.995, "T-Up", color.dark_red, no);
        addchartbubble(ShowTestBubbles and EMACrossDown, High * 1.005, "E-X-Dn", color.dark_green, yes);
        addchartbubble(ShowTestBubbles and EMACrossUp, Low * 0.995, "E-X-Up", color.dark_red, no);
        addchartbubble(ShowTestBubbles and LongEMAPctSell, High * 1.005, "E-Pct-Dn", color.dark_green, yes);
        addchartbubble(ShowTestBubbles and SHortEMAPctSell, Low * 0.995, "E-Pct-Up", color.dark_red, no);

    #HOLD SIGNALS
    def LongHoldInd2 = LongHoldInd and !LongSellInd;
    def ShortHoldInd2 = ShortHoldInd and !ShortSellInd;

##################################################################
#                                 BARS                           #
##################################################################
AssignPriceColor(if LongBuyInd then GlobalColor("OpenLongPosition") else if ShortBuyInd then GlobalColor("OpenShortPosition") else if LongHoldInd2 then GlobalColor("HoldLongPosition") else if ShortHoldInd2 then GlobalColor("HoldShortPosition") else GlobalColor("CriteriaNotMet"));

##################################################################
# EMA TAKE PROFIT CLOUD (IDENTIFY IF PRICE IS EXTENDED FROM EMAS)#
##################################################################
            def OvrExtUp1 = if ShowOverExtCloud and SignalStart and TradingDayExt and (LongEntryInd or LongHoldInd2) then EMA1 * 1.01 else Double.NaN;
            def OvrExtUp2 = if ShowOverExtCloud and SignalStart and TradingDayExt and (LongEntryInd or LongHoldInd2) then EMA1 * 1.02 else Double.NaN;
            AddCloud(OvrExtUp1, OvrExtUp2, color.light_green, color.light_green);
            def OvrExtDn1 = if ShowOverExtCloud and SignalStart and TradingDayExt and (ShortEntryInd or ShortHoldInd2) then EMA1 * 0.99 else Double.NaN;
            def OvrExtDn2 = if ShowOverExtCloud and SignalStart and TradingDayExt and (ShortEntryInd or ShortHoldInd2) then EMA1 * 0.98 else Double.NaN;
            AddCloud(OvrExtDn1, OvrExtDn2, color.light_green, color.light_green);

##################################################################
#                                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, "CLOUD", if EMABullish then GlobalColor("OpenLongPosition") else if EMABearish then GlobalColor("OpenShortPosition") else color.gray);
AddLabel(yes, "EMA SEP", if EMAPctBullish then GlobalColor("OpenLongPosition") else if EMAPctBearish 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/POINTS FOR BUY/SELL                #
##################################################################
#BUY
def LongBuyBub = LongEntryInd;
addchartbubble(ShowBuySellBubbles and LongBuyBub, High * 1.005, "Long", color.green, yes);
def ShortBuyBub = ShortEntryInd;
addchartbubble(ShowBuySellBubbles and ShortBuyBub, Low * 0.995, "Short", color.red, no);

plot LongBuyPoint = if LongBuyBub then EMA1 else double.nan;
LongBuyPoint.SetDefaultColor(color.white);
LongBuyPoint.SetPaintingStrategy(PaintingStrategy.Arrow_Up);
LongBuyPoint.SetLineWeight(5);
LongBuyPoint.HideBubble();
plot ShortBuyPoint = if ShortBuyBub then EMA1 else double.nan;
ShortBuyPoint.SetDefaultColor(color.white);
ShortBuyPoint.SetPaintingStrategy(PaintingStrategy.Arrow_Down);
ShortBuyPoint.SetLineWeight(5);
ShortBuyPoint.HideBubble();

#SELL
def LongSellBub = (LongEntryInd[1] or LongHoldInd2[1]) and (LongEntryInd[2] or LongHoldInd2[2]) and LongSellInd;
addchartbubble(ShowBuySellBubbles and LongSellBub, High * 1.005, "Sell", color.red, yes);
def ShortSellBub = (ShortEntryInd[1] or ShortHoldINd2[1]) and (ShortEntryInd[2] or ShortHoldINd2[2]) and ShortSellInd;
addchartbubble(ShowBuySellBubbles and ShortSellBub, Low * 0.995, "Sell", color.green, no);

plot LongSellPoint = if LongSellBub then Close else double.nan;
LongSellPoint.SetDefaultColor(color.red);
LongSellPoint.SetPaintingStrategy(PaintingStrategy.Squares);
LongSellPoint.SetLineWeight(5);
LongSellPoint.HideBubble();
plot ShortSellPoint = if ShortSellBub then Close else double.nan;
ShortSellPoint.SetDefaultColor(color.green);
ShortSellPoint.SetPaintingStrategy(PaintingStrategy.Squares);
ShortSellPoint.SetLineWeight(5);
ShortSellPoint.HideBubble();

#TAKE PROFIT
def LongTkPftBub = TradingDayExt and (LongEntryInd or LongHoldInd2) and high > EMA1 * 1.01;
addchartbubble(ShowTkPftBubble and LongTkPftBub, high * 1.001, "Tk Pft", GlobalColor("TakeProfit"), yes);
def ShortTkPftBub = TradingDayExt and (ShortEntryInd or ShortHoldInd2) and low < EMA1 * 0.99;
addchartbubble(ShowTkPftBubble and ShortTkPftBub, low * 0.999, "Tk Pft", GlobalColor("TakeProfit"), no);

plot LongTkPftPoint = if LongTkPftBub then High else double.nan;
LongTkPftPoint.SetDefaultColor(color.green);
LongTkPftPoint.SetPaintingStrategy(PaintingStrategy.Boolean_Wedge_Up);
LongTkPftPoint.SetLineWeight(5);
LongTkPftPoint.HideBubble();
plot ShortTkPftPoint = if ShortTkPftBub then Low else double.nan;
ShortTkPftPoint.SetDefaultColor(color.red);
ShortTkPftPoint.SetPaintingStrategy(PaintingStrategy.Boolean_Wedge_Down);
ShortTkPftPoint.SetLineWeight(5);
ShortTkPftPoint.HideBubble();

##################################################################
#                             STOP LOSS                          #
##################################################################
def longstop = if (open < close) then open else close;
def shortstop = if (open > close) then open else close;
addlabel(if (LongEntryInd or LongHoldInd2) then yes else no, "STOP $ " + longstop[4] + " ", color.white);
addlabel(if (ShortEntryInd or ShortHoldInd2) then yes else no, "STOP $ " + shortstop[4] + " ", color.white);

##################################################################
#                                ORDERS                          #
##################################################################
#BUY ORDERS
AddOrder(OrderType.BUY_TO_OPEN, ShowOrders and LongEntryInd, EMA1 * 1.0025, 100, Color.GREEN, Color.LIGHT_GREEN);
AddOrder(OrderType.SELL_TO_OPEN, ShowOrders and ShortEntryInd, EMA1 * 0.9975, 100, Color.GREEN, Color.LIGHT_GREEN);

#SELL ORDERS
AddOrder(OrderType.SELL_TO_CLOSE, ShowOrders and ShowTkPftOrders and LongTkPftBub, high * 0.999, 100, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.SELL_TO_CLOSE, ShowOrders and (LongSellInd or EndDay[-1]), open[-1], 100, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, ShowOrders and ShowTkPftOrders and ShortTkPftBub, low * 1.001, 100, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, ShowOrders and (ShortSellInd or EndDay[-1]), open[-1], 100, Color.RED, Color.LIGHT_RED);
##################################################################
#                                ALERTS                          #
##################################################################
Alert(AlertOn and (LongSellBub or ShortSellBub or LongTkPftBub or ShortTkPftBub), "SELL" + GetSymbol(), Alert.BAR, Sound.Bell);
Alert(AlertOn and (LongBuyInd or ShortBuyInd), "BUY" + GetSymbol(), Alert.BAR, Sound.Chimes);

##################################################################
#                       CANDLE COLOR LABEL                       #
##################################################################
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, "No Criteria", GlobalColor("CriteriaNotMet"));

##################################################################
#                BACKGROUND COLOR FOR FLEX GRID                  #
##################################################################
AssignBackgroundColor(if ShowFlexGridBackgroundColor and LongBuyInd then GlobalColor("OpenLongPosition") else if ShowFlexGridBackgroundColor and ShortBuyInd then GlobalColor("OpenShortPosition") else if ShowFlexGridBackgroundColor and (LongTkPftBub or ShortTkPftBub) then GlobalColor("TakeProfit") else color.current);
Excited to try it out.

For your order quantity, use the following code and replace '100' units with the variable. It will use $10k as funding the whole time so you can see return in relative %, not relative to how many shares you purchase.

def orderQuantity = Round(10000 / open, 0);

Keep working!
 
Excited to try it out.

For your order quantity, use the following code and replace '100' units with the variable. It will use $10k as funding the whole time so you can see return in relative %, not relative to how many shares you purchase.

def orderQuantity = Round(10000 / open, 0);

Keep working!
90 Days - $10,000

TSLA - $7,585.51
FB - $1,740.19
AAPL - $67.23
AMZN - $2,467
GOOGL - $1,085.37
MSFT - $264.02
TSM - $734.10
AMD - $7,016.65
BABA - $1,841.80
SPY - $132.45
QQQ - $77.55

All over the place but all profitable at least
 
90 Days - $10,000

TSLA - $7,585.51
FB - $1,740.19
AAPL - $67.23
AMZN - $2,467
GOOGL - $1,085.37
MSFT - $264.02
TSM - $734.10
AMD - $7,016.65
BABA - $1,841.80
SPY - $132.45
QQQ - $77.55

All over the place but all profitable at least

After spending like 3 days looking at this thing, I don't think the newest iteration is any different. All the scripts suffer from future bias and are on paper profitable because they are looking into the future. At least in terms of how the backtest orders are placed.

I spent $250k on consulting and dev time building algos over the last few years. Made a bunch of money trading futures, lost a bunch of money trading futures. I got lucky to break even. It all started from a script I found here that took me down the rabbit hole. It was a hull moving avg 'holy grail' algo from what i remember. My point is these entries are not even close to real. If you cannot automate a strategy, you're just using colors on a chart to gamble. Gambling is fun but making sure money is more fun.

I hope I'm misinterpreting your code and you know something I don't. The basic entry logic and exit logic is fine but you cannot manipulate the entry price. You have to use open[-1] in TOS and mentally account for some slippage. If you try and use this chart live, the EMA cannot and will not stay stagnant in the current candle that's updating, which it shouldn't, and therefore you cannot make an entry until the candle is closed. Right now you're entering trades at some percent relative to current candles EMA, based on last candles buy trigger. You cannot go in the past and get the price of what it was. This is future telling bias. The current candle EMA isn't calculated until the current candle is closed. Does that make sense?

I'm happy to hop on a skype call and chat. I sure hope I'm wrong and you've figured it out though!
 
After spending like 3 days looking at this thing, I don't think the newest iteration is any different. All the scripts suffer from future bias and are on paper profitable because they are looking into the future. At least in terms of how the backtest orders are placed.

I spent $250k on consulting and dev time building algos over the last few years. Made a bunch of money trading futures, lost a bunch of money trading futures. I got lucky to break even. It all started from a script I found here that took me down the rabbit hole. It was a hull moving avg 'holy grail' algo from what i remember. My point is these entries are not even close to real. If you cannot automate a strategy, you're just using colors on a chart to gamble. Gambling is fun but making sure money is more fun.

I hope I'm misinterpreting your code and you know something I don't. The basic entry logic and exit logic is fine but you cannot manipulate the entry price. You have to use open[-1] in TOS and mentally account for some slippage. If you try and use this chart live, the EMA cannot and will not stay stagnant in the current candle that's updating, which it shouldn't, and therefore you cannot make an entry until the candle is closed. Right now you're entering trades at some percent relative to current candles EMA, based on last candles buy trigger. You cannot go in the past and get the price of what it was. This is future telling bias. The current candle EMA isn't calculated until the current candle is closed. Does that make sense?

I'm happy to hop on a skype call and chat. I sure hope I'm wrong and you've figured it out though!
Instead the order saying open[-1], is there any other way you can think to code "if there is a long entry indicator on the previous bar and I am not already in a trade than enter when the price comes within 0.0025 of the 5EMA, regardless if this results in a repainted candle or not or wether the price is moving up or down"

Alternatively, can we define the state of the candle at open? Was the price at the 5EMA or was it not? Was there a sell signal that turned into a hold signal? etc. It would be nice to be able to know what the candle looked like right at open so I could be super accurate but I don't think that is possible.
 
Instead the order saying open[-1], is there any other way you can think to code "if there is a long entry indicator on the previous bar and I am not already in a trade than enter when the price comes within 0.0025 of the 5EMA, regardless if this results in a repainted candle or not or wether the price is moving up or down"

Alternatively, can we define the state of the candle at open? Was the price at the 5EMA or was it not? Was there a sell signal that turned into a hold signal? etc. It would be nice to be able to know what the candle looked like right at open so I could be super accurate but I don't think that is possible.
To answer your first question, no, you cannot. The 5EMA of the current bar isn't set in stone until the candle is closed. I'm sure we could come up with some logic to see if it reached the 5EMA mid candle while the 5EMA was moving and fire it but what we couldn't do is figure out all the candles in which it didn't fire because the entry logic repainted. This is where the problem lies.

To answer your 2nd question, it's probably not possible in TOS the was thinkscript was designed. That's why we moved to Ninjatrader and custom servers. TOS would work the way you like while running it live, however, in any backtest, it will not.
 
Hello, I was trying to evaluate this and was wondering if there's a reason why it would behave differently in OnDemand mode.
Indicators bubbles and orders don't seem to show up consistently.

For your order quantity, use the following code and replace '100' units with the variable. It will use $10k as funding the whole time so you can see return in relative %, not relative to how many shares you purchase.
def orderQuantity = Round(10000 / open, 0);
But then I assume for closing orders we need to "remember" the quantity we used at the last open order right?
 
Hello, I was trying to evaluate this and was wondering if there's a reason why it would behave differently in OnDemand mode.
Indicators bubbles and orders don't seem to show up consistently.


But then I assume for closing orders we need to "remember" the quantity we used at the last open order right?
Ya, you're right about order quantity. I forgot how TOS 'remembers' things candle to candle. Um, maybe just a stock # of shares is a better number to look at.
 
Just for fun I created a new type of order. Pretty sure this could be accomplished with a trailing stop on the buy and sell when the price gets back to the 5EMA. Super easy trade, takes 5-15 minutes. Happens maybe once or twice a day if that. Results would be better if you just waited til after 9:00 EST.

This is just for fun but very interesting to look at. TSLA made over $74k in 90 days.

The price always come back to the 5EMA.

AddOrder(OrderType.BUY_TO_OPEN, ShortTkPftBub, low * 1.0025, 100, Color.GREEN, Color.LIGHT_GREEN);
AddOrder(OrderType.SELL_TO_OPEN, LongTkPftBub, high * 0.9975, 100, Color.GREEN, Color.LIGHT_GREEN);

def SellShortTkPft = if ShortTkPftBub within 3 bars and high > EMA1 then EMA1 else double.nan;
def SellLongTkPft = if LongTkPftBub within 3 bars and low < EMA1 then EMA1 else double.nan;

AddOrder(OrderType.SELL_TO_CLOSE, SellShortTkPft, EMA1, 100, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, SellLongTkPft, EMA1, 100, Color.RED, Color.LIGHT_RED);
 
No, the pre-defined orderQuantity goes into both the buy and sell orders. At the time of purchase.
def orderQuantity = Round(10000 / open, 0);

What he's saying is if you took $10,000 and had a 10% loss, now you have $9000. The next trade will trade $10,000. Now that I think about it, I'd like each trade to be a constant $ denomination so you can analyze the return. Otherwise, you'd be compounding your estimation. Just need to know what you're analyzing.

EDIT: So, yes, I think the original code is working as should.
 
Just for fun I created a new type of order. Pretty sure this could be accomplished with a trailing stop on the buy and sell when the price gets back to the 5EMA. Super easy trade, takes 5-15 minutes. Happens maybe once or twice a day if that. Results would be better if you just waited til after 9:00 EST.

This is just for fun but very interesting to look at. TSLA made over $74k in 90 days.

The price always come back to the 5EMA.

AddOrder(OrderType.BUY_TO_OPEN, ShortTkPftBub, low * 1.0025, 100, Color.GREEN, Color.LIGHT_GREEN);
AddOrder(OrderType.SELL_TO_OPEN, LongTkPftBub, high * 0.9975, 100, Color.GREEN, Color.LIGHT_GREEN);

def SellShortTkPft = if ShortTkPftBub within 3 bars and high > EMA1 then EMA1 else double.nan;
def SellLongTkPft = if LongTkPftBub within 3 bars and low < EMA1 then EMA1 else double.nan;

AddOrder(OrderType.SELL_TO_CLOSE, SellShortTkPft, EMA1, 100, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, SellLongTkPft, EMA1, 100, Color.RED, Color.LIGHT_RED);
So... let's look at the entry.

def ShortTkPftBub = TradingDayExt and (ShortEntryInd or ShortHoldInd2) and low < EMA1 * 0.99;

It's looking at current candle situation. So let's say we're on 5 minute chart and at 5:01 ShortTkPftBub is true. We're all set to short. The low is less than the current EMA times 99% plus whatever checks you have. Now, at 5:04 the stock jumps on twitter news and now jumped up 100$ in price. Now, with 100% certainty, the low is still lower than 99% EMA. So, at the end of the candle, when the trade executes, at 5:04:59seconds, the low * 1.0025 is unattainable as an entry.

I'm trying to explain, the 5EMA that's triggering the order doesn't exist. The reason in TOS why you have to use open[-1] for entries and exits, which is using the price of the future candle open to execute a trade called on the current candle, is because how thinkscript works. If you watched your strategy live, you'd see your entries happen, then disappear when the price changes.

Thinkscript is a really strange language / compiles awkwardly. It's a particular programming language that's somewhat easy to read but really difficult to work with. Basically, Thinkscript executes on each candle over and over until the candle completes.

Does that make sense? Admin, chime in here? I'm 99% sure I'm correct but willing to be told otherwise.
 
I believe this works? Although it makes each opening trade the size of the initial amount, so there's no compounding effect over time. I assume if the goal is to compare strategies it's fair though.

Code:
input tradeAmount = 10000;
def opening = LongEntryInd Or ShortEntryInd;
def orderQuantity = if (opening) then Round(tradeAmount / open, 0) else orderQuantity[1];

#OPEN ORDERS
AddOrder(OrderType.BUY_TO_OPEN, ShowOrders and LongEntryInd, EMA1 * 1.0025, orderQuantity, Color.GREEN, Color.LIGHT_GREEN);
AddOrder(OrderType.SELL_TO_OPEN, ShowOrders and ShortEntryInd, EMA1 * 0.9975, orderQuantity, Color.GREEN, Color.LIGHT_GREEN);

#CLOSE ORDERS
AddOrder(OrderType.SELL_TO_CLOSE, ShowOrders and ShowTkPftOrders and LongTkPftBub, high * 0.999, orderQuantity, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.SELL_TO_CLOSE, ShowOrders and (LongSellInd or EndDay[-1]), open[-1], orderQuantity, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, ShowOrders and ShowTkPftOrders and ShortTkPftBub, low * 1.001, orderQuantity, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, ShowOrders and (ShortSellInd or EndDay[-1]), open[-1], orderQuantity, Color.RED, Color.LIGHT_RED);
 
I believe this works? Although it makes each opening trade the size of the initial amount, so there's no compounding effect over time. I assume if the goal is to compare strategies it's fair though.

Code:
input tradeAmount = 10000;
def opening = LongEntryInd Or ShortEntryInd;
def orderQuantity = if (opening) then Round(tradeAmount / open, 0) else orderQuantity[1];

#OPEN ORDERS
AddOrder(OrderType.BUY_TO_OPEN, ShowOrders and LongEntryInd, EMA1 * 1.0025, orderQuantity, Color.GREEN, Color.LIGHT_GREEN);
AddOrder(OrderType.SELL_TO_OPEN, ShowOrders and ShortEntryInd, EMA1 * 0.9975, orderQuantity, Color.GREEN, Color.LIGHT_GREEN);

#CLOSE ORDERS
AddOrder(OrderType.SELL_TO_CLOSE, ShowOrders and ShowTkPftOrders and LongTkPftBub, high * 0.999, orderQuantity, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.SELL_TO_CLOSE, ShowOrders and (LongSellInd or EndDay[-1]), open[-1], orderQuantity, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, ShowOrders and ShowTkPftOrders and ShortTkPftBub, low * 1.001, orderQuantity, Color.RED, Color.LIGHT_RED);
AddOrder(OrderType.BUY_TO_CLOSE, ShowOrders and (ShortSellInd or EndDay[-1]), open[-1], orderQuantity, Color.RED, Color.LIGHT_RED);

Ya that works for compound numbers. Invest 10k, it get's 50% return, now it invests $15k on next candle. Not good IMO to look at returns analysis.
 

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

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
298 Online
Create Post

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