View file src/colab/grid_trading.py - Download

# -*- coding: utf-8 -*-
"""grid_trading.ipynb

Automatically generated by Colab.

Original file is located at
    https://colab.research.google.com/drive/1aCCUi1d2CPESo6ngUtRp86vZb29I04X9

# GRID TRADING
"""

!pip install yfinance

import pandas as pd
import numpy as np
import math
import matplotlib.pyplot as plt # Visualization
import matplotlib.dates as mdates # Formatting dates
import seaborn as sns # Visualization
from sklearn.preprocessing import MinMaxScaler
import torch # Library for implementing Deep Neural Network
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader

# Loading the Apple.Inc Stock Data

import yfinance as yf
from datetime import date, timedelta, datetime

#end_date =  date.today().strftime("%Y-%m-%d") #end date for our data retrieval will be current date
end_date = '2023-09-18'
start_date = '1990-01-01' # Beginning date for our historical data retrieval

df = yf.download('AAPL', start=start_date, end=end_date)# Function used to fetch the data
print("")
print(df.iloc[0,:])
print(df.iloc[0,3])
print(df)

print(len(df))
# cloture_apple = [df.iloc[i,3] / df.iloc[0,3] for i in range(len(df))]
cloture_apple = [df.iloc[i,3] / df.iloc[0,3] for i in range(2000)] # Apple
# cloture_apple = [df.iloc[i,3] / df.iloc[0,3] for i in range(400,1100)] # Google
print(cloture_apple)

plt.figure(figsize=(15,6))
plt.plot(cloture_apple)
plt.title('APPLE')
plt.show()

df_google = yf.download('GOOG', start=start_date, end=end_date)
cloture_google = [df_google.iloc[i,3] / df_google.iloc[400,3] for i in range(400,1100)]

def data_plot(df):
    df_plot = df.copy()

    ncols = 1
    nrows = int(round(df_plot.shape[1] / ncols, 0))

    fig, ax = plt.subplots(nrows=nrows, ncols=ncols,
                           sharex=True, figsize=(15,20))
    for i, ax in enumerate(fig.axes):
        sns.lineplot(data=[(math.log(x) if x>0 else np.nan) for x in df_plot.iloc[:, i]], ax=ax)
        ax.tick_params(axis="x", rotation=30, labelsize=10, length=0)
        ax.xaxis.set_major_locator(mdates.AutoDateLocator())
    fig.tight_layout()
    plt.show()

data_plot(df)

df_adobe = yf.download('ADBE', start=start_date, end=end_date)
# data_plot(df_adobe)

cloture_adobe = [df_adobe.iloc[i,3] / df_adobe.iloc[2700,3] for i in range(2700,5000)]

plt.figure(figsize=(15,6))
plt.plot(cloture_adobe)
plt.show()

df_btc = yf.download('BTC-USD', start=start_date, end=end_date)
# data_plot(df_btc)

cloture_btc = [df_btc.iloc[i,3] / df_btc.iloc[1200,3] for i in range(1200,2000)]

plt.figure(figsize=(15,6))
plt.plot(cloture_adobe)
plt.show()

btc_usd = yf.Ticker('BTC-USD')
data = btc_usd.history(interval='1m', start='2024-09-01', end='2024-09-08')
print(len(data))
intraday_btc = [data.iloc[i,3] / data.iloc[0,3] for i in range(len(data))]
plt.figure(figsize=(15,6))
plt.plot(intraday_btc)
plt.show()

"""Trading functions"""

