<jupyter_start><jupyter_text>FOREX PREDICTIONS USING A GRU, AND A GRU-LSTM MODEL BY <NAME> We install the required libraries<jupyter_code>!mkdir patterns
!mkdir dataframes
#!pip install dataframe-sql
#!conda install ibis-framework -c conda-forge
#!pip install sql_to_ibis
!pip3 install derby
!pip3 install pyarrow 
!pip3 install pandas_datareader
!pip3 install yfinance
!pip3 install hurst

!pip3 install ipywidgets
!pip3 install python-engineio==3.9
!pip3 install python-socketio==4.4.0
!pip3 install fxcmpy<jupyter_output><empty_output><jupyter_text>Activate Jupyter extentions<jupyter_code>!jupyter nbextension install --py widgetsnbextension --user
!jupyter nbextension enable widgetsnbextension --user --py<jupyter_output><empty_output><jupyter_text>We import the required libraries<jupyter_code># Load the necessary packages and modules

import zipfile

from numpy import cumsum, log, polyfit, sqrt, std, subtract, array, argmax
from numpy.random import randn
import numpy as np  # useful for many scientific computing in Python

import hashlib

#import talib

import pandas as pd # primary data structure library
from pandas_datareader import data as pdr
import yfinance

%matplotlib inline
import matplotlib.pyplot as plt

import sklearn
import sklearn.preprocessing
import sklearn.metrics as metrics
from sklearn.metrics import r2_score
from sklearn.preprocessing import StandardScaler, MinMaxScaler, OneHotEncoder, LabelEncoder

import tensorflow as tf
import tensorflow.keras.backend as K
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.layers import GRU, LSTM, Bidirectional, Dense, Dropout
import tensorflow.keras as keras

import math
import datetime
import os

import fxcmpy<jupyter_output><empty_output><jupyter_text>Create function for saving dataset to a parquet file<jupyter_code>def saveDataframeToParquet(new_series_df,new_name,drive_dir='./'):
    pingInfoFilePath = drive_dir+"dataframes/"+new_name+".parquet"
    new_series_df.to_parquet(pingInfoFilePath,engine='pyarrow')<jupyter_output><empty_output><jupyter_text>Create function for reading saved parquet data to a dataframe<jupyter_code>def readSavedDataframes(new_name,drive_dir='./'):
    pingInfoFilePath = drive_dir+"dataframes/"+new_name+".parquet"
    try:
        with open(pingInfoFilePath) as f:
            return pd.read_parquet(pingInfoFilePath, engine='pyarrow')
    except IOError:
        return 'nil'<jupyter_output><empty_output><jupyter_text>Initiate Scaler<jupyter_code>sc = StandardScaler()

def adj_r2_score(r2, n, k):
    return 1-((1-r2)*((n-1)/(n-k-1)))<jupyter_output><empty_output><jupyter_text>Import Data from CSV file<jupyter_code>df = pd.read_csv('eurusd_minute.csv')

df.tail()<jupyter_output><empty_output><jupyter_text>Create Date-Time function<jupyter_code>def CombineDateAndTime(df,date_col,time_col,timestamp_col,datetime_col):
    df[timestamp_col] = df[date_col]+" "+df[time_col]
    df[timestamp_col] = pd.to_datetime(df[timestamp_col])
    df[datetime_col] = df[timestamp_col]
    df[date_col] = pd.to_datetime(df[date_col])
    df = df.sort_values(timestamp_col, ascending=True)
    return df<jupyter_output><empty_output><jupyter_text>Create function for setting timestamp as DataFrame Index column<jupyter_code>def setTimestampAsDFIndex(df,timestamp_col):
    df = df.set_index(timestamp_col)
    return df<jupyter_output><empty_output><jupyter_text>Ste values for necessary variables<jupyter_code>date_col ='Date'
time_col='Time'
timestamp_col='timestamp'
datetime_col='DateTime'

len = df.shape[0]
data_end = len-1

years_for_data = 1
data_start = data_end-(525960*years_for_data) # 525960mins = 1 year, 1051920mins = 2 years, 1577880mins = 3 years, 2103840mins = 4 years, 2629800mins = 5 years

