☆☆ 新着記事 ☆☆

2020年6月25日木曜日

FLASK_WTFormsを使う基本のコード (入力エラー・メッセージ付)

(ファイル構成)
-- app.py
 |- / template
         |- index.html


(app.py)
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from flask import Flask, render_template, url_for, flash,redirect
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length
app = Flask(__name__)
app.config['SECRET_KEY'] = 'Thisisasecret!'
class Message(FlaskForm):
    username = StringField('username',
                            validators=[DataRequired(), Length(min=2, max=5)])
    password = PasswordField('password',
                             validators=[DataRequired(), Length(min=2, max=5)])
    submit = SubmitField('Check Up')

                            
@app.route('/', methods=['GET', 'POST'])
def form():
    form = Message()
    if form.validate_on_submit():
        flash(f'Found the result for {form.username.data}','success') #Bootstrapの機能
        result =  '<h1>The username is {}. <br>The password is {}.</h1>'.format(form.username.data, form.password.data)
        return redirect(url_for('form', result=result))
    return render_template("index.html", form=form ,)

if __name__ == '__main__':
    app.run()



(index.html)


     <form method="POST" action="">
            {{ form.hidden_tag() }}
  
                    {{ form.username.label }}
                    {% if form.username.errors %}
                        {{ form.username(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.username.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.username }}
                    {% endif %}
           
            
                    {{ form.password.label}}
                    {% if form.password.errors %}
                        {{ form.password(class="form-control form-control-lg is-invalid") }}
                        <div class="invalid-feedback">
                            {% for error in form.password.errors %}
                                <span>{{ error }}</span>
                            {% endfor %}
                        </div>
                    {% else %}
                        {{ form.password}}
                    {% endif %}
              
            <div class="form-group">
                {{ form.submit() }}
            </div>
 
        </form>

 {% with messages = get_flashed_messages(with_categories=true) %}
  {% if messages %}
   {% for category, message in messages %}
     <div class="alert alert-{{ category}}">
   {{ message}}
     </div>
   {% endfor %}
  {% endif %}
 {% endwith%}

 {{ result | safe}}



=======

resultの結果は、URLに反映されてしまう。要修正
http://127.0.0.1:5000/?result=%3Ch1%3EThe+username+is+123.+%3Cbr%3EThe+password+is+3333.%3C%2Fh1%3E


2020年6月22日月曜日

Matplotlib で表を作成し、png形式で画像として保存する

Matplotlibで表を作成する場合、一度グラフと表を作成し、表だけ表示を消す。



import matplotlib.pyplot as plt
import six


fig = plt.figure()
ax = fig.add_subplot(111)

col_labels = ['col1', 'col2', 'col3']
row_labels = ['row1', 'row2', 'row3']
table_vals = [[11, 12, 13], [21, 22, 23], [31, 32, 33]]

# Draw table
the_table = plt.table(cellText=table_vals,
                      colWidths=[0.1] * 3,
                      rowLabels=row_labels,
                      colLabels=col_labels,
                      loc='center')
the_table.auto_set_font_size(False)
the_table.set_fontsize(24)
the_table.scale(4, 4)

# Removing ticks and spines enables you to get the figure only with table
plt.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False)
plt.tick_params(axis='y', which='both', right=False, left=False, labelleft=False)
for pos in ['right','top','bottom','left']:
    plt.gca().spines[pos].set_visible(False)
plt.savefig('matplotlib-table', bbox_inches='tight', pad_inches=0.05)
plt.show()

(1) fig = plt.figure(figsize=(width height))
figの大きさを指定できる。値を指定しない場合のデフォルトは
[6.4, 4.8].


(2) Titleを付ける場合

  ax.set_title(label='TOP 10 Stock Price Gainer ', fontsize=25,
       loc="left", pad=0.5,
                 backgroundcolor='green',
                 color='white',
                 verticalalignment= 'baseline')

(2) ax =fig.add_subplot(111)
# figure内の枠の大きさとどこに配置している。subplot(行の数,列の数,何番目に配置しているか)





(3) 表を作成する

(Subplot Parameterの指定)
   plt.subplots_adjust(
        left=0.22,
        bottom=0.11,
        right=0.65,
        top=0.88,
        wspace=0.20,
        hspace=0.20)