def trade(cv, t1, signal, display_graph=False):
    tt = len(cv)  # temps total
    l = torch.tensor(1.0, requires_grad=True)       # liquidités
    q = torch.tensor(0.0, requires_grad=True)       # quantité d'actions détenues
    graph = []
    q = q + 0.5 * l / cv[t1]
    l = l - 0.5 * l
    for t in range(t1, tt):
        cours_actuel = cv[t]
        s = signal(cv[t-t1:t])
        if s > 1:
            s = 1
        if s < -1:
            s = -1
        if s > 0:    # on achète
            q = q + s * l / cours_actuel
            l = l - s * l
        elif s < 0:  # on vend
            l = l - s * q * cours_actuel
            q = q + s * q
        k = l + q * cours_actuel
        if display_graph:
            graph = graph + [[cours_actuel, q.to("cpu").detach().numpy(), k.to("cpu").detach().numpy()]]
    if display_graph:
        plt.figure(figsize=(15,6))
        plt.plot(graph)
        plt.show()
    return k

def signal3(cv):
    if (cv[-1] < 0.8):
        return 1
    elif (cv[-1] > 1.8):
        return -1
    else:
        return 0

"""Parameters for Apple"""

N = 20
# train A:B, test C:D

A = 100
B = 1100
C = 1200
D = 2200

k = trade(cloture_apple, N, signal3, True)
print(k)

import math

math.log(3)

def band(c, density):
  return math.floor(math.log(c) * density)

def floor(b, density):
  return math.exp(b / density)

print(band(3.4, 10))
print(floor(12, 10))
print(floor(13, 10))
print(band(3.321, 10))
print(band(3.320, 10))

for c in np.arange(0.5, 2, 0.1):
  print(f"{c}: {band(c, 10)}")

def simple_grid_trade(cv, t1, display_graph=False):
    tt = len(cv)  # temps total
    l = torch.tensor(1.0, requires_grad=True)       # liquidités
    q = torch.tensor(0.0, requires_grad=True)       # quantité d'actions détenues
    graph = []
    q = q + 0.5 * l / cv[t1]
    l = l - 0.5 * l
    bande_actuelle = 0
    tendance_actuelle = 0
    for t in range(t1, tt):
        cours_actuel = cv[t]
        # s = signal(cv[t-t1:t])
        bande_precedente = bande_actuelle
        bande_actuelle = band(cours_actuel, 10)
        tendance_precedente = tendance_actuelle
        if bande_actuelle < bande_precedente:
          tendance_actuelle = -1
          if tendance_actuelle == tendance_precedente:
            s = 1
          else:
            s = 0
        elif bande_actuelle > bande_precedente:
          tendance_actuelle = 1
          if tendance_actuelle == tendance_precedente:
            s = -1
          else:
            s = 0
        else:
          s = 0
        if s > 0:    # on achète
            q = q + s * l / cours_actuel
            l = l - s * l
        elif s < 0:  # on vend
            l = l - s * q * cours_actuel
            q = q + s * q
        k = l + q * cours_actuel
        if display_graph:
            graph = graph + [[cours_actuel, q.to("cpu").detach().numpy(), k.to("cpu").detach().numpy()]]
    if display_graph:
        plt.figure(figsize=(15,6))
        plt.plot(graph)
        plt.show()
    return k

k = simple_grid_trade(cloture_apple, N, True)
print(k)

def grid_trade(cv, t1, display_graph=False):
    tt = len(cv)  # temps total
    l = torch.tensor(1.0, requires_grad=True)       # liquidités
    q = torch.tensor(0.0, requires_grad=True)       # quantité d'actions détenues
    graph = []
    q = q + 0.5 * l / cv[t1]
    l = l - 0.5 * l
    bande_actuelle = 0
    tendance_actuelle = 0
    for t in range(t1, tt):
        cours_actuel = cv[t]
        # s = signal(cv[t-t1:t])
        bande_precedente = bande_actuelle
        bande_actuelle = band(cours_actuel, 10)
        tendance_precedente = tendance_actuelle
        if bande_actuelle < bande_precedente:
          tendance_actuelle = -1
          if tendance_actuelle == tendance_precedente:
            s = 0.1
          else:
            s = 0
        elif bande_actuelle > bande_precedente:
          tendance_actuelle = 1
          if tendance_actuelle == tendance_precedente:
            s = -0.1
          else:
            s = 0
        else:
          s = 0
        if s > 0:    # on achète
            q = q + s * l / cours_actuel
            l = l - s * l
        elif s < 0:  # on vend
            l = l - s * q * cours_actuel
            q = q + s * q
        k = l + q * cours_actuel
        if display_graph:
            graph = graph + [[cours_actuel, q.to("cpu").detach().numpy(), k.to("cpu").detach().numpy()]]
    if display_graph:
        plt.figure(figsize=(15,6))
        plt.plot(graph)
        plt.show()
    return k

