1

Why are the up triangles, when the program is supposed to buy, not on the line when it crosses under, or in the other scenario, the down triangle, when the program is supposed to sell, not on the line when it crosses on top? The blue line is the price and the red line is the EMA, tracking the price.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import requests
plt.style.use("fivethirtyeight")


df = pd.read_csv("TSLA.csv")
df = df.set_index(pd.DatetimeIndex(df["Date"].values))

ShortEMA = df.Close.ewm(span=5, adjust = False).mean()
MiddleEMA = df.Close.ewm(span = 21, adjust = False).mean()
LongEMA = df.Close.ewm(span = 53, adjust = False).mean()

df['Short'] = ShortEMA
df['Middle'] = MiddleEMA
df['Long'] = LongEMA

def MyStrat(data):
    bought_list = []
    sold_list = []
    In = False
    Out = True
    for i in range(0, len(data)):
        if  data["Close"][i] > data["Short"][i] and In == False and Out == True:
            bought_list.append(data["Close"][i])
            sold_list.append(np.nan)
            In = True
            Out = False

        elif data["Close"][i] < data["Short"][i] and In == True and Out == False:
            sold_list.append(data["Close"][i])
            bought_list.append(np.nan)
            In = False
            Out = True

        else:
            bought_list.append(np.nan)
            sold_list.append(np.nan)

    return(bought_list,sold_list)

df["Bought"] = MyStrat(df)[0]
df["Sold"] = MyStrat(df)[1]
print(df)


plt.figure(figsize=(16, 5))
plt.title('Buy and Sell', fontsize = 18)
plt.plot(df['Close'], label = 'Close Price', color = 'blue', alpha = 0.35)
plt.plot(ShortEMA, label = 'Short', color = 'red', alpha = 0.35)
plt.scatter(df.index, df["Bought"], color = "purple", marker = "^", alpha = 1)
plt.scatter(df.index, df["Sold"], color = "blue", marker = "v", alpha = 1)
plt.xlabel("Date", fontsize = 18)
plt.ylabel("Close", fontsize = 18)
plt.show()

You can use this data for reference:

Date,Open,High,Low,Close,Adj Close,Volume
2022-01-06,1077.000000,1088.000000,1020.500000,1064.699951,1064.699951,30112200
2022-01-07,1080.369995,1080.930054,1010.000000,1026.959961,1026.959961,28054900
2022-01-10,1000.000000,1059.099976,980.000000,1058.119995,1058.119995,30605000
2022-01-11,1053.670044,1075.849976,1038.819946,1064.400024,1064.400024,22021100
2022-01-12,1078.849976,1114.839966,1072.589966,1106.219971,1106.219971,27913000
2022-01-13,1109.069946,1115.599976,1026.540039,1031.560059,1031.560059,32403300
2022-01-14,1019.880005,1052.000000,1013.380005,1049.609985,1049.609985,24308100
2022-01-18,1026.609985,1070.790039,1016.059998,1030.510010,1030.510010,22247800
2022-01-19,1041.709961,1054.670044,995.000000,995.650024,995.650024,25147500
2022-01-20,1009.729980,1041.660034,994.000000,996.270020,996.270020,23496200
2022-01-21,996.340027,1004.549988,940.500000,943.900024,943.900024,34472000
2022-01-24,904.760010,933.510010,851.469971,930.000000,930.000000,50521900
2022-01-25,914.200012,951.260010,903.210022,918.400024,918.400024,28865300
2022-01-26,952.429993,987.690002,906.000000,937.409973,937.409973,34955800
2022-01-27,933.359985,935.390015,829.000000,829.099976,829.099976,49036500
2022-01-28,831.559998,857.500000,792.010010,846.349976,846.349976,44929700
2022-01-31,872.710022,937.989990,862.049988,936.719971,936.719971,34812000
2022-02-01,935.210022,943.700012,905.000000,931.250000,931.250000,24379400
2022-02-02,928.179993,931.500000,889.409973,905.659973,905.659973,22264300
2022-02-03,882.000000,937.000000,880.520020,891.140015,891.140015,26285200
2022-02-04,897.219971,936.500000,881.169983,923.320007,923.320007,24541800
2022-02-07,923.789978,947.770020,902.710022,907.340027,907.340027,20331500
2022-02-08,905.530029,926.289978,894.799988,922.000000,922.000000,16909700
2022-02-09,935.000000,946.270020,920.000000,932.000000,932.000000,17419800
2022-02-10,908.369995,943.809998,896.700012,904.549988,904.549988,22042300
2022-02-11,909.630005,915.960022,850.700012,860.000000,860.000000,26548600
2022-02-14,861.570007,898.880005,853.150024,875.760010,875.760010,22585500
2022-02-15,900.000000,923.000000,893.380005,922.429993,922.429993,19095400
2022-02-16,914.049988,926.429993,901.210022,923.390015,923.390015,17098100
2022-02-17,913.260010,918.500000,874.099976,876.349976,876.349976,18392800
2022-02-18,886.000000,886.869995,837.609985,856.979980,856.979980,22833900
2022-02-22,834.130005,856.729980,801.099976,821.530029,821.530029,27762700
2022-02-23,830.429993,835.299988,760.559998,764.039978,764.039978,31752300
2022-02-24,700.390015,802.479980,700.000000,800.770020,800.770020,45107400
2022-02-25,809.229980,819.500000,782.400024,809.869995,809.869995,25355900
2022-02-28,815.010010,876.859985,814.710022,870.429993,870.429993,33002300
2022-03-01,869.679993,889.880005,853.780029,864.369995,864.369995,24922300
2022-03-02,872.130005,886.479980,844.270020,879.890015,879.890015,24881100
2022-03-03,878.770020,886.440002,832.599976,839.289978,839.289978,20541200
2022-03-04,849.099976,855.650024,825.159973,838.289978,838.289978,22333200
2022-03-07,856.299988,866.140015,804.570007,804.580017,804.580017,24164700
2022-03-08,795.530029,849.989990,782.169983,824.400024,824.400024,26799700
2022-03-09,839.479980,860.559998,832.010010,858.969971,858.969971,19728000
2022-03-10,851.450012,854.450012,810.359985,838.299988,838.299988,19549500
2022-03-11,840.200012,843.799988,793.770020,795.349976,795.349976,22272800
2022-03-14,780.609985,800.700012,756.039978,766.369995,766.369995,23717400
2022-03-15,775.270020,805.570007,756.570007,801.890015,801.890015,22280400
2022-03-16,809.000000,842.000000,802.260010,840.229980,840.229980,28009600
2022-03-17,830.989990,875.000000,825.719971,871.599976,871.599976,22194300
2022-03-18,874.489990,907.849976,867.390015,905.390015,905.390015,33408500
2022-03-21,914.979980,942.849976,907.090027,921.159973,921.159973,27327200
2022-03-22,930.000000,997.859985,921.750000,993.979980,993.979980,35289500
2022-03-23,979.940002,1040.699951,976.400024,999.109985,999.109985,40225400
2022-03-24,1009.729980,1024.489990,988.799988,1013.919983,1013.919983,22973600
2022-03-25,1008.000000,1021.799988,997.320007,1010.640015,1010.640015,20642900
2022-03-28,1065.099976,1097.880005,1053.599976,1091.839966,1091.839966,34168700
2022-03-29,1107.989990,1114.770020,1073.109985,1099.569946,1099.569946,24538300
2022-03-30,1091.170044,1113.949951,1084.000000,1093.989990,1093.989990,19955000
2022-03-31,1094.569946,1103.140015,1076.640015,1077.599976,1077.599976,16265600
2022-03-31,1094.569946,1103.139893,1076.640991,1077.599976,1077.599976,16330919
tdy
  • 36,675
  • 19
  • 86
  • 83

