simple backtest
Numpy Simple Backtest
Numpyを使ったバックテスト
Numpy OHLCデータの読み込みとグラフ描画
(MT4 保存 15分足)
# numpy等のインポート -------------------------------------------------------- import numpy as np import time import datetime # matplotlibのインポートと設定 --------------------------------------------- import matplotlib.pyplot as plt from pylab import rcParams # matplotlibの設定 rcParams['figure.figsize'] = 14,5 # 図のサイズ設定 plt.style.use('ggplot') # 色スタイル設定 # csvデータの読み込み ------------------------------------------------------ """ [['2018.07.20' '21:30' '111.477' '111.518' '111.462' '111.467' '827'] ['2018.07.20' '21:45' '111.467' '111.479' '111.381' '111.444' '470'] ['2018.07.22' '22:00' '111.364' '111.432' '111.363' '111.419' '107']] """ data = np.loadtxt("USDJPY15.csv",delimiter=",", dtype='str') # 文字列として読み込み # 文字列データの日付datetimeへの変換と、float数値への変換 data = [[ datetime.datetime.fromisoformat("-".join((i[0]+" "+i[1]).split("."))) , float(i[2]), float(i[3]), float(i[4]), float(i[5]), float(i[6])] for i in data] #data = [i for i in data if i[0] > datetime.datetime.fromisoformat('2019-01-01 00:00') ] # Close価格のグラフ化 ------------------------------------------------------ x = [i[0] for i in data] y = [i[4] for i in data] plt.plot(x, y) #plt.savefig("figure1.png") plt.show()
Numpy シンプルバックテスト
# バックテスト ------------------------------------------------------------- lot = 1 # 売買ロット position = 0 # 保有ポジション amount_start = 0 # 初期証拠金 amount = amount_start # 証拠金残高 profit_y = [] # 資産推移 close = np.array([]) # 終値 count = 0 #売買カウント for tick in data: now = tick[0] ltp = tick[4] # last traded price profit_y.append( amount + (position*ltp*lot) ) # 資産推移 close = np.append(close,ltp) close = close[-1000:] if len(close) < 1000: pass smaA = np.mean(close[-1000:]) smaB = np.mean(close[-400:]) if smaA > smaB and position < 1: "BUY" if position < 0: # 保有ポジション決済 amount = amount - ltp*lot position += 1 amount = amount - ltp*lot # 買注文 position += 1 # ポジション保有数 count += 1 elif smaA < smaB and position > -1: "SELL" if position > 0: # 保有ポジション決済 amount = amount + ltp*lot position -= 1 amount = amount + ltp*lot # 売注文 position -= 1 # ポジション保有数 count += 1 amount_all = amount + (position*ltp*lot) # 取引後資産 profit = amount_all - count * lot * 0.012 # スプレッド分差し引き print("取引回数(簡易):", count) print("開始時資産 :",amount_start) print("獲得値幅 :",round(amount_all,5)) print("利益 :",round(profit,5))
取引回数(簡易): 87
開始時資産 : 0
獲得値幅 : 17.799
利益 : 16.755
x = [i[0] for i in data] y = [i[4] for i in data] import matplotlib.pyplot as plt plt.style.use("ggplot") fig = plt.figure(figsize=(13,8)) # Close価格のグラフ化 ------------------------------------------------------ ax1 = fig.add_subplot(211) ax1.set_ylabel("close") ax1.plot(x, y) # 資産変動のグラフ化 ------------------------------------------------------- ax2 = fig.add_subplot(212) ax2.set_ylabel("amount") ax2.plot(x, profit_y) #plt.savefig("figure2.png") plt.show()
Pandas Simple Backtest
Pandasを使ったバックテスト
Pandas OHLCデータの読み込みとグラフ描画
(MT4 保存 15分足)
import pandas as pd import datetime """ # USDJPY15.csv 2018.07.20,21:30,111.477,111.518,111.462,111.467,827 2018.07.20,21:45,111.467,111.479,111.381,111.444,470 2018.07.22,22:00,111.364,111.432,111.363,111.419,107 """ df_ohlc = pd.read_csv("USDJPY15.csv", header=None) df_ohlc[0] = df_ohlc[0] +" "+ df_ohlc[1] df_ohlc[0] = pd.to_datetime(df_ohlc[0]) df_ohlc.columns = ["date","time","open","high","low","close","volume"] df_ohlc.index = df_ohlc["date"] del df_ohlc["time"] del df_ohlc["date"] df_ohlc[["close"]].plot() df_ohlc.head(5)
Pandas シンプルバックテスト
Pandasを使ったバックテスト
df = df_ohlc.copy() df = df[datetime.datetime(2018,1,1):] df["smaA"] = df["close"].rolling(window=400,min_periods=1).mean() df["smaB"] = df["close"].rolling(window=1000,min_periods=1).mean() df["signal"] = 0 df.loc[ df["smaA"] < df["smaB"] ,"signal"] = 1 df.loc[ df["smaA"] > df["smaB"] ,"signal"] = -1 count = df['signal'].diff().value_counts() df['returns'] = df['close']-df['close'].shift(1) df['strategy'] = df['returns'] * df['signal'].shift(1) df['strategy'].cumsum().plot() print("取引回数(簡易):",count.sum() - count[0]) v = df['strategy'].cumsum()[-1] print("獲得値幅:",round(v,5)) profit = v - (count.sum() - count[0]) * 0.012 print("手数料差し引き後利益:",round(profit,5))
コードライセンスは CC0 もしくは Unlicense
Creative Commons — CC0 1.0 Universal
Unlicense.org » Unlicense Yourself: Set Your Code Free
Searching code
日本語
Python 3.6.5 ドキュメント
https://docs.python.jp/3/
Qiita
https://qiita.com/
エンジニアリングに関する知識を記録・共有するためのサービス
teratail
https://teratail.com/
エンジニア特化型Q&Aサイト
人力検索はてな
http://q.hatena.ne.jp
note 検索 : Python
https://note.mu/search?context=note&q=Python
英語
Python 3.6.5 documentation
https://docs.python.org/3/
Nullege
http://nullege.com/
Nullege is a search engine for Python source code.
searchcode
https://searchcode.com/
stack overflow
https://stackoverflow.com/
github
https://github.com/explore
PyData
https://pydata.org
Google 複数サイト検索
Python site:hatenablog.com OR site:teratail.com OR site:qiita.com OR site:d.hatena.ne.jp
OR site:q.hatena.ne.jp OR site:docs.python.jp OR site:pythondatascience.plavox.info
情報
GitHubのコード検索 : プログラマにとっての宝の山
https://postd.cc/github-code-advances-search-programmers-goldmine/
Python 3 環境構築 「Getting Started」
Python 3 環境構築 「Getting Started」
Python 3.6.5 を実行するための基本的な動作環境構築。
インストールから文字の表示「Hello World!」実行まで。
プログラミング言語 Python
Pythonは多様な分野で使われている、パワフルな動的プログラミング言語です。
比較的学習しやすい言語です。
Python 3 学習情報
Python>>> About>>> Getting Started
https://www.python.org/about/gettingstarted/
The Python Tutorial 3.6.5
https://docs.python.org/3.6/tutorial/index.html#the-python-tutorial
Python チュートリアル 3.6.5
https://docs.python.jp/3/tutorial/index.html
Python 3.6.5 documentation
https://docs.python.org/3/index.html
Python 3.6.5 ドキュメント
https://docs.python.jp/3/index.html
Dive Into Python 3
http://www.diveintopython3.net/
Dive Into Python 3 日本語版
http://diveintopython3-ja.rdy.jp/
(書籍)詳細!Python3入門ノート
https://honto.jp/netstore/pd-book_28495507.html
(学習サイト)【世界で5万人が受講】実践 Python データサイエンス | Udemy
https://www.udemy.com/python-jp/learn/v4/
(学習サイト)Python入門 | 10秒で始めるAIプログラミング学習サービスAidemy[アイデミー]
https://aidemy.net/courses/3010
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Pythonのバージョン
Python 2 と Python 3 があり、Python 3 から始まるのが新しいバージョン。
Python 3 への移行が推奨されており、新しく学ぶのであれば 2 より 3 が良いです。
インストール(Windows 10)
Windowsの場合はインストール用実行ファイルをダウンロードし実行する。
数字が新しい、最新のバージョンをインストールする。
Python.org
https://www.python.org/
Python 3.6.5 (Windows x86-64 executable installer)
インストール用実行ファイルには、Python 3 の他に、標準のライブラリや統合開発環境(IDE)などのソフトウェアも含まれています。
PATH システム環境変数(Windows)
コマンドラインでPythonを実行できるようにPATH(システム環境変数)を設定する。
インストール時に、自動的にPATHが設定されるように指定することもできる。「Add Python to PATH」
インストール(Ubuntu 17)
sudo apt-get install python3
python -m pip install --upgrade pip
起動
コンソール(コマンドライン)で python
もしくは python3
とコマンド入力し起動。
Python のコマンドの後に .py ファイルを指定することで、.py ファイルに保存したコードが実行できる。
文字の表示
画面に文字を出力する。例文「Hello World!」
print("Hello World!")
Python 3 簡易基本チートシート(下書き)
Python 3 簡易基本チートシート(下書き)
Python 3.6.5
Python 3 学習情報
Python>>> About>>> Getting Started
https://www.python.org/about/gettingstarted/
The Python Tutorial 3.6.5
https://docs.python.org/3.6/tutorial/index.html#the-python-tutorial
Python チュートリアル 3.6.5
https://docs.python.jp/3/tutorial/index.html
Python 3.6.5 documentation
https://docs.python.org/3/index.html
Python 3.6.5 ドキュメント
https://docs.python.jp/3/index.html
Dive Into Python 3
http://www.diveintopython3.net/
Dive Into Python 3 日本語版
http://diveintopython3-ja.rdy.jp/
(書籍)詳細!Python3入門ノート
https://honto.jp/netstore/pd-book_28495507.html
(学習サイト)【世界で5万人が受講】実践 Python データサイエンス | Udemy
https://www.udemy.com/python-jp/learn/v4/
(学習サイト)Python入門 | 10秒で始めるAIプログラミング学習サービスAidemy[アイデミー]
https://aidemy.net/courses/3010
基本
ステートメント(命令文)の区切りは 改行 もしくは ; (セミコロン) インデントは4文字スペースが標準。
プリント(画面に出力等)
print(値1,値2, sep="区切り文字", end="行末文字")
エスケープシーケンス
\n
改行 \t
タブ \"
ダブルクオート \\
バックスラッシュ
例:print("文書\n文書")
計算
print("1 + 2",end=" = ") print(1 + 2) a = ((3+2)/2+10) * 10 # = 125 print("a =","((3+2)/2+10) * 10 =",a) #小数点の丸め print("round(a/c*100) % =",round(a/c*100),"%") #切り上げ切り下げはmathモジュール
数値演算子
+ - * /
//
(小数点以下切り捨て)
%
(割ったあまり)
**
(累乗)
文字列演算子
+
連結 *n
n回の繰り返し
代入演算子
a += 1
(a = a + 1)
+=
足す -=
引く
*=
/=
//=
%=
**=
文字の操作
text = "Shimbun Yomiuri" #文字列[位置] #Shimbun Yomiuri #前から 0,1,2,,, print(text[8],end="") #Y #後ろから -1,-2,-3,,, print(text[-6],end="") #o #スライス print(text[10:15]) #miuri print(text[8:8+7],end=" ") #Yomiuri #最初からある文字まで print(text[:7]) #Shimbun #ステップで抜き出す print(text[6:10:3]) #no print(text[::5]) #Sum
演算子
比較
==
!=
>
>=
<
<=
論理
and
or
not
ビット演算子
&
|
^
-
シフト
<<
>>
型
type()
整数 int 浮動小数点 float 文字列 str
str()
数値から文字列への変換
int()
整数への変換
float()
浮動小数点への変換
isinstance(オブジェクト,クラス)
インスタンスの確認(一致でTrueを返す)
変数
Pythonは定数なし(大文字の変数で表現)
文字は、大文字、小文字のアルファベット、数字、アンダーバー_
が使用できる。
予約語は使用できない 先頭に数字は使用できない
関数
関数(引数,引数2)
組み込み関数
数値 : print()
出力 abs()
絶対値 max(数値1,数値2,,,,)
最大 min(数値1,数値2,,,,)
最小 round(数値,桁)
数字の丸め 等
文字列 : chr(整数)
ord(文字)
Unicode変換 len(文字列)
文字数(2バイト文字も1文字換算) 等
出入力 : print()
input(説明)
ユーザー入力 open()
ファイル 等
モジュール
import モジュール名,モジュール名2,,,
import モジュール名 as 名(として用いる)
from モジュール名 import 関数名
(as 名(として)
) 関数のみ
(関数として読み込んだ場合、使うためにモジュール名の指定は必要ない)
モジュール名.関数()
モジュールの関数を使用
import math math.floor(15.4) #切り捨て math.sin(1) #.sin() , .cos(1) , .tan(1) math.pi #定数 math.degrees(math.pi) #radianからdegreesへの変換
文字列のメゾット
s = "Pythonオブジェクト" print(s) #Pythonオブジェクト print(type(s)) #<class 'str'> print(s.upper()) #PYTHONオブジェクト print(s.lower()) #pythonオブジェクト print(s.swapcase()) #pYTHONオブジェクト print(s.count("n")) #1 print(s.find("n")) #5 無ければ-1 print(s.replace(検索文字列,置換文字列,回数)) #検索文字列の置換
format()
#Python 3.5 s = "{0} {2} Python {1} Bot" print(s.format(10,"Market","New")) s = "{t} Python {n} Bot" print(s.format(t = "New",n = "Market"))
#Python 3.6 t = "New" n = "Market" s = f"{t} Python {name} Bot" #最初にfもしくはF print(s)
条件分岐(if)
True
1, Falseとみなされないなんらかの値
False
0, None, 0.0, 空の値
if 条件: 処理1 else: #Falseの場合 処理2
if 条件: 処理1 else: #Falseの場合 処理2
if 条件1: 処理1 elif 条件2:#条件1がFalseの場合のみ 処理2 else: #両方Falseの場合 処理3
test = a if a>b else b
特殊な書き方(Trueならa、Falseならb)
繰り返し(while)
条件がTrueの間、処理を繰り返す
while 条件: 処理 #条件判定(while)を再度行う else 処理2(whileがFalseの場合)
break
繰り返しを止める else処理は行われない
continue
中断しwhile判定を再度行う
繰り返し(for)
for 変数 in データ群 :
range(開始,終了,ステップ)
#n回の繰り返し #iにrange(n)を順番に入れる for i in range(n): 処理1 else 処理2
#3×3の位置 for x in range(3): print() for y in range(3): print(f"({x},{y})",end="")
(Pythonではカウンタは使わない)
例外処理(try)
try : 処理 except : エラー時の処理 finally : 最後に実行する処理(exceptの場合でも実行)
try : except 例外 : else :
try : test = "a" int(test) except ValueError : print("ValueError") except ZeroDivisionError : print("ZeroDivisionError") except Exception as exception: print(exception) except BaseException as base_exception: print(base_exception) else : print("done")
リスト
(Pythonにはリストの他、似たものとして、ダブル、辞書、配列(NumPy)がある)
list[要素,要素,要素]
list[値1,値2,値3]
a = 1 b = 2 c = 3 list = [a,b,c] print(list) #[1,2,3]
[1, 2, 3]
変数の値がリストに入る。
zeros = [0]*5 text = ["text",".txt"]*2
[0, 0, 0, 0, 0]
['text', '.txt', 'text', '.txt']
list()
a = list(range(-5, 6, 2))
[-5, -3, -1, 1, 3, 5] #ステップで奇数のみのリスト
a = list("word")
['w', 'o', 'r', 'd']
a[0]
インデックス番号
a[1] = "check"
listはimmutableではなくmutableなので変更できる
a[0] = ["b","c"]
多重(多次元)リスト
IndexError
存在しないインデックス番号
.append(値)
リストの最後に要素を追加
.insert(位置,値)
リストの指定位置に要素を挿入
.pop(値)
リストの最初か最後を抜き取る(0,-1)
.remove(位置)
リストの指定位置を抜き取る (delによる定義の削除も可能)
a = ["A","B","C"] if "B" in a: a.remove("B") print(a)
['A', 'C']
.split(セパレータ)
文字列を区切りでリスト化する
セパレータ.join(リスト)
リストをセパレータで文字列化する
リストの連結、分割、複製、比較
リストA + リストB
連結
リスト += ["要素"]
最後に連結
リストA.extend(リストB)
連結
リスト[開始:終了(:ステップ)]
分割(スライス)
リストA = リストB
同じオブジェクトのリスト is
確認
リスト.copy()
複製 リスト[:]
複製 list(リスト)
複製
リストの並び替え
リスト.sort()
並び替え 小から大 AからZ 大文字から小文字
リスト.sort(reverse = True)
並び替え(降順) 大から小
sorted(リスト)
並び替え 元のリストを書き換えない
sorted(リスト,reverse = True)
並び替え(降順) 書き換えない
リスト.reverse()
逆順
リスト.sort(key = len)
比較関数 文字列の長さで並び替え
sorted(リスト, key = str.lower)
比較関数 大文字小文字の区別をしない
random.shuffle(リスト)
randomモジュール ランダムに並び替え 書き換えない
リストの取り出し
当てはまる要素を順に取り出す
for 単語 in リスト : print(単語)
enumerate() カウントする
for i, 単語 in enumerate(リスト, 1) print(f"{i} {単語}")
zip()
リストの同時操作
リスト内包表記
[変数Aの処理 for 変数A in リスト]
a = [1, 2, 3, 4] c = [b*5 for b in a] print(c)
[変数Aの処理 for 変数A in リスト if 条件]
a = [1, 2, 3, 4] c = [b for b in a if 1 < b < 4] print(c)
リストの要素を検索
要素 in リスト
一致 TrueもしくはFalse
リスト.index(要素)
一致する要素の位置
リスト.count(要素)
一致する要素の数
sum(リスト)
合計 max(リスト)
最大 min(リスト)
最小
#一部文字列(一部の単語等)の検索 a = ["ok","test"] b = "te" for i in a: if b in i: result = True break print(result)
リストの要素のランダムな取り出し
import random a = ["ok","test"] result = random.choice(a) print(result)
ランダムな10個の数値リスト
from random import randint numbers = [] while len(numbers)<10 : n = randint(0,100) if n in numbers: continue numbers.append(n) print(numbers)
タプル
タプルはimmutable(作成後にその状態を変えることのできないオブジェクト)
a = 1, b = (0,1,2) (c, d) = (1, 2) c, d = 1, 2
tuple()
タプルへの変換
セット(集合)
set()
セットへの変換 重複する要素は除外される 要素に順番はない
a = set()
空集合
.add()
.remove()
.discard()
.clear()
.pop()
frozenset()
.union()
.intersection()
.difference()
.symmetric_difference()
&
-
^
==
!=
|=
&=
-=
.update()
.intersection_update()
.difference_update()
.symmetric_difference_update()
.isdisjoint()
.issubset()
<=
.issuperset()
>=
辞書
{名前:値,名前:値}
要素はイミュータブル
dict()
a = dict(news=1,mail=2,search=3)
辞書A.update(辞書B)
del 辞書[名前]
.copy()
.get()
in
関数
引数無し、戻り値有り
def 関数名() 処理 return 戻り値
引数有り、戻り値有り
def 関数名(引数)00 引数を使用した処理 return 戻り値
pass
処理が未定の場合に用いる return None
処理を途中で抜ける
def triangle(base, height): area = base * height / 2 return area a = triangle(15,13) print(a)
関数内で定義された変数はローカル変数であり、全体で利用されるグローバル変数とは異なる。関数内でもグローバル変数は利用することができる。
位置引数とキーワード引数がある。引数には初期値が設定できる。
*引数名
*を頭につけ引数をタプルで指定 (*args
**kwargs
)
sys.argv
コマンドラインからの引数
def calc(a,*arg): #処理 return arg print(calc("a","b","c"))
関数オブジェクト
def do(func): func() def a(): print("Hi!") b = print b("Hello World!") do(a)
クロージャ(関数閉包)(関数内関数)
def closure_1(a): def closure_2(b): return a * b return closure_2 c = closure_1(10) print(c(2))
無名関数 (lambda式)
#def a(x,y): # return x + y #print(a(2,5)) b = lambda x, y : x + y print(b(2,5))
a = (lambda x,y : x + y)(2,5)
ソート関数
def sort(a): list = ["A","C","B"] b = list.index(a) return b list = ["A","A","B","B","C"] list.sort(key = sort) print(list)
map()
map(関数,イテラブル)
fillter()
fillter(関数,イテラブル)
イテレータ(iterator)
list = ["A","C","B"] a_iter = iter(list) print(next(a_iter)) print(next(a_iter))
ジェネレータ(generator)
def generator_a(): yield "A" yield "B" yield "C" abc = generator_a() print(next(abc)) print(next(abc))
クラス定義
クラス名の一文字目は大文字にするのが慣例
第1引数にはselfが慣例
class Aa: def __init__(self,color = "赤"): self.color = color self.score = 0 def add(self,score): self.score += score msg = f"{self.color} : {score}点加算、合計点数は {self.score}点" print(msg) player1 = Aa("赤") player2 = Aa("青") print(f"プレイヤー1 : {player1.color}") print(f"プレイヤー2 : {player2.color}") player1.add(15) player2.add(5) player1.add(10) player2.add(5) print(f"プレイヤー1 : {player1.score}点") print(f"プレイヤー2 : {player2.score}点")
クラスメゾット
class Aa: group = "A" num = 0 @classmethod def count(cls): cls.num += 1 print(f"追加{cls.num}") def __init__(self,color = "白"): Aa.count() self.serial = Aa.num self.color = color self.score = 0 def add(self,score): self.score += score msg = f"{self.color} : {score}点加算、合計点数は {self.score}点" print(msg) player1 = Aa("赤") player2 = Aa("青") player3 = Aa("黄") print(f"プレイヤー1 color:{player1.color} serial:{player1.serial} group:{player1.group}") print(f"プレイヤー2 color:{player2.color} serial:{player2.serial} group:{player2.group}") print(f"プレイヤー3 color:{player3.color} serial:{player3.serial} group:{player3.group}") player1.add(15) player2.add(5) print(f"プレイヤー1 : {player1.score}点") print(f"プレイヤー2 : {player2.score}点")
クラスの継承
class Aa: a = "A" class Bb(Aa): b = "B" c = Bb() print(c.a)
オーバーライド
#サブクラス def 上書きする関数名(self,引数)
super()
プロパティ
__変数名
非公開のインスタンス変数
@property
ゲッター関数
@プロパティ.setter
セッター関数
ファイル操作
モジュールの再読み込み
import importlib importlib.reload(モジュール名)
Python 3 Scripts
Python 3 Scripts
コンソール文字出力の上書き
Python3のコンソールへの文字の標準出力は、その行であれば上書きして書き換えることができる。 画面全体、複数行にわたる書き換えの場合には別のライブラリ等を利用した方法になる。
Carriage Return(CR)を使用してキャレットを行末から行頭(左端)に戻す。
index
サンプルコード
import sys, time for num, i in enumerate(range(10)): sys.stdout.write("\r%d" % num) sys.stdout.flush() time.sleep(0.05) #!/usr/bin/env python #-*- coding:utf-8 -*- print("END") #B import sys import time for i in range(10): sys.stdout.write("\r%d" % i) sys.stdout.flush() time.sleep(0.1) print("END") # from time import sleep for i in range(10): print('\r', i, end='') sleep(0.1) print("END") # import math import sys import time END = 170 MAX_LEN = 30 def get_progressbar_str(progress): BAR_LEN = int(MAX_LEN * progress) return ('[' + '=' * BAR_LEN + ('>' if BAR_LEN < MAX_LEN else '') + ' ' * (MAX_LEN - BAR_LEN) + '] %.1f%%' % (progress * 100.)) for i in range(END + 1): time.sleep(0.01) progress = 1.0 * i / END sys.stderr.write('\r\033[K' + get_progressbar_str(progress)) sys.stderr.flush() sys.stderr.write('\n') sys.stderr.flush() print("END") # for i in range(10): sys.stdout.write("*") sys.stdout.flush() time.sleep(0.1) print() print("END") # import sys import time for i in range(10): sys.stdout.write("\r{}".format(i)) sys.stdout.flush() time.sleep(0.1) print() print("END") # import sys, time for i in range(10): sys.stdout.write("\r%d" % i) sys.stdout.flush() time.sleep(0.1) print("END") # def override_print(message, line_length = 100): if len(message) > line_length: message = message[:line_length - 3] + "..." sys.stdout.write((u"\r{0:<" + str(line_length) + "}").format(message)) sys.stdout.flush()
プロセスバー表現
import time import sys sys.stdout.write('['+' '*10+']') # moved *11 on account of ] sys.stdout.write('\b'*11) sys.stdout.flush() for i in range(10): time.sleep(1) sys.stdout.write('.') sys.stdout.flush() sys.stdout.write('] Done!\n') print("END") import time import sys sys.stdout.write('['+' '*10+']') sys.stdout.write('\b'*10) sys.stdout.flush() for i in range(10): time.sleep(1) sys.stdout.write('\b' + '=') if(i < 9): sys.stdout.write('>') sys.stdout.flush() sys.stdout.write('] Done!\n') print("END") import time import sys sys.stdout.write('['+' '*10+'] 0%') sys.stdout.flush() for i in range(10): time.sleep(1) sys.stdout.write('\b'*(15-i) + '=') if(i < 9): sys.stdout.write('>') sys.stdout.write(' '*(8-i) + '] ' + str(i+1) + '0%') sys.stdout.flush() # overwrite the percentage sign and write Done instead sys.stdout.write('\b\b\b\bDone!\n') print("END") import time for x in range (0,5): b = "Loading" + "." * x print (b, end="\r") time.sleep(1)
MetaTrader
MetaTrader
MetaTrader とは
MetaTraderはロシアのMetaQuotes Software社が開発したFX向け取引ソフトウェアです。
MetaTrader 4(MT4、メタトレーダー4)、MetaTrader 5【現行バージョン】(MT5、メタトレーダー5)
注文、チャート分析、独自のスクリプトやインジケーターの作成、EAを利用した自動売買ができます。
多くのネット証券会社で利用することができ、FX以外の商品の売買にも使われています。
利点・欠点のあるソフトウェアですが、同じスクリプト(インジケーター、テクニカル、情報表示、自動売買等)をMTを導入している多くの会社で使うことができ、ウェブ上のMetaTraderに関する情報も多いです。
forexfactory(質の高いFXレードフォーラム(英語))などのサイトでスクリプトをダウンロードし、簡単に導入できます。
自動売買(自動取引、EA(Expert Advisor))について記載します。
インストール
MetaTraderを導入しているFX会社からダウンロード。もしくは公式サイトからダウンロードする場合、MetaQuotes Software社のサイトで入手できます。
MT4とMT5では、UI、可能な機能、コードの記述方法等が異なり、MT5が新しいバージョンです。
https://www.metaquotes.net/
基本操作
基本操作に関してはFX会社、証券会社の説明がわかりやすいです。
MT4 Meta Trader 4 メタトレーダー4 | OANDA Japan株式会社
https://www.oanda.jp/service/mt4/
MT4の使い方 記事一覧 | OANDA FX Lab-education(オアンダ ラボ)
https://www.oanda.jp/lab-education/blog_mt4/
楽天MT4口座 | 楽天証券
https://www.rakuten-sec.co.jp/web/fx/mt4/
MetaTrader 4 取扱説明書 (楽天証券)
https://www.rakuten-sec.co.jp/web/fx/pdf/mt4_guide.pdf
MT4(メタトレーダー4)|FX・外国為替取引のFOREX.com
https://www.forex.com/jp/services/metatrader/
(FX・外国為替取引のFOREX.com) 3つのスペシャルEAプレゼント!
https://www.forex.com/jp/why-forexcom/campaigns/ea-indicator-gift/
(FXTF) MT4 EA(自動売買)とは|FXTF
https://www.fxtrade.co.jp/mt4/ea
(FX雑誌のウェブサイト) ザイFX!×メタトレーダー(MT4)
http://zai.diamond.jp/mt4
MQL4
MQL4参考サイト
FX 自動売買・初心者でもできるシステムトレード入門 : FX自動売買システムの自作
http://www.systemtrade1.com/main/mt4/jisaku/ea_jisaku.html
MT4向けEAのプログラミングを学ぶ | OANDA FX Lab-education(オアンダ ラボ)
https://www.oanda.jp/lab-education/fx_on/
MT4 FX自動売買入門 | お気楽FX 相場生活入門編
http://han-rei.com/sistre/
MQL Wizard
[MetaEditor] File > New > MQL Wizard > Custom Indicator
Name : Indicators\MA_TEST
Parameters : InputA int 1
Event handlers : OnCalculate(ohlc)
Plots : LabelA Line Red
以上の設定で簡易的なコードが作成されます。
簡易MQLメモ
色設定の反映
default.tpl EAファイル名.tpl
ATOMとMarkdownで簡単HTML作成
ATOMとMarkdownで簡単HTML作成
ATOMエディタとMarkdown記述方式を利用することで、
ウェブサイトに使えるHTMLデータを簡単に作ることができます。
このページの文書はHTML書き出しを利用して作られています。
ATOMエディタ とは
ATOMはGitHubにより開発されている高機能なテキストエディタです。
ATOMエディタでは、MarkdownファイルをリアルタイムでHTML描画しながら編集できます。
プレビュー画面は、マークダウン(.md)ファイル編集中に Packages > Markdown Preview > Toggle Preview
もしくは、Ctrl + Shift + M キーで表示することができます。
プレビュー画面を保存するか、プレビュー画面右クリックにある[ Copy As HTML ]でHTMLデータを作成できます。
Markdown記法 とは
Markdown(マークダウン)は、プレーンテキストに見出しや引用等の装飾できる軽量マークアップ言語です。
HTMLより簡単に、文書の文字サイズや形式、表示をかえることができ、
多くのBlogやCMSで使われています。 ファイル拡張子は .md です。
https://daringfireball.net/projects/markdown/
Markdownの基本の書き方
プレーンテキスト中に記号やスペースを入れることで、文書を整形します。
見出し
シャープ(#)の後に空白、その後に文字を書くことで、見出し(HTMLにおけるh1タグ)
# 見出し(h1) ## 見出し(h2) ### 見出し(h3)
# 見出し(h1) ## 見出し(h2) ### 見出し(h3)
改行
行の最後にスペース2つを入れることで改行
文書1 (最後にスペース2つ) 文書2
文書1
文書2
段落
行間に空白の行を入れることで段落
段落1 段落1 (空白の行) 段落2 段落2
段落1 段落1
段落2 段落2
リスト
アスタリスク( * )の後に空白、その後に文字を書くことでリスト
アスタリスクのかわりにハイフン( - )、プラス( + )も使用できます。
スペースかタブでインデント(字下げ)することで、階層化できます。
* くだもの * りんご * みかん * やさい + おかし + ポテトチップス + 飴だま
- くだもの
- りんご
- みかん
- やさい
- おかし
- ポテトチップス
- 飴だま
リスト記号のかわりに数字とピリオドで表記。記述数字の順番は無視される。
1. りんご 3. みかん 2. スイカ
- りんご
- みかん
- スイカ
斜体,強調
斜体
アスタリスク( * )で文字を挟むことで斜体
言語 *English*
言語 English
強調
アスタリスク( ** )2つもしくはアンダーコア( __ )2つで文字を挟むことで強調
文章中で**単語**を__強調__できます。
文章中で単語を強調できます。
斜体と強調
アスタリスク( *** )3つもしくはアンダーコア( ___ )3つで
文字を挟むことで斜体と強調両方
***斜体と強調***
斜体と強調
打ち消し線
ハイフン( - )3つで文字を挟むことで打ち消し線
~~打ち消し線~~
打ち消し線
引用
行の先頭に > で引用
>連続で多重引用
引用
多重引用
コード
グレイヴ・アクセント3つ( ``` )もしくはダッシュ(\~\~\~)で文字を挟むことでコード
(Markdownを適用しない文書を表示する)
グレイヴ・アクセント( ` )で文字を挟むことでインラインコード
(文書中の一部をコード表示にする)
~~~
コード
~~~
コード
罫線
アスタリスク3つ以上( *** )、アンダーコア3つ以上( ___ )もしくはハイフン3つ以上( --- )と改行で罫線
HTMLでの<HR> (Horizontal Rule)にあたる
*** ___ ---
リンク
URLを<>で挟むことでリンク
<https://google.com/>
鍵括弧[]に名称、括弧()にURLで文字にリンク
[Google](https://google.com/)
外部参照
URLを別の場所に記述して利用
検索サイト[Google][1]は巨大な[データベース][2]です。 [1]:https://google.com/ "TEST" [2]:https://kotobank.jp/word/%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9-6197
画像
![alt](URL)
で画像を貼り付け
alt情報は画像の代替用のテキスト情報
![alt情報](URL)
pre 整形済みテキスト
半角スペース4つもしくはタブで、コードをpre表示
(スペース) # 見出し(h1) (スペース) ## 見出し(h2) (スペース) ### 見出し(h3)
# 見出し(h1)
## 見出し(h2)
### 見出し(h3)
table
| Header One | Header Two |
| :------------- | :------------- |
| Item One | Item Two |
Header One | Header Two |
---|---|
Item One | Item Two |
Checkbox
- [ ] Todo list - [x] ATOMインストール - [ ] bot制作 - [ ] trading研究
エスケープ
\
を記号の前に置くことで、文字として表示
\*\*\*
***
その他
aaaaaaaaaaaaaaaa
| 目次 | |:-----------|
Left align | Right align | Center align |
---|---|---|
This | This | This |
column | column | column |
will | will | will |
be | be | be |
left | right | center |
aligned | aligned | aligned |
CCXTの基本
CCXT の基本
CryptoCurrency eXchange Trading Library の基本
https://github.com/ccxt/ccxt
https://github.com/ccxt/ccxt/blob/master/README.md
> pip search ccxt
ccxt (1.12.43)
> pip install ccxt
各取引所オブジェクトに対して共通のメゾット操作が可能
from pprint import pprint
import ccxt
print(ccxt.exchanges)
['bitflyer']
Public API
from pprint import pprint
import ccxt
import json
#API KEY(Public API利用時は必要ない)
bf = ccxt.bitflyer({
'apiKey': 'xxxxxxxxxxxxx',
'secret': 'xxxxxxxxxxxxx'
})
pprint(bf)
#通貨の情報
fetch_markets_result = bf.fetch_markets()
pprint(fetch_markets_result[0])
print(json.dumps(fetch_markets_result, indent=True))
#通貨の価格
fetch_markets_ticker = bf.fetch_ticker(symbol='BTC/JPY')
print(json.dumps(fetch_markets_ticker, indent=True))
#fetch_ticker(symbol='BTC/JPY', params={'パラメータ': '値'})
#板情報
fetch_order_book = bf.fetch_order_book(symbol='BTC/JPY')
print(fetch_order_book)
#print(json.dumps(fetch_order_book, indent=True))
#取引履歴
fetch_order_result = bf.fetch_trades(symbol='BTC/JPY', limit=1)
print(json.dumps(fetch_order_result, indent=True))
結果
[
{
"id": "BTC_JPY",
"symbol": "BTC/JPY",
"base": "BTC",
"quote": "JPY",
"info": {
"product_code": "BTC_JPY"
}
},
#他通貨省略
]
{
"symbol": "BTC/JPY",
"timestamp": 1522388592008,
"datetime": "2018-03-30T05:43:12.800Z",
"high": null,
"low": null,
"bid": 745428.0,
"bidVolume": null,
"ask": 745500.0,
"askVolume": null,
"vwap": null,
"open": null,
"close": 745328.0,
"last": 745328.0,
"previousClose": null,
"change": null,
"percentage": null,
"average": null,
"baseVolume": 31560.82277259,
"quoteVolume": null,
"info": {
"product_code": "BTC_JPY",
"timestamp": "2018-03-30T05:43:12.08",
"tick_id": 2107224,
"best_bid": 745428.0,
"best_ask": 745500.0,
"best_bid_size": 2.498,
"best_ask_size": 3.39208716,
"total_bid_depth": 2672.21621002,
"total_ask_depth": 3692.39069499,
"ltp": 745328.0,
"volume": 367134.94338736,
"volume_by_product": 31560.82277259
}
}
[
#履歴省略
]
#板情報省略
Private API
#Private API
#残高
fetch_balance_result = bf.fetch_balance()
#現物用日本円資産額
print(json.dumps(fetch_balance_result["JPY"]["total"], indent=True))
#指値注文
create_order_result = bf.create_order(symbol='BTC/JPY', type='limit', side='BUY', amount=0.002, price=747950)
print(json.dumps(create_order_result, indent=True))
#返しのidはbitflyer order id
#成行注文
order_result = bf.create_order(symbol='BTC/JPY', type='market', side='BUY', amount=0.002) #null
print(json.dumps(order_result, indent=True))
order_result = bf.create_order(symbol='BTC/JPY', type='market', side='SELL', amount=0.002) #null
print(json.dumps(order_result, indent=True))
#返しのidはbitflyer order id
#注文キャンセル
cancel_order_result = bf.cancel_order(id='xxx-xxxxxxxx-xxxxx', symbol='BTC/JPY')
print(json.dumps(cancel_order_result, indent=True))
#null
#注文履歴
orders_result = bf.fetch_orders(symbol='BTC/JPY')
print(json.dumps(orders_result[-1], indent=True))
TradingView Test(TEMP)
Long Entry Only PSAR
次の足でロングエントリー
//@version=3 strategy(title = "Buy Only",overlay=true) psar = sar(0, 0.02, 0.02) strategy.entry("L", true, when = (psar < high), stop=psar) strategy.close("L", when = (psar > low)) plot(psar,linewidth=3,color=red)
TradingView Long Entry Only
Long Entry Only
//@version=3 strategy(title = "Buy Only",overlay=true) buy = crossover(sma(close, 10), sma(close, 100)) sell = crossunder(sma(close, 10), sma(close, 100)) strategy.entry(id = "L", long = true, when = buy ) strategy.close(id = "L", when = sell ) plot(sma(close,100),linewidth=3,color=red) plot(sma(close,10),linewidth=2,color=red)
//@version=3 strategy(title = "Buy Only",overlay=true) buy = crossover(sma(close, 10), sma(close, 100)) sell = crossunder(sma(close, 10), sma(close, 100)) strategy.entry("L", strategy.long, when=buy) strategy.close("L", when=sell) plot(sma(close,100),linewidth=3,color=red) plot(sma(close,10),linewidth=2,color=red)
TradingView Scripts(TEMP)
Sunday BgColor
study("Sunday", overlay = true) //bgcolor(dayofweek == 1 ? #aaaaaa : dayofweek == 7 ? #aaaaaa : na, transp = 90) bgcolor(dayofweek == 1 ? #aaaaaa : na, transp = 80)
Cryptowatch Chart Matplotlib Slider Test
Cryptowatch APIから取得したBTCJPYチャートに、スライダーで調整可能な指標をMatplotlibで表示する。
import numpy as np import pandas as pd import json import requests from datetime import datetime from pprint import pprint import time import matplotlib.pyplot as plt from matplotlib.gridspec import GridSpec from matplotlib.widgets import Slider #------------------------------------------ def sma(df, n): df = df.rolling(window=int(n)).mean() return df def ewm(df, n): df = df.ewm(span=int(n)).mean() return df #設定 ------------------------ GET_PERIODS = 60 * 5 # 時間足(秒) GET_AFTER = 50 # 足本数 #Cryptowatch API History Data ------------------------ now = datetime.now() now = int(now.timestamp()) #現在時刻のUnixtime(秒単位) market = "bitflyer/btcjpy" get_periods = GET_PERIODS get_after = now - get_periods * GET_AFTER #HTTPライブラリ Requestsによる価格履歴取得 r = requests.get("https://api.cryptowat.ch/markets/" + market + "/ohlc?periods="+ str(get_periods) +"&after="+ str(get_after)).json() print("[ now :", now,"]", "[ periods :", get_periods, "]", "[ after :", get_after,"]") # Pandas OHLCデータ ------------------------ ohlcv = r["result"][str(get_periods)] df = pd.DataFrame(ohlcv, columns = ["datetime","open","high","low","close","volume",'']) df = df.set_index("datetime") # Indicator ------------------------ slider1_min, slider1_max, slider1_init, slider1_step = 1, 100, 15, 1 slider2_min, slider2_max, slider2_init, slider2_step = 1, 100, 5, 1 df_1 = sma(df["close"], slider1_init) df_2 = ewm(df["close"], slider1_init) print(df.head(5)) print(df.iloc[len(df_1) - 1]) # matplotlib ------------------- plt.style.use("ggplot") # matplotlib ggplot style読込 fig = plt.figure(figsize=(12,8)) # figsize=ウィンドウサイズ fig.patch.set_facecolor("#fafafa") # 全体背景色 gs = GridSpec(4, 1, height_ratios=[3, 0.8, 1.2, 1]) #縦4個、横1個のグリッドとその表示比率 gs.update(left=0.07,bottom=0.05, right=0.95, top=0.95, hspace=0) #全体の余白 ax0 = plt.subplot(gs[0]) ax0.plot(df["close"], marker="o", markersize=1.5, linewidth=2, color="orange") ax0.plot(df["high"], linewidth=0.7, color="orange") ax0.plot(df["low"], linewidth=0.7, color="orange") l1, = ax0.plot(df_1, linewidth=2, color="red") l2, = ax0.plot(df_2, linewidth=2, color="green") ax0.tick_params(axis="x", bottom=False, labelbottom=False) #x軸目盛とラベルの非表示 #ax0.axhline(0, color="orange") ax1 = plt.subplot(gs[1], sharex=ax0) ax1.spines["top"].set_color("slategray") #ax0とax1の境界線 ax1.bar(df.index,df["volume"], color="orange", width=get_periods*0.94) ax2 = plt.subplot(gs[2]) ax2.axis("off") #ax2のxy軸の非表示 ax3 = plt.subplot(gs[3], sharex=ax0) ax3.grid(False) #Slider slider_ax1 = fig.add_axes([0.6,0.26,0.3,0.032]) slider1 = Slider(slider_ax1, 'value1', slider1_min, slider1_max, valinit=slider1_init, valstep=slider1_step) slider_ax2 = fig.add_axes([0.6,0.22,0.3,0.032]) slider2 = Slider(slider_ax2, 'value2', slider2_min, slider2_max, valinit=slider2_init, valstep=slider2_step) def update1(value): df_1 = sma(df["close"], value) l1.set_ydata(df_1) fig.canvas.draw_idle() def update2(value): df_2 = ewm(df["close"], value) l2.set_ydata(df_2) fig.canvas.draw_idle() slider1.on_changed(update1) slider2.on_changed(update2) plt.show()
コードライセンスは CC0 もしくは Unlicense
Creative Commons — CC0 1.0 Universal
Unlicense.org » Unlicense Yourself: Set Your Code Free
matplotlib_simple_template.py
import matplotlib.pyplot as plt from matplotlib.gridspec import GridSpec # matplotlib ------------------- plt.style.use("ggplot") # style読込 fig = plt.figure(figsize=(12,8)) # figsize=ウィンドウサイズ fig.patch.set_facecolor("#fafafa") # 全体背景色 gs = GridSpec(4, 1, height_ratios=[3, 1, 0.8, 1.2]) #縦4個、横1個のグリッドとその表示比率 gs.update(left=0.07,bottom=0.05, right=0.95, top=0.95, hspace=0) #全体の余白 ax0 = plt.subplot(gs[0]) ax0.tick_params(axis="x", bottom=False, labelbottom=False) #x軸目盛とラベルの非表示 ax1 = plt.subplot(gs[1], sharex=ax0) ax1.spines["top"].set_color("slategray") ax2 = plt.subplot(gs[2]) ax2.axis("off") #軸の非表示 ax3 = plt.subplot(gs[3], sharex=ax0) ax3.grid(False) plt.show()
Searching code コード検索 参考情報
日本語
Python 3 ドキュメント
https://docs.python.jp/3/
Qiita
https://qiita.com/
エンジニアリングに関する知識を記録・共有するためのサービス
teratail
https://teratail.com/
エンジニア特化型Q&Aサイト
英語
Python 3.6.5 documentation
https://docs.python.org/3/
Nullege
http://nullege.com/
Nullege is a search engine for Python source code.
searchcode
https://searchcode.com/
stack overflow
https://stackoverflow.com/
github
https://github.com/explore
Google 複数サイト検索
Python site:hatenablog.com OR site:teratail.com OR site:qiita.com OR site:d.hatena.ne.jp OR site:q.hatena.ne.jp OR site:docs.python.jp OR site:pythondatascience.plavox.info
Bitfinex Ticker
""" https://bitfinex.readme.io/v2/reference#rest-public-ticker // on trading pairs (ex. tBTCUSD) [ BID, BID_SIZE, ASK, ASK_SIZE, DAILY_CHANGE, DAILY_CHANGE_PERC, LAST_PRICE, VOLUME, HIGH, LOW ] """ import requests from time import sleep api = "https://api.bitfinex.com/v2/{}/" currency_pair = "tBTCUSD" while(True): data_bitfinex = requests.get(api.format("ticker") + currency_pair) print(data_bitfinex.json()) sleep(5)