k = grid_trade(cloture_apple, N, True)
print(k)

def grid_trade(cv, t1, display_graph=False):
    tt = len(cv)  # temps total
    l = torch.tensor(1.0, requires_grad=True)       # liquidités
    q = torch.tensor(0.0, requires_grad=True)       # quantité d'actions détenues
    graph = []
    q = q + 0.5 * l / cv[t1]
    l = l - 0.5 * l
    bande_actuelle = 0
    tendance_actuelle = 0
    for t in range(t1, tt):
        cours_actuel = cv[t]
        # s = signal(cv[t-t1:t])
        bande_precedente = bande_actuelle
        bande_actuelle = band(cours_actuel, 10)
        tendance_precedente = tendance_actuelle
        if bande_actuelle < bande_precedente:
          tendance_actuelle = -1
          if tendance_actuelle == tendance_precedente:
            s = -0.1
          else:
            s = 0
        elif bande_actuelle > bande_precedente:
          tendance_actuelle = 1
          if tendance_actuelle == tendance_precedente:
            s = 0.1
          else:
            s = 0
        else:
          s = 0
        if s > 0:    # on achète
            q = q + s * l / cours_actuel
            l = l - s * l
        elif s < 0:  # on vend
            l = l - s * q * cours_actuel
            q = q + s * q
        k = l + q * cours_actuel
        if display_graph:
            graph = graph + [[cours_actuel, q.to("cpu").detach().numpy(), k.to("cpu").detach().numpy()]]
    if display_graph:
        plt.figure(figsize=(15,6))
        plt.plot(graph)
        plt.show()
    return k

k = grid_trade(cloture_apple, N, True)
print(k)

def grid_trade(cv, t1, density, display_graph=False):
    tt = len(cv)  # temps total
    l = torch.tensor(1.0, requires_grad=True)       # liquidités
    q = torch.tensor(0.0, requires_grad=True)       # quantité d'actions détenues
    graph = []
    q = q + 0.5 * l / cv[t1]
    l = l - 0.5 * l
    bande_actuelle = 0
    tendance_actuelle = 0
    for t in range(t1, tt):
        cours_actuel = cv[t]
        # s = signal(cv[t-t1:t])
        bande_precedente = bande_actuelle
        bande_actuelle = band(cours_actuel, density)
        tendance_precedente = tendance_actuelle
        if bande_actuelle < bande_precedente:
          tendance_actuelle = -1
          if tendance_actuelle == tendance_precedente:
            s = 0.1
          else:
            s = 0
        elif bande_actuelle > bande_precedente:
          tendance_actuelle = 1
          if tendance_actuelle == tendance_precedente:
            s = -0.1
          else:
            s = 0
        else:
          s = 0
        if s > 0:    # on achète
            q = q + s * l / cours_actuel
            l = l - s * l
        elif s < 0:  # on vend
            l = l - s * q * cours_actuel
            q = q + s * q
        k = l + q * cours_actuel
        if display_graph:
            graph = graph + [[cours_actuel, q.to("cpu").detach().numpy(), k.to("cpu").detach().numpy()]]
    if display_graph:
        plt.figure(figsize=(15,6))
        plt.plot(graph)
        plt.show()
    return k

k = grid_trade(cloture_apple, N, 10, True)
print(k)

for density in range(30):
  k = grid_trade(cloture_apple, N, density, False)
  print(f"{density}: {k}")

