# AI For Trading: Market Mechanics (4)

## Buy Side and Sell Side

We’ve just seen that there are buyers and sellers who go through the stock exchange to buy a stock that they think will do well, or sell a stock that they wish to remove from their investments

We’ve also introduced the market maker, who serves as the counterparty of these buyers or sellers

Since every buyer needs a seller, and every seller needs a buyer, a market maker plays the role of seller to those who wish to buy, and plays the role of buyer for those who wish to sell.

By convention, we refer to these market makers as the “sell side” of the finance industry. The sell side includes investment banks such as Goldman Sachs and Morgan Stanley.

The buy side refers to individual investors, and investment funds such as mutual funds and hedge funds. This Nanodegree is focused on the perspective of the “buy side”

However, it’s good to learn about the “sell side”, because these are the people that the “buy side” usually does business when they enter the market to buy or sell stocks.

## Liquidity

Liquidity: The ability to trade an asset at a stable price.

## OHLC

OHLC:Open,High,Low,Close
Open: open is the stock price at the beginning of the period.
High:high and low capture its range of movement
Close: close is where it ends

Resample Data

## Pandas Resample

You've learned about bucketing to different periods of time like Months. Let's see how it's done. We'll start with an example series of days.

import numpy as np
import pandas as pd

dates = pd.date_range('10/10/2018', periods=11, freq='D')
close_prices = np.arange(len(dates))

close = pd.Series(close_prices, dates)
close
2018-10-10     0
2018-10-11     1
2018-10-12     2
2018-10-13     3
2018-10-14     4
2018-10-15     5
2018-10-16     6
2018-10-17     7
2018-10-18     8
2018-10-19     9
2018-10-20    10
Freq: D, dtype: int64

Let's say we want to bucket these days into 3 day periods. To do that, we'll use the DataFrame.resample function. The first parameter in this function is a string called rule, which is a representation of how to resample the data. This string representation is made using an offset alias. You can find a list of them here. To create 3 day periods, we'll set rule to "3D".

close.resample('3D')
DatetimeIndexResampler [freq=<3 * Days>, axis=0, closed=left, label=left, convention=start, base=0]

This returns a DatetimeIndexResampler object. It's an intermediate object similar to the GroupBy object. Just like group by, it breaks the original data into groups. That means, we'll have to apply an operation to these groups. Let's make it simple and get the first element from each group.

close.resample('3D').first()
2018-10-10    0
2018-10-13    3
2018-10-16    6
2018-10-19    9
Freq: 3D, dtype: int64

You might notice that this is the same as .iloc[::3]

close.iloc[::3]
2018-10-10    0
2018-10-13    3
2018-10-16    6
2018-10-19    9
Freq: 3D, dtype: int64

So, why use the resample function instead of .iloc[::3] or the groupby function?

The resample function shines when handling time and/or date specific tasks. In fact, you can't use this function if the index isn't a time-related class.

try:
# Attempt resample on a series without a time index
pd.Series(close_prices).resample('W')
except TypeError:
print('It threw a TypeError.')
else:
print('It worked.')
It threw a TypeError.

One of the resampling tasks it can help with is resampling on periods, like weeks. Let's resample close from it's days frequency to weeks. We'll use the "W" offset allies, which stands for Weeks.

pd.DataFrame({
'days': close,
'weeks': close.resample('W').first()})
days weeks
2018-10-10 0.0 NaN
2018-10-11 1.0 NaN
2018-10-12 2.0 NaN
2018-10-13 3.0 NaN
2018-10-14 4.0 0.0
2018-10-15 5.0 NaN
2018-10-16 6.0 NaN
2018-10-17 7.0 NaN
2018-10-18 8.0 NaN
2018-10-19 9.0 NaN
2018-10-20 10.0 NaN
2018-10-21 NaN 5.0

The weeks offset considers the start of a week on a Monday. Since 2018-10-10 is a Wednesday, the first group only looks at the first 5 items. There are offsets that handle more complicated problems like filtering for Holidays. For now, we'll only worry about resampling for days, weeks, months, quarters, and years. The frequency you want the data to be in, will depend on how often you'll be trading. If you're making trade decisions based on reports that come out at the end of the year, we might only care about a frequency of years or months.

## OHLC

Now that you've seen how Pandas resamples time series data, we can apply this to Open, High, Low, and Close (OHLC). Pandas provides the Resampler.ohlc function will convert any resampling frequency to OHLC data. Let's get the Weekly OHLC.

close.resample('W').ohlc()
open high low close
2018-10-14 0 4 0 4
2018-10-21 5 10 5 10

Can you spot a potential problem with that? It has to do with resampling data that has already been resampled.

We're getting the OHLC from close data. If we want OHLC data from already resampled data, we should resample the first price from the open data, resample the highest price from the high data, etc..

To get the weekly closing prices from close, you can use the Resampler.last function.

close.resample('W').last()
2018-10-14     4
2018-10-21    10
Freq: W-SUN, dtype: int64

## Quiz

Implement days_to_weeks function to resample OHLC price data to weekly OHLC price data. You find find more Resampler functions here for calculating high and low prices.

import quiz_tests

def days_to_weeks(open_prices, high_prices, low_prices, close_prices):
"""Converts daily OHLC prices to weekly OHLC prices.

Parameters
----------
open_prices : DataFrame
Daily open prices for each ticker and date
high_prices : DataFrame
Daily high prices for each ticker and date
low_prices : DataFrame
Daily low prices for each ticker and date
close_prices : DataFrame
Daily close prices for each ticker and date

Returns
-------
open_prices_weekly : DataFrame
Weekly open prices for each ticker and date
high_prices_weekly : DataFrame
Weekly high prices for each ticker and date
low_prices_weekly : DataFrame
Weekly low prices for each ticker and date
close_prices_weekly : DataFrame
Weekly close prices for each ticker and date
"""

# TODO: Implement Function

open_prices_weekly = open_prices.resample('W').first()
high_prices_weekly = high_prices.resample('W').max()
low_prices_weekly = low_prices.resample('W').min()
close_prices_weekly = close_prices.resample('W').last()

return open_prices_weekly, high_prices_weekly, low_prices_weekly, close_prices_weekly

quiz_tests.test_days_to_weeks(days_to_weeks)
Tests Passed

## Quiz Solution

If you're having trouble, you can check out the quiz solution here.

## Volume

In general, large volumes of buy orders tend to sharply increase
Therefore, volume is an important factor to consider within your trading strategy.

## Gaps in Market data

Pre-market sessions (for the US market) are a period of time where stocks are very thinly traded

Market participants often use this to gauge the strength and direction of the market. P

Post-market sessions are often used by traders who want to trade on corporate announcements made after market closes, or for brokers to make whole of an incomplete client order.