1 Answers1

1

The problem with this is that the point of intersection occurs between days, not on a specific day. As the data is not continuous, but rather just one point per business day, it is not possible to put the arrow on the intersection itself. I have enlarged a portion of the graph here so you can see what I mean. The change occurs between the 9th and 10th. The data is only on the 9th or the 10th, so the arrow is plotted, and the buy occurs, on the 10th.

Section of plot

The buy/sell is on the next possible day, causing the mis-alignment of the arrows.

Rawson
  • 2,637
  • 1
  • 5
  • 14
  • So if i were to get more frequent data then it would buy/sell as soon as the next data comes in? –  Apr 09 '22 at 18:03
  • Yes, you would need more frequent data to be able to get a closer alignment. For example, if you had 4 data points per day that would plot at 0, 0.25, 0.5, 0.75 of the day, you would find that the 0.75 would buy/sell in the two points of intersections in the image above (the first data point after the "event"). This would still not be perfect, but would be closer to the true time; the more frequent the data the closer the buy/sell will be to the intersection. – Rawson Apr 09 '22 at 19:18
  • As suggested in [this question](https://stackoverflow.com/questions/37576527/finding-the-point-of-intersection-of-two-line-graphs-drawn-in-matplotlib), you could probably interpolate the data to get an exact point (but this would only be useful for plotting, and wouldn't be relevant for your actual data (given that it will still be daily)). – Rawson Apr 09 '22 at 19:18
  • So when I come to putting the api in, i just need to make it buy/sell at the same time as when they cross over, could i do this buy putting them in the same line of code or would that still be delayed? –  Apr 09 '22 at 21:03
  • However after inspection, 2 days pass after the cross over in mid 2022-01-29, then 2022-01-30, nothing happens and only in 2022-01-31 does the symbol come up. I hope that the graph isn't how the API would take orders... I guess I would need to get market data every second, but that's normal I guess. –  Apr 09 '22 at 21:40
  • The 29th and 30th are not trading days, so don't have any data. – Rawson Apr 09 '22 at 21:45
  • I'm not sure I understand what you mean by api comment. As your code is at the moment, if you increase the frequency of the data (and then remember to alter your ewm span) the buy/sell signal will move closer and closer to the true crossing point. If the api gives you much higher-frequency data, then you shouldn't need to make any adjustments. I am not familiar with using apis to take orders, but if it is running your model (with the correct spans and everything) it should order on the next available data point from the cross-over point. – Rawson Apr 09 '22 at 21:48
  • Can i make it order on the cross over point? –  Apr 09 '22 at 21:58
  • That's not a question I can answer as yes or no, as I don't know about the api you are using. However, if the data is frequent enough, it will do. – Rawson Apr 09 '22 at 22:10