print(len)
print(data_start)
print(data_end)<jupyter_output><empty_output><jupyter_text>Limit Data to the selected number of years<jupyter_code>#df_new = df[data_start:data_end]
df_new = df
df_new.tail()<jupyter_output><empty_output><jupyter_text>Set Date-Tame columns on DataFrame<jupyter_code>df_new = CombineDateAndTime(df_new,date_col,time_col,timestamp_col,datetime_col)
df_new.tail()<jupyter_output><empty_output><jupyter_text>Remove 2020 data from dataset (the dataset only has 4 months worth of 2020 data)<jupyter_code>df_new2 = df_new[(df_new['DateTime'] < '2020-01-01')]
df_new2.tail()<jupyter_output><empty_output><jupyter_text>Import 2020 to 2021 data<jupyter_code>df2020_2021 = pd.read_csv('EURUSD_M1_2020-2021.csv')
df2020_2021.head()<jupyter_output><empty_output><jupyter_text>Assign the correct BCh column values<jupyter_code>df2020_2021["BCh"] = df2020_2021["BC"]-df2020_2021["BO"]
df2020_2021.tail()<jupyter_output><empty_output><jupyter_text><jupyter_code>def setTimeColumns(df,timestamp_col,char_list,excluded_chars=[' ']):
    
    df["timestring"] = df[timestamp_col]
    a = -1
    for charGroup in char_list:
        a = a+1
        
        if charGroup[0] in excluded_chars:
            df["timestring"] = df['timestring'].str.slice(start=1)
        else:
            df[charGroup[0]] = df["timestring"].str.slice(stop=charGroup[1])
            df['timestring'] = df['timestring'].str.slice(start=charGroup[1])
    
        print(df.head())
        
    df = df.drop(columns=['timestring'])
    
    return df<jupyter_output><empty_output><jupyter_text>Create Date - Time columns<jupyter_code>timestamp_col = 'timestamp'
date_col = 'Date'
time_col = 'Time'
dateTime_col = 'DateTime'
year_col = 'year'
month_col = 'month'
day_col = 'day'
hour_col = 'hour'
minute_col = 'minute'
second_col = 'second'
char_list = [[year_col,4],[month_col,2],[day_col,2],[' ',1],[hour_col,2],[minute_col,2],[second_col,2]]
df2020_2021 = setTimeColumns(df2020_2021,timestamp_col,char_list)<jupyter_output><empty_output><jupyter_text>Create function for the creation of the **DateTime** and **timestamp** columns.<jupyter_code>def setDateTimeColumns(df,timestamp_col,date_col,time_col,dateTime_col,year_col,month_col,day_col,hour_col,minute_col,second_col):
    df[date_col] = df[year_col]+"-"+df[month_col]+"-"+df[day_col]
    df[time_col] = df[hour_col]+":"+df[minute_col]+":"+df[second_col]
    df[dateTime_col] = df[date_col]+" "+df[time_col]
    
    print(df.head())

    df[date_col] = pd.to_datetime(df[date_col])
    df[dateTime_col] = pd.to_datetime(df[dateTime_col])
    df[timestamp_col] = df[dateTime_col]
    df = df.drop(columns=[year_col,month_col,day_col,hour_col,minute_col,second_col])
    return df<jupyter_output><empty_output><jupyter_text>Create **DateTime** and **timestamp** columns<jupyter_code>df2020_2021 = setDateTimeColumns(df2020_2021,timestamp_col,date_col,time_col,dateTime_col,year_col,month_col,day_col,hour_col,minute_col,second_col)
