Normalizing Stock data for Machine Learning

When analyzing historical time frame data in machine learning it needs to be normalized. In this code example, I will show how to get S&P data then convert it to a percent of daily increase/decrease as well as a logarithmic daily increase/decrease.

The first part of this code will use yfinance as our datasource.

#we're going to use yfinance as our data source
!pip install yfinance --upgrade --no-cache-dir

import pandas as pd
import numpy as np
import yfinance as yf

Next, we’re going to create a dataframe called df and download SPY data from 2000 to it.

#Here we're creating a dataframe for spy data from 2000-current
df = yf.download('spy',
  start='2000-01-01',
  end='2020-08-21',
  progress=True)
  #dauto_adjust=True,
  #actions='inline',) #adjust for stock splits and dividends
#print the dataframe to see what lives in it
print(df)

Finally, we’ll print the result of df so you can get an idea of what is inside of it.

We’re going to drop all the columns except Adj Close. Then we’ll rename it adj_close. Next, we’ll create a column labeled simple_rtn. This is the daily simple return or percent increase/decrease. The next line of code creates a logarithmic increase/decrease. Logarithmic gives equal bearing to the Y-axis and can be defined as follows, “A logarithmic price scale uses the percentage of change to plot data points, so, the scale prices are not positioned equidistantly. A linear price scale uses an equal value between price scales providing an equal distance between values.”

#only keep adj close
df = df.loc[:, ['Adj Close']]
df.rename(columns={'Adj Close':'adj_close'}, inplace=True)
#create column simple return
df['simple_rtn'] = df.adj_close.pct_change()
#create column logrithmic returns
df['log_rtn'] = np.log(df.adj_close/df.adj_close.shift(1))
print(df)

This next command just analyzes the data so you can spot-check what you’ve created.

#here we can analyze our data
df.info()

This next section describes what the daily increase/decrease of the SPY looks like. You can see statistically relevant information about S&P here.

#get statistical data on the data frame
df.describe()

Next, we can see a distribution of adjustable close, logarithmic return, and simple return.

#view chart of data to get an overview of what lives in the data
import matplotlib.pyplot as plt
df.hist(bins=50, figsize=(20,15))
plt.show()

This is all for data normalization. You can now apply different algorithmic analyses to the data.

Memory handler errors in MT4 while importing history files or csv files

I no longer trade using Metatrader. I noticed users kept hitting an invalid link on my website to this search phrase. So the purpose of this post is to catch those invalid links related to Metatrader. I would recommend learning Python and custom developing your algorithms. It will be much more rewarding.

If you have issues with Memory handler errors in MT4 it is because you’re trying to convert too many symbols at the same time. Close all of your charts and only leave open the pair you’re working with. When you’re done close it and go on to the next. This will get rid of the memory errors that MT4 complains about once terminal.exe starts to use more than 1GB of memory.

Attached are zip files I had or that I was working on for Metatrader. I don’t know if they’re up to date, if they work, or support them in any form.

Monitor Account Balance and Send Email Alerts in Metatrader When Account Drops Below Threshold

I no longer trade using Metatrader. I noticed users kept hitting an invalid link on my website to this search phrase. So the purpose of this post is to catch those invalid links related to Metatrader. I would recommend learning Python and custom developing your algorithms. It will be much more rewarding.

I had a strategy that I programmed awhile ago that completely drained my account. The strategy itself was fine. In fact it was doing so good I decided to apply it from some of my currency pairs to XAU/USD. After applying I caught a flight to LAX to pick up a Porsche I had found online. I had never traded gold before but judging from the backtest it should have performed relatively well. The problem was I did not anticipate the large spread on gold. The spread was enough to send my strategy constantly opening and closing positions. The buy rules and sell rules were being met because of the huge spread. Once I landed I had picked up the Porsche and headed to my hotel, not realizing at the time I had left my briefcase and laptop in the back of the taxi that I caught at LAX. When I arrived at my hotel I checked my phone only to realize one of my accounts was down around 70%, only 30% of my capital remaining. I immediately freaked out and started my investigation. It was then I realized the large spread in gold was constantly opening and closing positions. Costing me the spread every 5 minutes or so. I called Oanda as I then realized I lost my laptop I could not shut off the robot. Closing the trades manually from my phone only made the account drain faster.

Now you see my reason for writing this code. The purpose of it is to grab your account balance at a specific time and then if it drops below a threshold to send an email notification. This code is in mqh format. Which is an include file. The reason for this is so that it can be applied to any expert advisor.


//+------------------------------------------------------------------+
//| DailyBalanceCheck.mq4 |
//| Copyright © 2011, Jeremy R. Whittaker |
//| http://www.JeremyWhittaker.com |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, Jeremy R. Whittaker"
#property link "http://www.JeremyWhittaker.com"

double todaysBalance, dDouble;
int iHandle, iErrorCode;
extern string sFileName=”dailyBalance.csv”;
int iDecimalPlaces=2;
int sendWarningCount, sendBalanceCount;

void dailyBalanceCheck(){
int count;
double onePercent;

if(todaysBalance<1){
fnReadFile();
todaysBalance=dDouble;
}

if(Hour()==16 && Minute()==59){
count=0;
sendWarningCount=0;
sendBalanceCount=0;
}

if(Hour()==1700 && Minute()==0){
if(count==0){
todaysBalance=AccountBalance();
dDouble=todaysBalance;
fnWriteFile();
if(sendBalanceCount<1){
SendMail(“Account Update”,”Good evening Mr. Whittaker todays balance is “+todaysBalance+”. Your current account equity is “+AccountEquity());
Print(“Sending Balance Email”);
sendBalanceCount=sendBalanceCount+1;
}
count=count+1;
}
}

onePercent=todaysBalance*0.01;

if(AccountEquity() SendMail(“Warning account equity down 1%”,”Account Balance at 5PM was “+todaysBalance+”. Now it is “+AccountEquity());
Print(“Sending Warning Email”);
sendWarningCount=sendWarningCount+1;
}
return(false);
}

//+——————————————————————+
bool fnReadFile()
{
iHandle = FileOpen(sFileName,FILE_CSV|FILE_READ,’;’);
if(iHandle < 1)
{
iErrorCode = GetLastError();
if (iErrorCode == 4103)
Print(“File not found”);
else
Print(“Error reading file: “,iErrorCode);
return(false);
}
dDouble = StrToDouble(FileReadString(iHandle));
FileClose(iHandle);
return(true);
}

//+------------------------------------------------------------------+
bool fnWriteFile()
{
iHandle = FileOpen(sFileName,FILE_CSV|FILE_WRITE,';');
if(iHandle < 1)
{
iErrorCode = GetLastError();
Print("Error updating file: ",iErrorCode);
return(false);
}
FileWrite(iHandle,DoubleToStr(dDouble,iDecimalPlaces));
FileClose(iHandle);
return(true);
}
//+------------------------------------------------------------------+

Attached are zip files I had or that I was working on for Metatrader. I don’t know if they’re up to date, if they work, or support them in any form.

Whittaker hourly ATR indicator for Metatrader

I no longer trade using Metatrader. I noticed users kept hitting an invalid link on my website to this search phrase. So the purpose of this post is to catch those invalid links related to Metatrader. I would recommend learning Python and custom developing your algorithms. It will be much more rewarding.

Attached are zip files I had or that I was working on for Metatrader. I don’t know if they’re up to date, if they work, or support them in any form.