# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# ## Crypto Arbitrage
#
# In this Challenge, you'll take on the role of an analyst at a high-tech investment firm. The vice president (VP) of your department is considering arbitrage opportunities in Bitcoin and other cryptocurrencies. As Bitcoin trades on markets across the globe, can you capitalize on simultaneous price dislocations in those markets by using the powers of Pandas?
#
# For this assignment, you’ll sort through historical trade data for Bitcoin on two exchanges: Bitstamp and Coinbase. Your task is to apply the three phases of financial analysis to determine if any arbitrage opportunities exist for Bitcoin.
#
# This aspect of the Challenge will consist of 3 phases.
#
# 1. Collect the data.
#
# 2. Prepare the data.
#
# 3. Analyze the data. 
#
#

# ###  Import the required libraries and dependencies.

# +
# Import the Pandas library
import pandas as pd

# Import the Path module from the pathlib library
from pathlib import Path

# Import the %matplotlib inline magic function
# %matplotlib inline
# -

# ## Collect the Data
#
# To collect the data that you’ll need, complete the following steps:
#
# Instructions. 
#
# 1. Using the Pandas `read_csv` function and the `Path` module, import the data from `bitstamp.csv` file, and create a DataFrame called `bitstamp`. Set the DatetimeIndex as the Timestamp column, and be sure to parse and format the dates.
#
# 2. Use the `head` (and/or the `tail`) function to confirm that Pandas properly imported the data.
#
# 3. Repeat Steps 1 and 2 for `coinbase.csv` file.

# ### Step 1: Using the Pandas `read_csv` function and the `Path` module, import the data from `bitstamp.csv` file, and create a DataFrame called `bitstamp`. Set the DatetimeIndex as the Timestamp column, and be sure to parse and format the dates.

# Read in the CSV file called "bitstamp.csv" using the Path module. 
# The CSV file is located in the Resources folder.
# Set the index to the column "Date"
# Set the parse_dates and infer_datetime_format parameters
bitstamp_csvpath = Path('./Resources/bitstamp.csv')
bitstamp = pd.read_csv(
    bitstamp_csvpath, 
    index_col="Timestamp", 
    parse_dates=True, 
    infer_datetime_format=True)

# ### Step 2: Use the `head` (and/or the `tail`) function to confirm that Pandas properly imported the data.

# Use the head (and/or tail) function to confirm that the data was imported properly.
# Using the head function to confirm that the data was imported properly.
bitstamp.head()


# Using the tail function to confirm that the data was imported properly.
bitstamp.tail()

# ### Step 3: Repeat Steps 1 and 2 for `coinbase.csv` file.

# Read in the CSV file called "coinbase.csv" using the Path module. 
# The CSV file is located in the Resources folder.
# Set the index to the column "Timestamp"
# Set the parse_dates and infer_datetime_format parameters
coinbase_csvpath = Path('./Resources/coinbase.csv')
coinbase = pd.read_csv(
    coinbase_csvpath, 
    index_col="Timestamp", 
    parse_dates=True, 
    infer_datetime_format=True)

# Use the head (and/or tail) function to confirm that the data was imported properly.
# Using the head function to confirm that the data was imported properly.
coinbase.head()


# Using the tail function to confirm that the data was imported properly.
coinbase.tail()


# ## Prepare the Data
#
# To prepare and clean your data for analysis, complete the following steps:
#
# 1. For the bitstamp DataFrame, replace or drop all `NaN`, or missing, values in the DataFrame.
#
# 2. Use the `str.replace` function to remove the dollar signs ($) from the values in the Close column.
#
# 3. Convert the data type of the Close column to a `float`.
#
# 4. Review the data for duplicated values, and drop them if necessary.
#
# 5. Repeat Steps 1–4 for the coinbase DataFrame.

# ### Step 1: For the bitstamp DataFrame, replace or drop all `NaN`, or missing, values in the DataFrame.

# +
# For the bitstamp DataFrame, replace or drop all NaNs or missing values in the DataFrame
bitstamp = bitstamp.dropna()