def grid_trade(cv, t1, density, rate,  display_graph=False):
    tt = len(cv)  # temps total
    l = torch.tensor(1.0, requires_grad=True)       # liquidités
    q = torch.tensor(0.0, requires_grad=True)       # quantité d'actions détenues
    graph = []
    q = q + 0.5 * l / cv[t1]
    l = l - 0.5 * l
    bande_actuelle = 0
    tendance_actuelle = 0
    for t in range(t1, tt):
        cours_actuel = cv[t]
        # s = signal(cv[t-t1:t])
        bande_precedente = bande_actuelle
        bande_actuelle = band(cours_actuel, density)
        tendance_precedente = tendance_actuelle
        if bande_actuelle < bande_precedente:
          tendance_actuelle = -1
          if tendance_actuelle == tendance_precedente:
            s = rate
          else:
            s = 0
        elif bande_actuelle > bande_precedente:
          tendance_actuelle = 1
          if tendance_actuelle == tendance_precedente:
            s = -rate
          else:
            s = 0
        else:
          s = 0
        if s > 0:    # on achète
            q = q + s * l / cours_actuel
            l = l - s * l
        elif s < 0:  # on vend
            l = l - s * q * cours_actuel
            q = q + s * q
        k = l + q * cours_actuel
        if display_graph:
            graph = graph + [[cours_actuel, q.to("cpu").detach().numpy(), k.to("cpu").detach().numpy()]]
    if display_graph:
        plt.figure(figsize=(15,6))
        plt.plot(graph)
        plt.show()
    return k

def grid_trade(cv, t1, density, rate,  display_graph=False):
    tt = len(cv)  # temps total
    l = torch.tensor(1.0, requires_grad=True)       # liquidités
    q = torch.tensor(0.0, requires_grad=True)       # quantité d'actions détenues
    graph = []
    q = q + 0.5 * l / cv[t1]
    l = l - 0.5 * l
    bande_actuelle = 0
    tendance_actuelle = 0
    for t in range(t1, tt):
        cours_actuel = cv[t]
        # s = signal(cv[t-t1:t])
        bande_precedente = bande_actuelle
        bande_actuelle = band(cours_actuel, density)
        tendance_precedente = tendance_actuelle
        if bande_actuelle < bande_precedente:
          tendance_actuelle = -1
          if tendance_actuelle == tendance_precedente:
            s = rate
          else:
            s = 0
        elif bande_actuelle > bande_precedente:
          tendance_actuelle = 1
          if tendance_actuelle == tendance_precedente:
            s = -rate
          else:
            s = 0
        else:
          s = 0
        if s > 0:    # on achète
            # q = q + s * l / cours_actuel
            q = q + s * l / floor(bande_actuelle + 1, density)
            l = l - s * l
        elif s < 0:  # on vend
            # l = l - s * q * cours_actuel
            l = l - s * q * floor(bande_actuelle, density)
            q = q + s * q
        k = l + q * cours_actuel
        if display_graph:
            graph = graph + [[cours_actuel, q.to("cpu").detach().numpy(), k.to("cpu").detach().numpy()]]
    if display_graph:
        plt.figure(figsize=(15,6))
        plt.plot(graph)
        plt.show()
    return k

k = grid_trade(cloture_apple, N, 10, 0.1, True)
print(k)

k = grid_trade(cloture_apple, N, 4, 0.65, True)
print(k)

k = grid_trade(cloture_apple, N, 9, -1, True)
print(k)

k = grid_trade(cloture_google, N, 4, 0.65, True)
print(k)

k = grid_trade(cloture_google, N, 9, -1, True)
print(k)

density = 15
rate = 0.1

for rate in np.arange(-1.0, 1.0, 0.05):
  k = grid_trade(cloture_apple, N, density, rate, False)
  print(f"{density} {rate:5.2f}: {k}")

nd = 20
rmin = -1.0
rmax = 1.0
dr = 0.1
nr = int((rmax - rmin) / dr)
a = np.empty((nd, nr))

for density in range(nd):
  for i, rate in enumerate(np.arange(rmin, rmax, dr)):
    k = grid_trade(cloture_apple, N, density, rate, False)
    a[density, i] = k