left = 0.125  # the left side of the subplots of the figure
right = 0.9   # the right side of the subplots of the figure
bottom = 0.1  # the bottom of the subplots of the figure
top = 0.9     # the top of the subplots of the figure
wspace = 0.2  # the amount of width reserved for space between subplots,
              # expressed as a fraction of the average axis width
hspace = 0.2  # the amount of height reserved for space between subplots,
              # expressed as a fraction of the average axis height

(列幅の指定)
colWidths=[0.1] * 3,

列幅を変える場合は、それぞれ指定する。
colWidths=[0.5, 0.1, 0.2]

(テーブルの場所)
loc=’center’ :表を中央に配置する。


(画像ファイルにした際に表示される大きさ(Scale))
   the_table.scale(5, 5)
( width 5 inches, and its height 5 inches.)
(4) 表の表示の削除
plt.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False)
plt.tick_params(axis='y', which='both', right=False, left=False, labelleft=False)
又は
plt.axis(‘off’)

(セルの色を変える)

    # Cell Coloring
    for col in range(data_len):
        col_num= data_len-(col+1)
        if data['Close'][col_num]-data['Close'][col_num-1]>0:
            the_table[(col+1,5)].set_facecolor('#adff2f')
        else:
            the_table[(col+1,5)].set_facecolor('#ff0000') 




(セルの色を変える:)
table.properties()メソッドやset_text_props()等を使って変更
https://matplotlib.org/3.1.0/api/table_api.html

    # Cell Coloring
    table_props = the_table.properties()
    table_cells = table_props['child_artists']
    for i in range(4):
        the_table[(0,i)].set_facecolor('green')
        the_table[(0,i)].get_text().set_fontsize('25')
        the_table[(0,i)].get_text().set_color('white')
        the_table[(0,i)].get_text().set_fontweight('bold')
    for i in range(len(to_csv)):
        n =i +1
        the_table[(n,0)].get_text().set_fontweight('bold')
        the_table[(n,0)].get_text().set_fontsize('35')









https://www.geeksforgeeks.org/matplotlib-axes-axes-table-in-python/


# Implementation of matplotlib function
import matplotlib.pyplot as plt
  
val1 = ["{:X}".format(i) for i in range(10)]
val2 = ["{:02X}".format(10 * i) for i in range(10)]
val3 = [["" for c in range(10)] for r in range(10)]
  
fig, ax = plt.subplots()
ax.set_axis_off()
table = ax.table(
    cellText = val3, 
    rowLabels = val2, 
    colLabels = val1,
    rowColours =["palegreen"] * 10
    colColours =["palegreen"] * 10,
    cellLoc ='center'
    loc ='upper left')        
  
ax.set_title('matplotlib.axes.Axes.table() function Example',
             fontweight ="bold")
  
plt.show()

=================================================================================
こんな図