# Confirming all NaN values are dropped
bitstamp.isnull().sum()

# -

# ### Step 2: Use the `str.replace` function to remove the dollar signs ($) from the values in the Close column.

# +
# Use the str.replace function to remove the dollar sign, $, from the values in the Close column
bitstamp.loc[:, "Close"] = bitstamp.loc[:, "Close"].str.replace("$", "")

# Display the first five rows to ensure removal of dollar sign worked as expected
bitstamp.head()

# -

# ### Step 3: Convert the data type of the Close column to a `float`.

# +
# Convert the Close data type to a float
bitstamp.loc[:, "Close"] = bitstamp.loc[:, "Close"].astype("float")

# Confirm the data type conversion worked as expected
bitstamp.dtypes

# -

# ### Step 4: Review the data for duplicated values, and drop them if necessary.

# +
# Review the data for duplicate values, and drop them if necessary

# Using the duplicated function in conjunction with the sum function to confirm the number of duplicate values in the DataFrame
# Running this shows 0 duplicate values in the bitstamp DataFrame so it is not necessary to drop duplicated values
bitstamp.duplicated().sum()

# -

# ### Step 5: Repeat Steps 1–4 for the coinbase DataFrame.

# Repeat Steps 1–4 for the coinbase DataFrame


# +
# For the coibase DataFrame, replace or drop all NaNs or missing values in the DataFrame
coinbase = coinbase.dropna()

# Confirming all NaN values are dropped
coinbase.isnull().sum()


# +
# Use the str.replace function to remove the dollar sign, $, from the values in the Close column
coinbase.loc[:, "Close"] = coinbase.loc[:, "Close"].str.replace("$", "")

# Display the first five rows to ensure removal of dollar sign worked as expected
coinbase.head()


# +
# Convert the Close data type to a float
coinbase.loc[:, "Close"] = coinbase.loc[:, "Close"].astype("float")

# Confirm the data type conversion worked as expected
coinbase.dtypes


# +
# Review the data for duplicate values, and drop them if necessary

# Using the duplicated function in conjunction with the sum function to confirm the number of duplicate values in the DataFrame
# Running this shows 0 duplicate values in the coinbase DataFrame so it is not necessary to drop duplicated values
coinbase.duplicated().sum()

# -

# ## Analyze the Data
#
# Your analysis consists of the following tasks: 
#
# 1. Choose the columns of data on which to focus your analysis.
#
# 2. Get the summary statistics and plot the data.
#
# 3. Focus your analysis on specific dates.
#
# 4. Calculate the arbitrage profits.

# ### Step 1: Choose columns of data on which to focus your analysis.
#
# Select the data you want to analyze. Use `loc` or `iloc` to select the following columns of data for both the bitstamp and coinbase DataFrames:
#
# * Timestamp (index)
#
# * Close
#

# +
# Use loc or iloc to select `Timestamp (the index)` and `Close` from bitstamp DataFrame
bitstamp_sliced = bitstamp.loc[:, "Close"]

# Review the first five rows of the DataFrame
bitstamp_sliced.head()

# +
# Use loc or iloc to select `Timestamp (the index)` and `Close` from coinbase DataFrame
coinbase_sliced = coinbase.loc[:, "Close"]

# Review the first five rows of the DataFrame
coinbase_sliced.head()
# -

# ### Step 2: Get summary statistics and plot the data.
#
# Sort through the time series data associated with the bitstamp and coinbase DataFrames to identify potential arbitrage opportunities. To do so, complete the following steps:
#
# 1. Generate the summary statistics for each DataFrame by using the `describe` function.
#
# 2. For each DataFrame, create a line plot for the full period of time in the dataset. Be sure to tailor the figure size, title, and color to each visualization.
#
# 3. In one plot, overlay the visualizations that you created in Step 2 for bitstamp and coinbase. Be sure to adjust the legend and title for this new visualization.
#
# 4. Using the `loc` and `plot` functions, plot the price action of the assets on each exchange for different dates and times. Your goal is to evaluate how the spread between the two exchanges changed across the time period that the datasets define. Did the degree of spread change as time progressed?