import numpy as np
from matplotlib import pyplot as plt
from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show

# plt.rcParams["figure.figsize"] = [7.00, 3.50]
plt.rcParams["figure.autolayout"] = True
plt.imshow(a, cmap=cm.RdBu)
plt.show()

nd = 20
rmin = -1.0
rmax = 1.0
dr = 0.1
nr = int((rmax - rmin) / dr)
a = np.empty((nd, nr))

for density in range(nd):
  for i, rate in enumerate(np.arange(rmin, rmax, dr)):
    k = grid_trade(cloture_google, N, density, rate, False)
    a[density, i] = k

plt.rcParams["figure.autolayout"] = True
plt.imshow(a, cmap=cm.RdBu)
plt.show()

nd = 20
rmin = -1.0
rmax = 1.0
dr = 0.1
nr = int((rmax - rmin) / dr)
a = np.empty((nd, nr))

for density in range(nd):
  for i, rate in enumerate(np.arange(rmin, rmax, dr)):
    k = grid_trade(cloture_adobe, N, density, rate, False)
    a[density, i] = k

plt.rcParams["figure.autolayout"] = True
plt.imshow(a, cmap=cm.RdBu)
plt.show()

k = grid_trade(cloture_adobe, N, 17, 1, True)
print(k)

nd = 20
rmin = -1.0
rmax = 1.0
dr = 0.1
nr = int((rmax - rmin) / dr)
a = np.empty((nd, nr))

for density in range(nd):
  for i, rate in enumerate(np.arange(rmin, rmax, dr)):
    k = grid_trade(cloture_btc, N, density, rate, False)
    a[density, i] = k

plt.rcParams["figure.autolayout"] = True
plt.imshow(a, cmap=cm.RdBu)
plt.show()

nd = 20
rmin = -1.0
rmax = 1.0
dr = 0.1
nr = int((rmax - rmin) / dr)
a = np.empty((nd, nr))

for density in range(nd):
  for i, rate in enumerate(np.arange(rmin, rmax, dr)):
    k = grid_trade(intraday_btc, N, density, rate, False)
    a[density, i] = k

plt.rcParams["figure.autolayout"] = True
plt.imshow(a, cmap=cm.RdBu)
plt.show()

k = grid_trade(intraday_btc, N, 9, 1, True)
print(k)

k = grid_trade(intraday_btc, N, 18, -1, True)
print(k)

nd = 60
rmin = -1.0
rmax = 1.0
dr = 0.1
nr = int((rmax - rmin) / dr)
a = np.empty((nd, nr))

for density in range(nd):
  for i, rate in enumerate(np.arange(rmin, rmax, dr)):
    k = grid_trade(intraday_btc, N, density, rate, False)
    a[density, i] = k

plt.rcParams["figure.autolayout"] = True
plt.imshow(a, cmap=cm.RdBu)
plt.show()

k = grid_trade(intraday_btc, N, 50, 1, True)
print(k)

# Commented out IPython magic to ensure Python compatibility.
# %%script echo Disabled
# 
# density = 15
# rate = 0.1
# 
# for density in range(1,30):
#  for rate in np.arange(-1.0, 1.0, 0.05):
#   k = grid_trade(cloture_apple, N, density, rate, False)
#   print(f"{density} {rate:5.2f}: {k}")

# Commented out IPython magic to ensure Python compatibility.
# %%script echo Disabled
# 
# density = 15
# rate = 0.1
# 
# for rate in np.arange(-1.0, 1.0, 0.05):
#   for density in range(1,20):
#     k = grid_trade(cloture_apple, N, density, rate, False)
#     print(f"{density:2} {rate:5.2f}: {k}")

"""Imports and device"""

# Commented out IPython magic to ensure Python compatibility.
# %%script echo Disabled
# 
# import torch
# from torch import nn
# 
# # Get cpu or gpu device for training.
# device = "cuda" if torch.cuda.is_available() else "cpu"
# print(f"Using {device} device")