df2020_2021.tail()<jupyter_output><empty_output><jupyter_text>Combine 2020 to 2021 data with initial dataset<jupyter_code>df_full = df_new2.append(df2020_2021)
df_full.head()<jupyter_output><empty_output><jupyter_text>Drop all other unnecessary columns<jupyter_code>columns_to_drop = ['AO','AH','AL','AC','ACh']
df_full = df_full.drop(columns=columns_to_drop)
df_full.tail()<jupyter_output><empty_output><jupyter_text>Save full Dataframe to parquet file so that you won't have to do the previous steps again next time around.<jupyter_code>dataframe_parquet_file_name = 'EURUSD_2005_to_2021_dataset'
saveDataframeToParquet(df_full, dataframe_parquet_file_name)
df_full = readSavedDataframes(dataframe_parquet_file_name)<jupyter_output><empty_output><jupyter_text>Set timestamp as DataFrame Index<jupyter_code>df_full = setTimestampAsDFIndex(df_full,timestamp_col)
df_full.tail()<jupyter_output><empty_output><jupyter_text>Create Diff column by subtracting the previous value of BC column from the current BC value<jupyter_code>df_full["Diff"] = df_full.BC.diff()
df_full.tail()<jupyter_output><empty_output><jupyter_text>Create 5 minute moving average column MA5<jupyter_code>df_full['MA5'] = df_full['BC'].rolling(5).mean()
df_full['MA20'] = df_full['BC'].rolling(20).mean()
df_full['MA50'] = df_full['BC'].rolling(50).mean()
df_full['MA100'] = df_full['BC'].rolling(100).mean()
df_full["MA5Diff"] = df_full.MA5.diff()
df_full["MA20Diff"] = df_full.MA20.diff()
df_full["MA50Diff"] = df_full.MA50.diff()
df_full["MA100Diff"] = df_full.MA100.diff()
df_full.tail()<jupyter_output><empty_output><jupyter_text><jupyter_code>length = df_full.shape[0]
data_end = length-1

years_for_data = 4
data_start = data_end-(525960*years_for_data) # 525960mins = 1 year, 1051920mins = 2 years, 1577880mins = 3 years, 2103840mins = 4 years, 2629800mins = 5 years

print(df_full.shape)
print(length)
print(data_start)
print(data_end)

#df_new = df_full[data_start:data_end]
df_new = df_full[data_start:data_end]
df_new.shape<jupyter_output>(5972867, 17)
5972867
2817106
5972866<jupyter_text>Fit (train) the scaler<jupyter_code>scDiff = sc.fit(df_new[['Diff']])
scMA5Diff = sc.fit(df_new[['MA5Diff']])
scMA20Diff = sc.fit(df_new[['MA20Diff']])
scMA50Diff = sc.fit(df_new[['MA50Diff']])
scMA100Diff = sc.fit(df_new[['MA100Diff']])<jupyter_output><empty_output><jupyter_text>Split the data into train 80% and test 20%<jupyter_code>train_size = int(df_new.shape[0]*0.8)
train_dataset, test_dataset = df_new.iloc[:train_size], df_new.iloc[train_size:]<jupyter_output><empty_output><jupyter_text>Separate the dataset into 'BC','MA5','MA5Diff','BullActivity' and 'BearActivity'<jupyter_code>df_train_Diff = train_dataset[["Diff"]].copy()
df_train_MA5Diff = train_dataset[["MA5Diff"]].copy()
df_train_MA20Diff = train_dataset[["MA20Diff"]].copy()
df_train_MA50Diff = train_dataset[["MA50Diff"]].copy()
df_train_MA100Diff = train_dataset[["MA100Diff"]].copy()

df_test_Diff = test_dataset[["Diff"]].copy()
df_test_MA5Diff = test_dataset[["MA5Diff"]].copy()
df_test_MA20Diff = test_dataset[["MA20Diff"]].copy()
df_test_MA50Diff = test_dataset[["MA50Diff"]].copy()
df_test_MA100Diff = test_dataset[["MA100Diff"]].copy()<jupyter_output><empty_output><jupyter_text>Replace NaN with zeros<jupyter_code>df_train_Diff["Diff"] = df_train_Diff["Diff"].fillna(0)
df_train_MA5Diff["MA5Diff"] = df_train_MA5Diff["MA5Diff"].fillna(0)
df_train_MA20Diff["MA20Diff"] = df_train_MA20Diff["MA20Diff"].fillna(0)
df_train_MA50Diff["MA50Diff"] = df_train_MA50Diff["MA50Diff"].fillna(0)
df_train_MA100Diff["MA100Diff"] = df_train_MA100Diff["MA100Diff"].fillna(0)