# Generate the summary statistics for the focused bitstamp DataFrame
bitstamp_sliced.describe()


# Generate the summary statistics for the focused coinbase DataFrame
coinbase_sliced.describe()


# Create a line plot for the bitstamp DataFrame for the full length of time in the dataset 
# Be sure that the figure size, title, and color are tailored to each visualization
bitstamp_sliced.plot(figsize=(15, 10), title='Bitstamp', color='blue', ylabel='Close')


# Create a line plot for the coinbase DataFrame for the full length of time in the dataset 
# Be sure that the figure size, title, and color are tailored to each visualization
coinbase_sliced.plot(figsize=(15, 10), title='Coinbase', color='orange', ylabel='Close')


# Overlay the visualizations for the bitstamp and coinbase DataFrames in one plot
# The plot should visualize the prices over the full lenth of the dataset
# Be sure to include the parameters: legend, figure size, title, and color and label
bitstamp_sliced.plot(legend=True, figsize=(15, 10), title='Coinbase vs Bitstamp', color='blue', label='Bitstamp', ylabel='Close')
coinbase_sliced.plot(legend=True, figsize=(15, 10), color='orange', label='Coinbase', ylabel='Close')


# Using the loc and plot functions, create an overlay plot that visualizes 
# the price action of both DataFrames for a one month period early in the dataset
# Be sure to include the parameters: legend, figure size, title, and color and label
bitstamp_sliced.loc['2018-01-01':'2018-02-01'].plot(legend=True, figsize=(15, 10), title='Exchange Comparison (January 2018)', color='blue', label='Bitstamp', ylabel='Close')
coinbase_sliced.loc['2018-01-01':'2018-02-01'].plot(legend=True, figsize=(15, 10), color='orange', label='Coinbase', ylabel='Close')


# Using the loc and plot functions, create an overlay plot that visualizes 
# the price action of both DataFrames for a one month period later in the dataset
# Be sure to include the parameters: legend, figure size, title, and color and label 
bitstamp_sliced.loc['2018-03-01':'2018-04-01'].plot(legend=True, figsize=(15, 10), title='Exchange Comparison (March 2018)', color='blue', label='Bitstamp', ylabel='Close')
coinbase_sliced.loc['2018-03-01':'2018-04-01'].plot(legend=True, figsize=(15, 10), color='orange', label='Coinbase', ylabel='Close')


# **Question** Based on the visualizations of the different time periods, has the degree of spread change as time progressed?
#
# **Answer** The visualizations show that the degree of spread decreased as time progressed. The visualization of the data in January of 2018 has a wider spread than the data in March of 2018 and so appears to have opportunity for larger profits. Within the January data, it appears that the largest spread occured around 2018-01-28. Due to the change in spread over these time periods, I assume the arbitrage opportunities presented brought more participants to the market and so narrowed the spread and decreased the number of arbitrage opportunities.
#

# ### Step 3: Focus Your Analysis on Specific Dates
#
# Focus your analysis on specific dates by completing the following steps:
#
# 1. Select three dates to evaluate for arbitrage profitability. Choose one date that’s early in the dataset, one from the middle of the dataset, and one from the later part of the time period.
#
# 2. For each of the three dates, generate the summary statistics and then create a box plot. This big-picture view is meant to help you gain a better understanding of the data before you perform your arbitrage calculations. As you compare the data, what conclusions can you draw?

# Create an overlay plot that visualizes the two dataframes over a period of one day early in the dataset. 
# Be sure that the plots include the parameters `legend`, `figsize`, `title`, `color` and `label` 
bitstamp_sliced.loc['2018-01-28'].plot(legend=True, figsize=(15, 10), title='Exchange Comparison (January 28, 2018)', color='blue', label='Bitstamp', ylabel='Close')
coinbase_sliced.loc['2018-01-28'].plot(legend=True, figsize=(15, 10), color='orange', label='Coinbase', ylabel='Close')