import yfinance as yf import pandas as pd import numpy as np import matplotlib.pyplot as plt import datetime import matplotlib.dates as mdates from matplotlib.dates import drange from matplotlib.dates import DateFormatter ticker_name="VOO" DJIA = yf.Ticker(ticker_name) data=DJIA.history( period='5d' ) data2=DJIA.history( period='6d' ) data.drop(columns=['Dividends','Stock Splits'],inplace=True) print(data) # Row Label row_labels_pre_sorted= [] row_labels=[] for d in data["Close"].keys(): modified_d = d.strftime('%Y-%m-%d') row_labels_pre_sorted.append(modified_d) row_labels = sorted(row_labels_pre_sorted, reverse=True) # Value row_name=[] for Open, High, Low, Close, Volume in zip(data['Open'],data['High'],data['Low'],data['Close'],data['Volume']): open_p = '{:,.2f}'.format(Open) row_name.append(open_p) high_p = '{:,.2f}'.format(High) row_name.append(high_p) Low_p = '{:,.2f}'.format(Low) row_name.append(Low_p) Close_p = '{:,.2f}'.format(Close) row_name.append(Close_p) row_name.append(Volume/1000000) list1= row_name[:5] list2= row_name[5:10] list3= row_name[5+5:10+5] list4= row_name[5+5*2:10+5*2] list5= row_name[5+5*3:10+5*3] val_list =[list5, list4, list3,list2,list1] table_vals = val_list # New table fig = plt.figure(figsize=(12, 4)) ax = fig.add_subplot(111) ax.set_title('Ticker Name : '+ticker_name, fontsize=36, pad=50) #fig.suptitle('Ticker: Dow Jones Industry Average(DJIA)', fontsize=32) row1 = 'Open' row2 = 'High' row3 = 'Low' row4 = 'Close' row5 = 'Volume(Mil)' col_labels = [row1, row2,row3,row4,row5] # Draw table the_table = plt.table(cellText=table_vals, colWidths=[0.1] * 5, rowLabels=row_labels, colLabels=col_labels, loc='center') the_table.auto_set_font_size(False) the_table.set_fontsize(20) # Cell Coloring if data['Close'][4]-data['Close'][3]>0: the_table[(1,3)].set_facecolor('#adff2f') else: the_table[(1,3)].set_facecolor('#ff0000') if data['Close'][3]-data['Close'][2]>0: the_table[(2,3)].set_facecolor('#adff2f') else: the_table[(2,3)].set_facecolor('#ff0000') if data['Close'][2]-data['Close'][1]>0: the_table[(3,3)].set_facecolor('#adff2f') else: the_table[(3,3)].set_facecolor('#ff0000') if data['Close'][1]-data['Close'][0]>0: the_table[(4,3)].set_facecolor('#adff2f') else: the_table[(4,3)].set_facecolor('#ff0000') if data['Close'][1]-data2['Close'][0]>0: the_table[(5,3)].set_facecolor('#adff2f') else: the_table[(5,3)].set_facecolor('#ff0000') the_table.scale(4, 4) # Removing ticks and spines enables you to get the figure only with table plt.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False) plt.tick_params(axis='y', which='both', right=False, left=False, labelleft=False) for pos in ['right','top','bottom','left']: plt.gca().spines[pos].set_visible(False) plt.savefig(ticker_name, bbox_inches='tight', pad_inches=0.05) plt.show()


2020年6月19日金曜日

Python Object -- Excelで管理する典型的表形式


参考)
PandasのDataFrameへの要素へのアクセス



import yfinance as yf
DJIA = yf.Ticker("DJIA")

data=DJIA.history(
    start="2020-06-11",
    end='2020-06-18'
    )

print(data)

                Open      High       Low     Close      Volume  Dividends  Stock Splits
Date
2020-06-10  27251.89  27355.22  26938.05  26989.99  6570840000          0             0
2020-06-11  26282.51  26294.08  25082.72  25128.17  7018890000          0             0
2020-06-12  25659.42  25965.55  25078.41  25605.54  5832250000          0             0
2020-06-15  25270.39  25891.58  24843.18  25763.16  5740660000          0             0
2020-06-16  26326.68  26611.03  25811.70  26289.98  5829240000          0             0
2020-06-17  26330.52  26400.07  26068.41  26119.61  4549390000          0             0

print(data.keys())
Index(['Open', 'High', 'Low', 'Close', 'Volume', 'Dividends', 'Stock Splits'], dtype='object')

print(data.index.values) //pandas
['2020-06-18T00:00:00.000000000' '2020-06-19T00:00:00.000000000']

print(data.columns.values) //pandas
['Open' 'High' 'Low' 'Close' 'Volume']


print(data['Close'])

Date
2020-06-10    26989.99
2020-06-11    25128.17
2020-06-12    25605.54
2020-06-15    25763.16
2020-06-16    26289.98
2020-06-17    26119.61
Name: Close, dtype: float64

print(data['Close'].keys())
DatetimeIndex(['2020-06-10', '2020-06-11', '2020-06-12', '2020-06-15',
               '2020-06-16', '2020-06-17'],
              dtype='datetime64[ns]', name='Date', freq=None)

print(data['Close'].values())
TypeError: 'numpy.ndarray' object is not callable

print(data['Close'].items())
<zip object at 0x000000000743ED88>


for price in data['Close']:
    print(price)

26989.99
25128.17
25605.54
25763.16
26289.98
26119.61

Finance APIを色々試してみる。

1. Alpha Vintage
2. Financial Modeling Prep API
3. yfinnance (Main使用)
一度は閉鎖されたYahoo FinanceのAPIを、なんとか使おうというPython ライブラリ



1. Alpha Vintage
・無料の場合、制限あり
・Index(DJIA等)やETFの値が取得できない