df_train_Diff["Diff"] = df_train_Diff["Diff"].fillna(0)
df_train_MA5Diff["MA5Diff"] = df_train_MA5Diff["MA5Diff"].fillna(0)
df_train_MA20Diff["MA20Diff"] = df_train_MA20Diff["MA20Diff"].fillna(0)
df_train_MA50Diff["MA50Diff"] = df_train_MA50Diff["MA50Diff"].fillna(0)
df_train_MA100Diff["MA100Diff"] = df_train_MA100Diff["MA100Diff"].fillna(0)<jupyter_output><empty_output><jupyter_text>Scale the datasets<jupyter_code>df_train_Diff_scaled = scDiff.transform(df_train_Diff)
df_train_MA5Diff_scaled = scMA5Diff.transform(df_train_MA5Diff)
df_train_MA20Diff_scaled = scMA20Diff.transform(df_train_MA20Diff)
df_train_MA50Diff_scaled = scMA50Diff.transform(df_train_MA50Diff)
df_train_MA100Diff_scaled = scMA100Diff.transform(df_train_MA100Diff)

df_test_Diff_scaled = scDiff.transform(df_test_Diff)
df_test_MA5Diff_scaled = scMA5Diff.transform(df_test_MA5Diff)
df_test_MA20Diff_scaled = scMA20Diff.transform(df_test_MA20Diff)
df_test_MA50Diff_scaled = scMA50Diff.transform(df_test_MA50Diff)
df_test_MA100Diff_scaled = scMA100Diff.transform(df_test_MA100Diff)<jupyter_output><empty_output><jupyter_text>Create function for creating input dataset<jupyter_code>def create_dataset (X, look_back = 1):
    Xs, ys = [], []

    num = X.size
 
    for i in range(num-look_back):
        v = X[i:i+look_back]
        Xs.append(v)
        ys.append(X[i+look_back])
 
    return np.array(Xs), np.array(ys)<jupyter_output><empty_output><jupyter_text>Create input datasets<jupyter_code>LOOK_BACK = 30
x_train_Diff, y_train_Diff = create_dataset(df_train_Diff_scaled,LOOK_BACK)
x_train_MA5Diff, y_train_MA5Diff = create_dataset(df_train_MA5Diff_scaled,LOOK_BACK)
x_train_MA20Diff, y_train_MA20Diff = create_dataset(df_train_MA20Diff_scaled,LOOK_BACK)
x_train_MA50Diff, y_train_MA50Diff = create_dataset(df_train_MA50Diff_scaled,LOOK_BACK)
x_train_MA100Diff, y_train_MA100Diff = create_dataset(df_train_MA100Diff_scaled,LOOK_BACK)

x_test_Diff, y_test_Diff = create_dataset(df_test_Diff_scaled,LOOK_BACK)
x_test_MA5Diff, y_test_MA5Diff = create_dataset(df_test_MA5Diff_scaled,LOOK_BACK)
x_test_MA20Diff, y_test_MA20Diff = create_dataset(df_test_MA20Diff_scaled,LOOK_BACK)
x_test_MA50Diff, y_test_MA50Diff = create_dataset(df_test_MA50Diff_scaled,LOOK_BACK)
x_test_MA100Diff, y_test_MA100Diff = create_dataset(df_test_MA100Diff_scaled,LOOK_BACK)

# Print data shape
print('x_train_Diff.shape = ',x_train_Diff.shape)
print('y_train_Diff.shape = ',y_train_Diff.shape)
print('x_train_MA5Diff.shape = ',x_train_MA5Diff.shape)
print('y_train_MA5Diff.shape = ',y_train_MA5Diff.shape)


print('x_test_Diff.shape = ',x_test_Diff.shape)
print('y_test_Diff.shape = ',y_test_Diff.shape)
print('x_test_MA5Diff.shape = ',x_test_MA5Diff.shape)
print('y_test_MA5Diff.shape = ',y_test_MA5Diff.shape) 
from numpy import asarray
from numpy import save

save('x_train_Diff.npy',x_train_Diff)
save('x_train_MA5Diff.npy',x_train_MA5Diff)
save('x_train_MA20Diff.npy',x_train_MA20Diff)
save('x_train_MA50Diff.npy',x_train_MA50Diff)
save('x_train_MA100Diff.npy',x_train_MA100Diff)

save('y_train_Diff.npy',y_train_Diff)
save('y_train_MA5Diff.npy',y_train_MA5Diff)
save('y_train_MA20Diff.npy',y_train_MA20Diff)
save('y_train_MA50Diff.npy',y_train_MA50Diff)
save('y_train_MA100Diff.npy',y_train_MA100Diff)

