grr

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()

f:id:testbot:20210315040326p:plain

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()

f:id:testbot:20210315040350p:plain



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)

f:id:testbot:20210315040404p:plain

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))

f:id:testbot:20210315040414p:plain

コードライセンスは 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」

(python.exeのフォルダパス) (python.exeのフォルダパス)\Scripts\

インストール(Ubuntu 17)

sudo apt-get install python3
python -m pip install --upgrade pip

起動

コンソール(コマンドライン)で python もしくは python3 とコマンド入力し起動。
Python のコマンドの後に .py ファイルを指定することで、.py ファイルに保存したコードが実行できる。

文字の表示

画面に文字を出力する。例文「Hello World!」

print("Hello World!")

Hello World!

Python 3 簡易基本チートシート(下書き)

Python 3 簡易基本チートシート(下書き)

python3_sheet.md

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モジュール
数値演算子

+ - * /
// (小数点以下切り捨て)
% (割ったあまり)
** (累乗)

文字列演算子

+連結 *nn回の繰り返し

代入演算子

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作成

ATOMMarkdownで簡単HTML作成

ATOMエディタとMarkdown記述方式を利用することで、
ウェブサイトに使えるHTMLデータを簡単に作ることができます。
このページの文書はHTML書き出しを利用して作られています。

ATOMエディタ とは

ATOMGitHubにより開発されている高機能なテキストエディタです。

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. スイカ
  1. りんご
  2. みかん
  3. イカ

斜体,強調

斜体

アスタリスク( * )で文字を挟むことで斜体
言語 *English*

言語 English

強調

アスタリスク( ** )2つもしくはアンダーコア( __ )2つで文字を挟むことで強調
文章中で**単語**を__強調__できます。

文章中で単語強調できます。

斜体と強調

アスタリスク( *** )3つもしくはアンダーコア( ___ )3つで
文字を挟むことで斜体と強調両方
***斜体と強調***
斜体と強調

打ち消し線

ハイフン( - )3つで文字を挟むことで打ち消し線
~~打ち消し線~~
打ち消し線

引用

行の先頭に > で引用

吾輩は猫である

>連続で多重引用

引用

多重引用

コード

グレイヴ・アクセント3つ( ``` )もしくはダッシュ(\~\~\~)で文字を挟むことでコード
(Markdownを適用しない文書を表示する)
グレイヴ・アクセント( ` )で文字を挟むことでインラインコード
(文書中の一部をコード表示にする)

~~~

コード    

~~~

コード

罫線

アスタリスク3つ以上( *** )、アンダーコア3つ以上( ___ )もしくはハイフン3つ以上( --- )と改行で罫線
HTMLでの<HR> (Horizontal Rule)にあたる

***
___
---



リンク

URLを<>で挟むことでリンク

<https://google.com/>

https://google.com/

鍵括弧[]に名称、括弧()にURLで文字にリンク

[Google](https://google.com/)

Google

外部参照

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

検索サイトGoogleは巨大なデータベースです。

画像

![alt](URL)で画像を貼り付け
alt情報は画像の代替用のテキスト情報

![alt情報](URL)  

alt情報


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研究
  • [ ] Todo list
    • [x] ATOMインストール
    • [ ] bot制作
    • [ ] trading研究

エスケープ

\を記号の前に置くことで、文字として表示

\*\*\*

***


その他

aaaaaaaaaaaaaaaa

aaaaaaaaaaaaaaa

| 目次 | |:-----------|

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)

Cryptowatch Chart Matplotlib Slider Test

f:id:testbot:20210314152303p:plain

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

f:id:testbot:20210314152221p:plain

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)