2. Financial Modeling Prep API 
https://financialmodelingprep.com/developer/docs/
・Market Movers Gainers, Loosers取得のエンドポイントあり。
・API 自体は使いやすい。
・CAPサイズ等でフィルターできないので、小規模な会社の株が表示されやすい。

[['Ascena Retail Group Inc.', 'ASNA', '$1.29', '(+119.76%)'],
 ['Array BioPharma Inc.', 'ARRY', '$46.57', '(+61.25%)'],
 ['Pensare Acquisition Corp. Warrant', 'WRLSW', '$0.18', '(+56.39%)'],
 ['Natuzzi S.p.A.', 'NTZ', '$1.77', '(+54.59%)'],
 ['Global Eagle Entertainment Inc.', 'ENT', '$3.23', '(+53.81%)'],
 ['Hamilton Beach Brands Holding Company Class A', 'HBB', '$14.58', '(+40.87%)'],
 ['CYREN Ltd.', 'CYRN', '$1.79', '(+34.59%)'],
 ['WISeKey International Holding AG', 'WKEY', '$9.50', '(+34.18%)'],
 ['Nebula Acquisition Corporation Warrant', 'NEBUW', '$2.45', '(+33.15%)'],
 ['Ocugen, Inc.', 'OCGN', '$0.38', '(+32.85%)']]

知らんがな、こんな会社、という会社が出てくる。
2. yfinnance
(特徴)
・無制限アクセス
・Index(DJIA等)やETFの値も取得できる


(参考)
https://aroussi.com/post/python-yahoo-finance
https://towardsdatascience.com/a-comprehensive-guide-to-downloading-stock-prices-in-python-2cd93ff821d4

(取得したデータへのアクセスはこちら)

Python Object -- Excelで管理する典型的表形式


(実際にやってみる)
pip install yfinance
でインストールしてね。



import yfinance as yf

msft =
yf.Ticker("MSFT")
print(msft)
"""
returns
<yfinance.Ticker object at 0x1a1715e898>
"""

# get stock info
msft.info //使えない pip install lxmlが必要


# get historical market data
msft.history(period="max")
"""
returns:
              Open    High    Low    Close      Volume  Dividends  Splits
Date
1986-03-13    0.06    0.07    0.06    0.07  1031788800        0.0     0.0
1986-03-14    0.07    0.07    0.07    0.07   308160000        0.0     0.0
...
2019-04-15  120.94  121.58  120.57  121.05    15792600        0.0     0.0
2019-04-16  121.64  121.65  120.10  120.77    14059700        0.0     0.0
"""

# show actions (dividends, splits)
msft.actions
"""
returns:
            Dividends  Splits
Date
1987-09-21       0.00     2.0
1990-04-16       0.00     2.0
...
2018-11-14       0.46     0.0
2019-02-20       0.46     0.0
"""

# show dividends
msft.dividends
"""
returns:
Date
2003-02-19    0.08
2003-10-15    0.16
...
2018-11-14    0.46
2019-02-20    0.46
"""

