Pythonista3を使って、GUIで値を入力し、計算結果とグラフを表示するアプリを作ってみました。
全体構成
構成は下記2つのブロックで構成されています
- ボタンタップ時の動作定義
- GUIの各部品作成~配置
コード説明
ボタンタップ時の動作定義部
def fx_margin_calc(sender):
mmr = float(mmr_i.text)/100
lot_u = float(lot_u_i.text)
ボタンタップ時の動作をdefで定義します。引数は、必ずsenderとします。これにより、Acationの指定元であるオブジェクトが渡されます。2行目以降、GUIから入力されたデータを参照し各変数に格納していきます。GUIから入力されるデータは文字列(String)であるため、floatを使い小数に型変換しておきます。
margin -= spread
margin = int(margin)
c_l2.text = str(margin)
GUIから読みだしたデータから計算した結果をGUIに返します。
表示する先のデータは文字列である必要があるため、今度はstrで文字列に変換して「c_l2.text」に格納しています。
plt.clf()
~省略~
plt.legend()
with io.BytesIO() as buf:
plt.savefig(buf)
png = ui.Image.from_data(buf.getvalue())
img_i.image = png
グラフはmatplotlibを使って作ります。作ったグラフは、ui.Image型に変換しないとui.view上で表示させることができないため、ByteIOを使うことで、bufに一旦取り出し、ui.Image.from_dataを使って、ui.Image型に変化しています。
GUIの各部品作成~配置
# UIの作成
v = ui.View()
v.background_color = '#e2e2e2'
# 計算条件入力
mmr_l = ui.Label(frame=(10, 10, 200, 30), alignment=2, text='証拠金維持率[%]')
泥臭い書き方ですが、部品を一つずつ作って、frameで配置座標を指定しながら作っていっています。
描いている内容は繰り返しなので、これ以降は省略します。
LabelとTextFildeの繰り返しで入力部分を作っているので、1つのデータ入力分をクラス化してみるともっとスマートに書けたかもしれません。この辺の書き方はまた調べて紹介したいと思います。
まとめ
GUIで値を入力し、計算結果とグラフを表示するアプリを作ってみました。頻繁に計算するような場合楽になると思いますので、是非試してみてください。
※FXは素人です、コード中の算出式は保証できません。アプリの作り方として参照ください。
コード例
import io
import matplotlib.pyplot as plt
import numpy as np
import ui
def fx_margin_calc(sender):
mmr = float(mmr_i.text)/100
lot_u = float(lot_u_i.text)
pips = float(pips_i.text)
spread = float(spread_i.text)
leverage = float(leverage_i.text)
balance = float(balance_i.text)
lot = float(lot_i.text)
bid = float(bid_i.text)
margin = balance/lot/lot_u/pips
margin -= bid/leverage*mmr/pips
margin -= spread
margin = int(margin)
c_l2.text = str(margin)
x = np.arange(bid*0.99, bid*1.01, bid*0.0002)
a = x+balance/lot/lot_u-x/leverage*mmr
a -= spread*pips
b = x-balance/lot/lot_u+x/leverage*mmr
b += spread*pips
plt.clf()
plt.plot(x, b, color='red', label='bid')
plt.plot(x, a, color='blue', label='ask')
plt.title('margin')
plt.xlabel('position value')
plt.ylabel('margin')
plt.grid()
plt.legend()
with io.BytesIO() as buf:
plt.savefig(buf)
png = ui.Image.from_data(buf.getvalue())
img_i.image = png
# UIの作成
v = ui.View()
v.background_color = '#e2e2e2'
# 計算条件入力
mmr_l = ui.Label(frame=(10, 10, 200, 30), alignment=2, text='証拠金維持率[%]')
lot_u_l = ui.Label(frame=(10, 40, 200, 30), alignment=2, text='1Lot当たりの通貨量')
pips_l = ui.Label(frame=(10, 70, 200, 30), alignment=2, text='1pips')
spread_l = ui.Label(frame=(10, 100, 200, 30), alignment=2, text='スプレッド')
leverage_l = ui.Label(frame=(10, 130, 200, 30), alignment=2, text='レバレッジ')
balance_l = ui.Label(frame=(10, 160, 200, 30), alignment=2, text='残高')
lot_l = ui.Label(frame=(10, 190, 200, 30), alignment=2, text='ポジション保有Lot')
bid_l = ui.Label(frame=(10, 220, 200, 30), alignment=2, text='ポジション保有時のbid')
mmr_i = ui.TextField(frame=(220, 10, 100, 30), placeholder='100')
lot_u_i = ui.TextField(frame=(220, 40, 100, 30), placeholder='100000')
pips_i = ui.TextField(frame=(220, 70, 100, 30), placeholder='0.01')
spread_i = ui.TextField(frame=(220, 100, 100, 30), placeholder='1.2')
leverage_i = ui.TextField(frame=(220, 130, 100, 30), placeholder='1000')
balance_i = ui.TextField(frame=(220, 160, 100, 30), placeholder='10000')
lot_i = ui.TextField(frame=(220, 190, 100, 30), placeholder='0.01')
bid_i = ui.TextField(frame=(220, 220, 100, 30), placeholder='150')
mmr_i.text='100'
lot_u_i.text='100000'
pips_i.text='0.01'
spread_i.text='1.2'
leverage_i.text='1000'
balance_i.text='10000'
lot_i.text='0.01'
bid_i.text='150'
mmr_i.keyboard_type = ui.KEYBOARD_NUMBERS
lot_u_i.keyboard_type = ui.KEYBOARD_NUMBERS
pips_i.keyboard_type = ui.KEYBOARD_NUMBERS
spread_i.keyboard_type = ui.KEYBOARD_NUMBERS
leverage_i.keyboard_type = ui.KEYBOARD_NUMBERS
balance_i.keyboard_type = ui.KEYBOARD_NUMBERS
lot_i.keyboard_type = ui.KEYBOARD_NUMBERS
bid_i.keyboard_type = ui.KEYBOARD_NUMBERS
# 計算結果表示
c_l1 = ui.Label(frame=(10, 280, 200, 30), alignment=2, text='許容変動[pips]')
c_l2 = ui.Label(frame=(220, 280, 100, 30))
c_b = ui.Button(frame=(330, 280, 40, 30), title='計算')
c_b.action = fx_margin_calc
img_i = ui.ImageView(frame=(10, 320, 350, 300))
v.add_subview(mmr_l)
v.add_subview(lot_u_l)
v.add_subview(pips_l)
v.add_subview(spread_l)
v.add_subview(leverage_l)
v.add_subview(balance_l)
v.add_subview(lot_l)
v.add_subview(bid_l)
v.add_subview(mmr_i)
v.add_subview(lot_u_i)
v.add_subview(pips_i)
v.add_subview(spread_i)
v.add_subview(leverage_i)
v.add_subview(balance_i)
v.add_subview(lot_i)
v.add_subview(bid_i)
v.add_subview(c_l1)
v.add_subview(c_l2)
v.add_subview(c_b)
v.add_subview(img_i)
# アプリを表示
v.present(style='sheet')