########  test  #######################
save('x_test_Diff.npy',x_test_Diff)
save('x_test_MA5Diff.npy',x_test_MA5Diff)
save('x_test_MA20Diff.npy',x_test_MA20Diff)
save('x_test_MA50Diff.npy',x_test_MA50Diff)
save('x_test_MA100Diff.npy',x_test_MA100Diff)

save('y_test_Diff.npy',y_test_Diff)
save('y_test_MA5Diff.npy',y_test_MA5Diff)
save('y_test_MA20Diff.npy',y_test_MA20Diff)
save('y_test_MA50Diff.npy',y_test_MA50Diff)
save('y_test_MA100Diff.npy',y_test_MA100Diff)<jupyter_output><empty_output><jupyter_text><jupyter_code>from numpy import load

y_test_MA100Diff = load('y_test_MA100Diff.npy')
import tensorflow as tf
import tensorflow.keras.backend as K
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import EarlyStopping
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.layers import GRU, LSTM, Bidirectional, Dense, Dropout
import tensorflow.keras as keras<jupyter_output><empty_output><jupyter_text>Create models<jupyter_code>import tensorflow.keras as keras

# Create BiLSTM model
def create_bilstm(units,X_train):
    model = Sequential()
    # Input layer
    model.add(Bidirectional(LSTM(units = units, return_sequences=True), input_shape=(X_train.shape[1], X_train.shape[2])))
    # Hidden layer
    model.add(Bidirectional(LSTM(units = units)))
    model.add(Dense(1))
    #Compile model
    model.compile(optimizer='adam',loss='mse')
    return model


# Create GRU model
def create_gru(units,X_train):
    model = Sequential()
    # Input layer
    model.add(GRU(units = units, return_sequences = True, input_shape = [X_train.shape[1], X_train.shape[2]]))
    model.add(Dropout(0.2)) 
    # Hidden layer
    model.add(GRU(units = units)) 
    model.add(Dropout(0.2))
    model.add(Dense(units = 1)) 
    #Compile model
    model.compile(optimizer='adam',loss='mse')
    return model


#optimizer='adam',loss='mse'
# Create GRU-LSTM model
def create_gru_lstm(gru_units,lstm_units,X_train,optimizer,loss):
    model = Sequential()
    # Input layer
    model.add(GRU(units = gru_units, return_sequences = True, input_shape = [X_train.shape[1], X_train.shape[2]]))
    model.add(Dropout(0.2)) 

    # Hidden layer
    model.add(LSTM (units = lstm_units))
    model.add(Dropout(0.2)) 
    #model.add(GRU(units = gru_units)) 
    #model.add(Dropout(0.2))
    model.add(Dense(units = 1)) 
    #Compile model
    model.compile(optimizer=optimizer,loss=loss)
    return model<jupyter_output><empty_output><jupyter_text>Set model variables<jupyter_code>n_steps = LOOK_BACK-1
n_inputs = 4
n_neurons = 128
n_outputs = 4
n_layers = 2
learning_rate = 0.001
batch_size = 50
n_epochs = 100

my_optimizer='adam'
patience=10
verbose=1
loss='mse'

