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.
按照惯例,我们将这些做市商称为金融业的“卖方”。卖方包括高盛(Goldman Sachs)和摩根士丹利(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”
买方是指个人投资者,以及共同基金对冲基金等投资基金。这个Nanodegree专注于“买方”的视角

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

Quize:Resample Data

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.
上市后会议通常由交易者使用,他们希望在市场收盘后进行公司公告交易,或者让经纪人完成整个不完整的客户订单。

为者常成,行者常至