# + tags=[]
# Using the early date that you have selected, calculate the arbitrage spread 
# by subtracting the coinbase lower closing prices from the bitstamp higher closing prices
arbitrage_spread_early = bitstamp_sliced.loc['2018-01-28'] - coinbase_sliced.loc['2018-01-28']

# Generate summary statistics for the early DataFrame
arbitrage_spread_early.describe()

# -

# Visualize the arbitrage spread from early in the dataset in a box plot
arbitrage_spread_early.plot(kind='box', title='Arbitrage Spread (January 28, 2018)')


# Create an overlay plot that visualizes the two dataframes over a period of one day from the middle of the dataset. 
# Be sure that the plots include the parameters `legend`, `figsize`, `title`, `color` and `label` 
bitstamp_sliced.loc['2018-02-08'].plot(legend=True, figsize=(15, 10), title='Exchange Comparison (February 8, 2018)', color='blue', label='Bitstamp', ylabel='Close')
coinbase_sliced.loc['2018-02-08'].plot(legend=True, figsize=(15, 10), color='orange', label='Coinbase', ylabel='Close')


# +
# Using the date in the middle that you have selected, calculate the arbitrage spread 
# by subtracting the cooinbase lower closing prices from the bitstamp higher closing prices
arbitrage_spread_middle = bitstamp_sliced.loc['2018-02-08'] - coinbase_sliced.loc['2018-02-08']

# Generate summary statistics 
arbitrage_spread_middle.describe()
# -

# Visualize the arbitrage spread from the middle of the dataset in a box plot
arbitrage_spread_middle.plot(kind='box', title='Arbitrage Spread (February 8, 2018)')


# Create an overlay plot that visualizes the two dataframes over a period of one day from late in the dataset. 
# Be sure that the plots include the parameters `legend`, `figsize`, `title`, `color` and `label` 
bitstamp_sliced.loc['2018-03-06'].plot(legend=True, figsize=(15, 10), title='Exchange Comparison (March 6, 2018)', color='blue', label='Bitstamp', ylabel='Close')
coinbase_sliced.loc['2018-03-06'].plot(legend=True, figsize=(15, 10), color='orange', label='Coinbase', ylabel='Close')


# +
# Using the date from the late that you have selected, calculate the arbitrage spread 
# by subtracting the coinbase lower closing prices from the bitstamp higher closing prices
arbitrage_spread_late = bitstamp_sliced.loc['2018-03-06'] - coinbase_sliced.loc['2018-03-06']

# Generate summary statistics for the late DataFrame
arbitrage_spread_late.describe()

# -

# Visualize the arbitrage spread from late in the dataset in a box plot
arbitrage_spread_late.plot(kind='box', title='Arbitrage Spread (March 6, 2018)')


# ### Step 4: Calculate the Arbitrage Profits
#
# Calculate the potential profits for each date that you selected in the previous section. Your goal is to determine whether arbitrage opportunities still exist in the Bitcoin market. Complete the following steps:
#
# 1. For each of the three dates, measure the arbitrage spread between the two exchanges by subtracting the lower-priced exchange from the higher-priced one. Then use a conditional statement to generate the summary statistics for each arbitrage_spread DataFrame, where the spread is greater than zero.
#
# 2. For each of the three dates, calculate the spread returns. To do so, divide the instances that have a positive arbitrage spread (that is, a spread greater than zero) by the price of Bitcoin from the exchange you’re buying on (that is, the lower-priced exchange). Review the resulting DataFrame.
#
# 3. For each of the three dates, narrow down your trading opportunities even further. To do so, determine the number of times your trades with positive returns exceed the 1% minimum threshold that you need to cover your costs.
#
# 4. Generate the summary statistics of your spread returns that are greater than 1%. How do the average returns compare among the three dates?
#
# 5. For each of the three dates, calculate the potential profit, in dollars, per trade. To do so, multiply the spread returns that were greater than 1% by the cost of what was purchased. Make sure to drop any missing values from the resulting DataFrame.
#
# 6. Generate the summary statistics, and plot the results for each of the three DataFrames.
#
# 7. Calculate the potential arbitrage profits that you can make on each day. To do so, sum the elements in the profit_per_trade DataFrame.
#
# 8. Using the `cumsum` function, plot the cumulative sum of each of the three DataFrames. Can you identify any patterns or trends in the profits across the three time periods?
#
# (NOTE: The starter code displays only one date. You'll want to do this analysis for two additional dates).

