まずは、Visual Studio Codeを起動してプログラムファイルを作成する
Visual Studio Code (VS Code)を起動したら新規ファイル(*.py)を作成して行1-430をコピペします。
ここでは、Jupter NotebookのようにPythonのプログラムをセル単位で実行します。
VS Codeの場合は「#%%」から「#%%」の間がセルになります。
セルを選択したら[Ctrl + Enter」でセルのコードを実行します。
IPythonが起動されて「インタラクティブ」ウィンドウが表示されます。
「インタラクティブ」ウィンドウからはPythonのコードを入力して実行させることができます。
たとえば、「df.info()」を入力して[Shift + Enter」で実行します。
* Article.py:
# Daily return vs log returns article (Part5)
# %%
### Import pandas and matplotlib libraries
import os
import math
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.dates import MonthLocator, DateFormatter
from matplotlib.dates import DayLocator, DateFormatter
import mplfinance as mpf # pip install --upgrade mplfinance
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import datetime as dt
from datetime import timedelta
from time import sleep
import yfinance as yf
import warnings
warnings.simplefilter('ignore')
plt.style.use('fivethirtyeight')
pd.set_option('display.max_rows', 10)
# %%
######################################################################################################################################
def load_data(symbol: str, start_date: dt.datetime , end_date: dt.datetime, period='1d', interval='1d', prepost=True) -> pd.DataFrame:
# valid periods: 1d,5d,1mo,3mo,6mo,1y,2y,5y,10y,ytd,max
# fetch data by interval (including intraday if period < 60 days)
# valid intervals: 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
try:
end_date = end_date + timedelta(days=1)
start_date_str = dt.datetime.strftime(start_date, "%Y-%m-%d")
end_date_str = dt.datetime.strftime(end_date, "%Y-%m-%d")
print(f"Loading data for {symbol}: start_date={start_date_str}, end_date={end_date_str}, {period=}, {interval=}")
df = yf.download(symbol, start=start_date_str, end=end_date_str, period=period, interval=interval, prepost=prepost)
# Date Open High Low Close Adj Close Volume Symbol : interval=1d,5d,1wk,1mo,3mo
# Datetime Open High Low Close Adj Close Volume Symbol : interval=1m,2m,5m,15m,30m,60m,90m,1h
# Add symbol
df['symbol'] = symbol
# Reset index
df.reset_index(inplace=True)
# Rename Date or Datetime column name to Time
if interval in '1m,2m,5m,15m,30m,60m,90m,1h':
df.rename(columns={'Datetime': 'Date'}, inplace=True)
else: # interval=1d,5d,1wk,1mo,3mo
df.rename(columns={'Date': 'Date'}, inplace=True)
# Convert column names to lower case
df.columns = df.columns.str.lower()
return df
except Exception as e:
print(f"load_data({symbol}) exception error: {str(e)}")
return pd.DataFrame()
############################################
def get_data(csv_file: str) -> pd.DataFrame:
print(f"Loading data: {csv_file} ")
df = pd.read_csv(csv_file)
# date,open,high,low,close,adj close,volume,symbol
df['date'] = pd.to_datetime(df['date'])
# df['date'] = pd.to_datetime(df['date'], utc=True)
df.set_index(['date'], inplace=True)
return df
##############################
# Main
##############################
pd.set_option('display.max_rows', 6)
### Load the crypto data from yahoo finance
symbol = 'BTC-JPY' # BTC-JPY, ETH-JPY, LTC-JPY, OP-USD, HEX-USD, TWT-US, MATIC-USD, DOGE-USD
interval = '1d' # 1m,2m,5m,15m,30m,60m,90m,1h,1d,5d,1wk,1mo,3mo
csv_file = f"data/csv/yahoo_crypto_20200101({symbol})_{interval}.csv" # data/csv/yahoo_crypto_20200101(BTC-JPY)_1d.csv
isFile = os.path.isfile(csv_file)
if not isFile:
if interval in '1m,2m,5m,15m,30m,60m,90m,1h':
end = dt.datetime.now()
start = end - timedelta(days=7)
else: # interval=1d,5d,1wk,1mo,3mo
start = dt.datetime(2020,1,1) # 2014,1,1 or 2020,1,1 or 2023,1,1
end = dt.datetime.now()
# load_data(symbol: str, start_date: dt.datetime , end_date: dt.datetime, period='1d', interval={'1m'|'1d'}, prepost=True) -> pd.DataFrame:
df = load_data(symbol, start, end, period='1d', interval=interval)
if not df.empty:
df.to_csv(csv_file, index=False)
# end of if not isFile:
isFile = os.path.isfile(csv_file)
if isFile:
df = get_data(csv_file)
df.dropna(inplace=True)
if df.empty:
print(f"Quit the program due to df is empty: {df.empty=}")
quit()
raw_df = df.copy()
# %%
df = raw_df.copy()
### Plot Line Chart : Close price
fig = plt.figure(figsize=(12, 6))
plt.plot(df['close'], label='close')
plt.title(f'{symbol} Plot Line Chart: Close Price')
plt.xlabel('Date')
plt.ylabel('Price')
plt.xticks(rotation=45)
plt.legend(loc='best')
plt.show()
# %%
df = raw_df.copy()
### Plot Bar Chart : Volume
fig = plt.figure(figsize=(12, 6))
plt.bar(df.index, df['volume'], label='volume')
plt.title(f'{symbol} Plot Bar Chart: Volume')
plt.xlabel('Date')
plt.ylabel('Volume')
plt.xticks(rotation=45)
plt.legend(loc='best')
plt.show()
# %%
df = raw_df.copy()
### Plot Close, Cumulative Log Return and Volume
# fig, ax = plt.subplots(2, 1, figsize=(10, 8))
# fig, ax1, ax2 = plt.subplots(2, 1, figsize=(10, 8))
fig = plt.figure(figsize=(12, 6))
ax1 = fig.add_subplot(2, 1, 1) # Plot Close
ax2 = fig.add_subplot(2, 1, 2) # Plot Volume
ax1.set_title(f'{symbol} Plot Close & Volume')
# Plot close price : line chart
ax1.plot(df['close'], label='close')
ax1.tick_params(bottom=False, labelbottom=False)
# ax1.tick_params(top=False,
# bottom=False,
# left=False,
# right=False,
# labelleft=True,
# labelbottom=True)
ax1.set_ylabel('Close Price')
ax1.legend(loc='best')
# Plot volume : bar chart
ax2.bar(df.index, df['volume'], label='volume')
# ax2.set_title('Volume')
ax2.set_xlabel('Date')
ax2.set_ylabel('Volume')
ax2.legend(loc='best')
# plt.legend(loc='best')
plt.xticks(rotation=45)
plt.show()
# %%
df = raw_df.copy()
# ### Plot line & volume using twinx()
fig, ax1 = plt.subplots(figsize=(12, 6))
ax2 = ax1.twinx()
ax1.set_title(f'{symbol} Plot Close & Volume')
ax1.plot(df['close'], label='close')
ax1.set_ylabel('Close Price')
ax1.tick_params(axis='y')
ax2.bar(df.index, df['volume'], label='volume', alpha=0.3)
ax2.set_ylabel('Volume')
ax2.tick_params(axis='y')
ax1.set_ylim(bottom=0)
ax2.set_ylim(bottom=0)
ax1.grid(True)
ax2.grid(False)
# Set the x-axis to display year/month format
ax1.xaxis.set_major_locator(DayLocator(interval=120))
# ax1.xaxis.set_major_locator(MonthLocator())
ax1.xaxis.set_major_formatter(DateFormatter('%y/%m'))
# ax1.xaxis.set_major_formatter(DateFormatter('%Y/%m'))
ax1.set_xlabel('Date', fontsize=9)
fig.autofmt_xdate(rotation=45)
plt.show()
# %%
df = raw_df.copy()
### Plot Candlestick : mplfinance
df = df.tail(60)
# mpf.plot(df) # type='candle', type='line', type='renko', or type='pnf'
mpf.plot(
df,
type='candle',
datetime_format='%m/%d',
style = 'binance', # yahoo, binance, mike
title=f'{symbol} Plot Candlestick (type=candle, style=mike)',
figratio=(12,6)
)
# mpf.plot(df, type='line')
# mpf.plot(df, type='renko')
# mpf.plot(df, type='pnf')
# figratio=(30,15),
# title='Some stock price',
# tight_layout=True,
# style = 'yahoo',
# mpf.available_styles()
# ['binance',
# 'blueskies',
# 'brasil',
# 'charles',
# 'checkers',
# 'classic',
# 'default',
# 'ibd',
# 'kenan',
# 'mike',
# 'nightclouds',
# 'sas',
# 'starsandstripes',
# 'yahoo']
# %%
df = raw_df.copy()
### Plot moving averages with the mav keyword
df = df.tail(60)
mpf.plot(
df,
type='ohlc',
mav=4,
datetime_format='%m/%d',
style = 'yahoo',
title=f'{symbol} Add moveing average (type=ohlc, mav=4)',
figratio=(12,6)
)
# %%
df = raw_df.copy()
### Plot Candlestick with moveing average
df = df.tail(60)
mpf.plot(
df,
type='candle',
mav=(3,6,9),
datetime_format='%m/%d',
style = 'yahoo',
title=f'{symbol} Add moveing average (type=candle, mav=(3,6,9))',
figratio=(12,6)
)
# %%
df = raw_df.copy()
### Plot Candlestick with moveing average & volume (stype=yahoo)
df = df.tail(60)
mpf.plot(
df,
type='candle',
mav=(3,6,9),
volume=True,
datetime_format='%m/%d',
style = 'yahoo',
title=f'{symbol} Add volume (type=candle, mav=(3,6,9), volume=True)',
figratio=(12,6)
)
# figratio=(30,15),
# title='Some stock price',
# tight_layout=True,
# style = 'yahoo',
# %%
df = raw_df.copy()
### Plot Candlestick with moveing average & volume (style=mike)
df = df.tail(60)
mpf.plot(
df,
type='candle',
mav=(3,6,9),
volume=True,
datetime_format='%m/%d',
style='mike', # yahoo, binance, mike
title=f'{symbol} Add volume (type=candle, mav=(3,6,9), volume=True)',
figratio=(12,6)
)
# %%
df = raw_df.copy()
# Load data
df = df.reset_index()
df = df.tail(150)
df = df.sort_values('date')
### Candlestick with Rangeslider
# Create subplots
# fig = make_subplots(rows=2, cols=1)
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.02)
# Plot candlestick chart
fig.add_trace(go.Candlestick(x=df['date'],
open=df['open'], high=df['high'],
low=df['low'], close=df['close'],
increasing=dict(line=dict(color='green')),
decreasing=dict(line=dict(color='red')),
name='Candlestick'), row=1, col=1)
# Plot moving averages
short_window = 20
long_window = 50
df['SMA_short'] = df['close'].rolling(short_window).mean()
df['SMA_long'] = df['close'].rolling(long_window).mean()
fig.add_trace(go.Scatter(x=df['date'], y=df['SMA_short'], name=f'SMA{short_window}'), row=1, col=1)
fig.add_trace(go.Scatter(x=df['date'], y=df['SMA_long'], name=f'SMA{long_window}'), row=1, col=1)
# Add volume bar chart
fig.add_trace(go.Bar(x=df['date'], y=df['volume'], name='Volume'), row=2, col=1)
# Format x-axis dates
fig.update_xaxes(
rangebreaks=[dict(bounds=['sat', 'mon'])],
type='date',
tickformat='%Y/%m'
)
# Add chart title and axis labels
fig.update_layout(title=f'{symbol} Candlestick Chart with Moving Averages and Volume (With Rangeslider)',
xaxis_title='Date',
yaxis_title='Price')
# Show plot
fig.show()
# %%
### Candlestick without Rangeslider
# Create subplots
# fig = make_subplots(rows=2, cols=1)
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.02)
# Plot candlestick chart
fig.add_trace(go.Candlestick(x=df['date'],
open=df['open'], high=df['high'],
low=df['low'], close=df['close'],
increasing=dict(line=dict(color='green')),
decreasing=dict(line=dict(color='red')),
name='Candlestick'), row=1, col=1)
# Plot moving averages
short_window = 20
long_window = 50
df['SMA_short'] = df['close'].rolling(short_window).mean()
df['SMA_long'] = df['close'].rolling(long_window).mean()
fig.add_trace(go.Scatter(x=df['date'], y=df['SMA_short'], name=f'SMA{short_window}'), row=1, col=1)
fig.add_trace(go.Scatter(x=df['date'], y=df['SMA_long'], name=f'SMA{long_window}'), row=1, col=1)
# Add volume bar chart
fig.add_trace(go.Bar(x=df['date'], y=df['volume'], name='Volume'), row=2, col=1)
# Format x-axis dates
fig.update_xaxes(
rangebreaks=[dict(bounds=['sat', 'mon'])],
type='date',
tickformat='%Y/%m'
)
# Add chart title and axis labels
fig.update_layout(title=f'{symbol} Candlestick Chart with Moving Averages and Volume (Without Rangeslider)',
xaxis_rangeslider_visible=False,
# xaxis_title='Date',
yaxis_title='Price')
# fig.update_layout(xaxis_rangeslider_visible=False)
# Show plot
fig.show()
図1にはVS Codeの画面が表示されています。
次のステップでは「セル」を選択して「セル」単位でPythonのコードを実行します。