# show splits
msft.splits
"""
returns:
Date
1987-09-21    2.0
1990-04-16    2.0
...
1999-03-29    2.0
2003-02-18    2.0


msft = yf.Ticker("MSFT")
で取得できるものは、yfinance.Ticker object <MSFT>

print(dir(msft))で確認すると、
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_balancesheet', '_base_url', '_calendar', '_cashflow', '_download_options', '_earnings', '_expirations', '_financials', '_fundamentals', '_get_fundamentals', '_history', '_info', '_institutional_holders', '_isin', '_major_holders', '_options2df', '_recommendations', '_scrape_url', '_sustainability', 'actions', 'balance_sheet', 'balancesheet', 'calendar', 'cashflow', 'divi
dends', 'earnings', 'financials', 'get_actions', 'get_balance_sheet', get_balancesheet', 'get_calendar', 'get_cashflow', 'get_dividends', 'get_earnings', 'get_financials', 'get_info', 'get_institutional_holders', 'get_isin', 'get_major_holders', 'get_recommendations', 'get_splits', 'get_sustainability', 'history', 'info', 'institutional_holders', 'isin', 'major_holders', 'option_chain', 'options', 'quarterly_balance_sheet', 'quarterly_balancesheet', 'quarterly_cashflow', 'qu
arterly_earnings', 'quarterly_financials', 'recommendations', 'splits', 'sustainability', 'ticker']

print(dir(msft.info))
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '
__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']

print(Ticker.info)
{'zip': '98052', 'sector': 'Technology', 'fullTimeEmployees': 144000, 'longBusinessSummary': 'Microsoft Corporation deve
lops, licenses, and supports software, services, devices, and solutions worldwide. Its Productivity and Business Process
es segment offers Office, Exchange, SharePoint, Microsoft Teams, Office 365 Security and Compliance, and Skype for Busin
ess, as well as related Client Access Licenses (CAL); Skype, Outlook.com, and OneDrive; LinkedIn that includes Talent an
d marketing solutions, and subscriptions; and Dynamics 365, a set of cloud-based and on-premises business solutions for
small and medium businesses, large organizations, and divisions of enterprises. Its Intelligent Cloud segment licenses S
QL and Windows Servers, Visual Studio, System Center, and related CALs; GitHub that provides a collaboration platform an..... 続く


https://www.youtube.com/watch?v=UPmf-eijhXI&list=PLaYT64KWZAEOOf3FnrYZKrm0GW7--go_a&index=3
info = sorted([[k,v] for k,v in msft.info.items()])
for k,v in info:
    print(f'{k}:{v}')

52WeekChange:0.44700778
SandP52WeekChange:0.015086055
address1:One Microsoft Way
algorithm:None
annualHoldingsTurnover:None
annualReportExpenseRatio:None
ask:0
askSize:1800
averageDailyVolume10Day:37895183
averageVolume:39978820
averageVolume10days:37895183

.history()のオプションの使い方

◆periodで指定
data=DJIA.history(
    period="1d",
   interval='5m'
    )
print(data)
                             Open    High     Low   Close  Volume  Dividends  Stock Splits
Datetime
2020-06-18 09:30:00-04:00  284.97  285.45  284.69  285.19  290160          0             0
2020-06-18 09:35:00-04:00  285.08  285.75  284.55  285.56  117414          0             0
2020-06-18 09:40:00-04:00  285.54  285.92  285.38  285.91   76632          0             0



data=DJIA.history(
    start="2020-06-11",
    end='2020-06-19' #ここで指定した日は含まない。
    ) #intervalも指定できる

Date
2020-06-10  27251.89  27355.22  26938.05  26989.99  6570840000          0
2020-06-11  26282.51  26294.08  25082.72  25128.17  7018890000          0
2020-06-12  25659.42  25965.55  25078.41  25605.54  5832250000          0
2020-06-15  25270.39  25891.58  24843.18  25763.16  5740660000          0
2020-06-16  26326.68  26611.03  25811.70  26289.98  5829240000          0
2020-06-17  26330.52  26400.07  26068.41  26119.61  4549390000          0
2020-06-18  26016.45  26154.20  25848.53  26080.10  4429030000          0


====簡単なグラフ
y_axis =[]
for y in data['Close']:
    y_axis.append(y)

x_axis =[]
fmt='%m/%d- %H:%M'
for x in data['Close'].keys():
    date = datetime.datetime.strftime(x,'%m/%d- %H:%M')
    x_axis.append(date)

fig = plt.figure(figsize=(7, 4))
ax = fig.add_subplot(1, 1, 1, fc='#191970')


plt.style.use=('seaborn-dark')
plt.plot(x_axis, y_axis, color='#98fb98')

#間隔の日数を指定
ticks = 12
plt.xticks(range(0, len(x_axis), ticks), x_axis[::ticks])


# 次の2行は軸ラベルを回転させるために使用
labels = ax.get_xticklabels()
plt.setp(labels, rotation=45, fontsize=5)

plt.tick_params( labelsize=7)
plt.title(ticker_name)
plt.xlabel('Date')
plt.ylabel('USD')
plt.grid(True)

plt.show()
plt.savefig('price.png')

◇.infoについて


◇msft.actions
            Dividends  Stock Splits
Date
2018-09-24      0.330           0.0
2018-12-24      0.421           0.0
2019-03-18      0.324           0.0
2019-06-24      0.416           0.0
2019-09-23      0.384           0.0
2019-12-23      0.458           0.0
2020-03-23      0.363           0.0
2020-06-22      0.424           0.0