# #### 1. For each of the three dates, measure the arbitrage spread between the two exchanges by subtracting the lower-priced exchange from the higher-priced one. Then use a conditional statement to generate the summary statistics for each arbitrage_spread DataFrame, where the spread is greater than zero.
#
# *NOTE*: For illustration, only one of the three dates is shown in the starter code below.

# +
# For the date early in the dataset, measure the arbitrage spread between the two exchanges
# by subtracting the lower-priced exchange from the higher-priced one

# Use a conditional statement to generate the summary statistics for each arbitrage_spread DataFrame


# +
# Repeating for Assignment Ask
# I would generally not include this a second time. This has has already been performed above.

# Using the early date that you have selected, calculate the arbitrage spread 
# by subtracting the coinbase lower closing prices from the bitstamp higher closing prices
arbitrage_spread_early = bitstamp_sliced.loc['2018-01-28'] - coinbase_sliced.loc['2018-01-28']

# Generate summary statistics for the early DataFrame
arbitrage_spread_early.describe()


# +
# Repeating for Assignment Ask
# I would generally not include this a second time. This has has already been performed above.

# Using the date in the middle that you have selected, calculate the arbitrage spread 
# by subtracting the cooinbase lower closing prices from the bitstamp higher closing prices
arbitrage_spread_middle = bitstamp_sliced.loc['2018-02-08'] - coinbase_sliced.loc['2018-02-08']

# Generate summary statistics 
arbitrage_spread_middle.describe()


# +
# Repeating for Assignment Ask
# I would generally not include this a second time. This has has already been performed above.

# Using the date from the late that you have selected, calculate the arbitrage spread 
# by subtracting the coinbase lower closing prices from the bitstamp higher closing prices
arbitrage_spread_late = bitstamp_sliced.loc['2018-03-06'] - coinbase_sliced.loc['2018-03-06']

# Generate summary statistics for the late DataFrame
arbitrage_spread_late.describe()

# -

# #### Analysis of Descriptive Data for the Three Evaluated Dates
#

# January 28, 2018, had the largest mean with an average difference between the prices on the two indexes being $247.552326. It also had the largest max spread of $439.010000.
#
# We can see that the mean spread was lower on February 8 than on January 28, and even lower on March 6 than on Febraury 8 or January 28. This would fit into my previous analysis when reviewing the larger dataset where I stated that the spread decreased over time.
#
# We can see a negative minimum value in the descriptive statistics for February 8 and March 6 which shows us that there was a time when the price on the Coinbase exchange was higher than the price on the Bitstamp exchange on each of these dates.
#

# #### 2. For each of the three dates, calculate the spread returns. To do so, divide the instances that have a positive arbitrage spread (that is, a spread greater than zero) by the price of Bitcoin from the exchange you’re buying on (that is, the lower-priced exchange). Review the resulting DataFrame.

# +
# For the date early in the dataset, calculate the spread returns by dividing the instances when the arbitrage spread is positive (> 0) 
# by the price of Bitcoin from the exchange you are buying on (the lower-priced exchange).
spread_return_early = arbitrage_spread_early[arbitrage_spread_early>0] / coinbase_sliced.loc['2018-01-28']

# Review the spread return DataFrame
spread_return_early
# -

# Print summary statistics
spread_return_early.describe()


# +
# For the date in the middle of the dataset, calculate the spread returns by dividing the instances when the arbitrage spread is positive (> 0) 
# by the price of Bitcoin from the exchange you are buying on (the lower-priced exchange).
spread_return_middle = arbitrage_spread_middle[arbitrage_spread_middle>0] / coinbase_sliced.loc['2018-02-08']

# Review the spread return DataFrame
spread_return_middle

# -