# GRU & LSTM Model Units/Neurons
gru_units = 20
#lstm_units = 256
lstm_units = 64<jupyter_output><empty_output><jupyter_text>Create GRU-LSTM Model<jupyter_code>Diff_model_gru_lstm = create_gru_lstm(gru_units,lstm_units,x_train_Diff)
Diff_model_gru_lstm.summary()<jupyter_output>Model: "sequential_6"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
gru_6 (GRU)                  (None, 30, 20)            1380      
_________________________________________________________________
dropout_8 (Dropout)          (None, 30, 20)            0         
_________________________________________________________________
lstm_6 (LSTM)                (None, 64)                21760     
_________________________________________________________________
dropout_9 (Dropout)          (None, 64)                0         
_________________________________________________________________
dense_6 (Dense)              (None, 1)                 65        
=================================================================
Total params: 23,205
Trainable params: 23,205
Non-trainable params: 0
__________________________________________________[...]<jupyter_text>Create GRU Model<jupyter_code>Diff_model_gru = create_gru(n_neurons,x_train_Diff)
Diff_model_gru.summary()<jupyter_output>Model: "sequential_7"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
gru_7 (GRU)                  (None, 30, 128)           50304     
_________________________________________________________________
dropout_10 (Dropout)         (None, 30, 128)           0         
_________________________________________________________________
gru_8 (GRU)                  (None, 128)               99072     
_________________________________________________________________
dropout_11 (Dropout)         (None, 128)               0         
_________________________________________________________________
dense_7 (Dense)              (None, 1)                 129       
=================================================================
Total params: 149,505
Trainable params: 149,505
Non-trainable params: 0
________________________________________________[...]<jupyter_text>Create BiLSTM Model<jupyter_code>Diff_model_bilstm = create_bilstm(n_neurons,x_train_Diff)
Diff_model_bilstm.summary()<jupyter_output>Model: "sequential_8"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
bidirectional_4 (Bidirection (None, 30, 256)           133120    
_________________________________________________________________
bidirectional_5 (Bidirection (None, 256)               394240    
_________________________________________________________________
dense_8 (Dense)              (None, 1)                 257       
=================================================================
Total params: 527,617
Trainable params: 527,617
Non-trainable params: 0
_________________________________________________________________<jupyter_text>Create function for training the model<jupyter_code>def fit_model(model,X_train,y_train,epochs,batch_size,patience,optimizer,loss):
    early_stop = keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = patience)
    model.compile(
        optimizer=optimizer,
        loss=loss
    )
    history = model.fit(X_train, y_train, epochs = epochs,
                        validation_split = 0.3,
                        batch_size = batch_size, shuffle = False, 
                        callbacks = [early_stop])
    return history<jupyter_output><empty_output><jupyter_text>Create function for making predictions<jupyter_code>def prediction(model,scaler,x_test):
    prediction = model.predict(x_test)
    prediction = scaler.inverse_transform(prediction)
    return prediction<jupyter_output><empty_output><jupyter_text><jupyter_code>gru_lstm_Diff_trained = fit_model(Diff_model_gru_lstm,x_train_Diff,y_train_Diff,n_epochs,batch_size,patience)
def get_compiled_model(model,optimizer,loss,metrics):
    model.compile(
        optimizer=optimizer,
        loss=loss,
        metrics=metrics,
    )
    return model
loss='mse'
metrics=["mean_squared_error"]
optimizer = "adam"
gru_lstm_Diff_trained_compiled = get_compiled_model(gru_lstm_Diff_trained,optimizer,loss,metrics)



gru_lstm_Diff_trained.save("gru_lstm_Diff_model.h5")

#keras.models.save_model(gru_lstm_Diff_trained, "gru_lstm_Diff_model.hdf5", overwrite=True, include_optimizer=True, save_format=None, save_traces=True)<jupyter_output><empty_output><jupyter_text>Train the GRU Model on Diff data<jupyter_code>gru_Diff_trained = fit_model(Diff_model_gru,x_train_Diff,y_train_Diff,n_epochs,batch_size,patience)
gru_Diff_trained.save("gru_Diff_model")<jupyter_output>Epoch 1/100
47276/66896 [====================>.........] - ETA: 28:38 - loss: 110.1755<jupyter_text>Train the GRU Model on MA5Diff data<jupyter_code>gru_MA5Diff_trained = fit_model(model_gru,x_train_MA5Diff,y_train_MA5Diff,n_epochs,batch_size,patience)
gru_MA5Diff_trained.save("gru_MA5Diff_model")<jupyter_output><empty_output><jupyter_text>Test the Diff-trained GRU model on Diff data<jupyter_code>prediction_gru_Diff_trained = prediction(gru_Diff_trained,sc,x_test_Diff)<jupyter_output><empty_output><jupyter_text>Test the MA5Diff-trained GRU model on Diff data<jupyter_code>prediction_gru_MA5Diff_trained = prediction(gru_MA5Diff_trained,sc,x_test_Diff)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12728668864899048, 'fraction_numerical': 0.03943267536925787, 'mean_word_length': 6.873399715504979, 'pattern_counts': {'":': 2, '<': 182, '<?xml version=': 0, '>': 182, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '46', 'dir': 'jupyter-structured-clean-dedup', 'id': '165417', 'license': 'MIT', 'n_tokens_mistral': 8434, 'n_tokens_neox': 7793, 'n_words': 1151, 'path': 'GRU_LSTM_TradingBot_Models.ipynb', 'repo_name': 'jlubinda/obtir-fx', 'size': '22150'}