# Print summary statistics
spread_return_middle.describe()


# +
# # For the date late in the dataset, calculate the spread returns by dividing the instances when the arbitrage spread is positive (> 0) 
# by the price of Bitcoin from the exchange you are buying on (the lower-priced exchange).
spread_return_late = arbitrage_spread_late[arbitrage_spread_late>0] / coinbase_sliced.loc['2018-03-06']

# Review the spread return DataFrame
spread_return_late

# -

# Print summary statistics
spread_return_late.describe()


# #### 3. For each of the three dates, narrow down your trading opportunities even further. To do so, determine the number of times your trades with positive returns exceed the 1% minimum threshold that you need to cover your costs.

# For the date early in the dataset, determine the number of times your trades with positive returns 
# exceed the 1% minimum threshold (.01) that you need to cover your costs
profitable_trades_early = spread_return_early[spread_return_early > 0.01]
len(profitable_trades_early)

# Review the first five profitable trades
profitable_trades_early.head()


# For the date in the middle of the dataset, determine the number of times your trades with positive returns 
# exceed the 1% minimum threshold (.01) that you need to cover your costs
profitable_trades_middle = spread_return_middle[spread_return_middle > 0.01]
len(profitable_trades_middle)


# Review the first five profitable trades
profitable_trades_middle.head()


# For the date early in the dataset, determine the number of times your trades with positive returns 
# exceed the 1% minimum threshold (.01) that you need to cover your costs
profitable_trades_late = spread_return_late[spread_return_late > 0.01]
len(profitable_trades_late)


# Review the first five profitable trades
profitable_trades_late.head()


# #### 4. Generate the summary statistics of your spread returns that are greater than 1%. How do the average returns compare among the three dates?

# For the date early in the dataset, generate the summary statistics for the profitable trades
# or your trades where the spread returns are are greater than 1%
profitable_trades_early.describe()


# For the date in the middle of the dataset, generate the summary statistics for the profitable trades
# or your trades where the spread returns are are greater than 1%
profitable_trades_middle.describe()


# For the date late in the dataset, generate the summary statistics for the profitable trades
# or you trades where the spread returns are are greater than 1%
profitable_trades_late.describe()


# #### Analysis Accounting for Profit Greater than 1%

# +
January 28, 2018, had 1,378 trades that would have produced a profit greater than 1%. The average return was 2.2201% for the profitable trades, which would account to a 1.2201% average profit being kept if we have trade costs equal to 1%.

February 8, 2018, only had one (1) trade that produced a profit greater than 1%. The trade produced a profit of 1.1103%, which would only be a profit of 0.1103% being kept if we have trade costs equal to 1%.

March 6, 2018, had zero (0) trades that produced a profit greater than 1%.

Taking this additional analysis into account, accounting for profitable trades with spread returns greater than 1%, we see a much better picture of the data.

# -

# #### 5. For each of the three dates, calculate the potential profit, in dollars, per trade. To do so, multiply the spread returns that were greater than 1% by the cost of what was purchased. Make sure to drop any missing values from the resulting DataFrame.

# +
# For the date early in the dataset, calculate the potential profit per trade in dollars 
# Multiply the profitable trades by the cost of the Bitcoin that was purchased
profit_early = profitable_trades_early * coinbase_sliced.loc['2018-01-28']

# Drop any missing values from the profit DataFrame
profit_per_trade_early = profit_early.dropna()

# View the early profit DataFrame
profit_per_trade_early


# +
# For the date in the middle of the dataset, calculate the potential profit per trade in dollars 
# Multiply the profitable trades by the cost of the Bitcoin that was purchased
profit_middle = profitable_trades_middle * coinbase_sliced.loc['2018-02-08']

# Drop any missing values from the profit DataFrame
profit_per_trade_middle = profit_middle.dropna()

# View the early profit DataFrame
profit_per_trade_middle


# +
# For the date late in the dataset, calculate the potential profit per trade in dollars 
# Multiply the profitable trades by the cost of the Bitcoin that was purchased
profit_late = profitable_trades_late * coinbase_sliced.loc['2018-03-06']

# Drop any missing values from the profit DataFrame
profit_per_trade_late = profit_late.dropna()

# View the early profit DataFrame
profit_per_trade_late

# -

# #### 6. Generate the summary statistics, and plot the results for each of the three DataFrames.

# Generate the summary statistics for the early profit per trade DataFrame
profit_per_trade_early.describe()


# Generate the summary statistics for the middle profit per trade DataFrame
profit_per_trade_middle.describe()


# Generate the summary statistics for the late profit per trade DataFrame
profit_per_trade_late.describe()


# Plot the results for the early profit per trade DataFrame
profit_per_trade_early.plot(figsize=(15, 10), title='Profit Per Trade - January 28, 2018', color='blue', ylabel='USD ($)')


# Plot the results for the middle profit per trade DataFrame
profit_per_trade_middle.plot(figsize=(15, 10), title='Profit Per Trade - February 8, 2018', color='blue', ylabel='USD ($)')


# As there was only one (1) profitable trade that produced a spread return greater than 1% on February 8, 2018, the plot is not useful. Other days can be analyzed to determine the best days within our data set.
#

# Plot the results for the late profit per trade DataFrame
profit_per_trade_late.plot(figsize=(15, 10), title='Profit Per Trade - March 6, 2018', color='blue', ylabel='USD ($)')


# As there was were zero (0) profitable trades that produced a spread return greater than 1% on March 6, 2018, the plot is not useful. Other days can be analyzed to determine the best days within our data set.
#

# #### 7. Calculate the potential arbitrage profits that you can make on each day. To do so, sum the elements in the profit_per_trade DataFrame.

# Calculate the sum of the potential profits for the early profit per trade DataFrame
profit_per_trade_early.sum()


# Calculate the sum of the potential profits for the middle profit per trade DataFrame
profit_per_trade_middle.sum()


# Calculate the sum of the potential profits for the late profit per trade DataFrame
profit_per_trade_late.sum()


# #### 8. Using the `cumsum` function, plot the cumulative sum of each of the three DataFrames. Can you identify any patterns or trends in the profits across the three time periods?

# Use the cumsum function to calculate the cumulative profits over time for the early profit per trade DataFrame
cumulative_profit_early = profit_per_trade_early.cumsum()


# Plot the cumulative sum of profits for the early profit per trade DataFrame
cumulative_profit_early.plot(figsize=(15, 10), title='Cumulative Sum - January 28, 2018', color='blue', ylabel='USD ($)')


# Use the cumsum function to calculate the cumulative profits over time for the middle profit per trade DataFrame
cumulative_profit_middle = profit_per_trade_middle.cumsum()


# Plot the cumulative sum of profits for the middle profit per trade DataFrame
cumulative_profit_middle.plot(figsize=(15, 10), title='Cumulative Sum - February 8, 2018', color='blue', ylabel='USD ($)')


# As there was only one (1) profitable trade that produced a spread return greater than 1% on February 8, 2018, the plot is not useful. Other days can be analyzed to determine the best days within our data set.

# Use the cumsum function to calculate the cumulative profits over time for the late profit per trade DataFrame
cumulative_profit_late = profit_per_trade_late.cumsum()


# Plot the cumulative sum of profits for the late profit per trade DataFrame
cumulative_profit_late.plot(figsize=(15, 10), title='Cumulative Sum - March 6, 2018', color='blue', ylabel='USD ($)')


# As there was were zero (0) profitable trades that produced a spread return greater than 1% on March 6, 2018, the plot is not useful. Other days can be analyzed to determine the best days within our data set.
#

# **Question:** After reviewing the profit information across each date from the different time periods, can you identify any patterns or trends?
#     
# **Answer:** Spreads decrease over time and tend to be wider in the morning in our data set. In addition, the spreads narrow and less arbitrage opportunities appear to exist as we move from early in our data set to late in our data set. This would be in-line with more market participants quickly acting on the opportunity and closing the spread.
#

StarcoderdataJupyterScriptsDedupFiltered