Skip to content

Instantly share code, notes, and snippets.

@nagishin
Last active September 19, 2018 22:55
Show Gist options
  • Save nagishin/50d9d7ab06dd242d7a962b3c83fb3e40 to your computer and use it in GitHub Desktop.
Save nagishin/50d9d7ab06dd242d7a962b3c83fb3e40 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### EMA設定パラメータ"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"# coding: utf-8\n",
"# OHLCVデータを取得する期間数\n",
"count = 20\n",
"# 移動平均期間:n\n",
"n = 3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 1分足OHLCVから終値リスト(close)を取得"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[6379, 6379.5, 6387, 6388, 6388, 6386, 6381, 6386, 6383.5, 6380, 6380, 6378, 6376, 6376, 6375.5, 6376, 6378, 6376, 6374, 6374]\n"
]
}
],
"source": [
"import time, requests\n",
"# 現在時刻と取得開始時刻\n",
"to_time = int(time.time())\n",
"from_time = to_time - count * 60\n",
"# OHLCVデータ取得\n",
"param = {\"period\": 1, \"from\": from_time, \"to\": to_time}\n",
"url = \"https://www.bitmex.com/api/udf/history?symbol=XBTUSD&resolution={period}&from={from}&to={to}\".format(**param)\n",
"data = requests.get(url).json()\n",
"# 終値リスト(最新のcount件数分)\n",
"close = data[\"c\"][-count:]\n",
"# 確認表示\n",
"print(close)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 自作EMA計算\n",
"EMA = 1分前のEMA+α×(現在の終値-1分前のEMA)\n",
"* 移動平均の期間n\n",
"* α=2÷(n+1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### 計算準備"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"n = 3\n",
"a = 0.5\n",
"length = 20\n"
]
}
],
"source": [
"# 係数:a\n",
"a = 2 / (n + 1)\n",
"# 終値リストの要素数を取得(=count)\n",
"length = len(close)\n",
"# 設定値確認\n",
"print(\"n =\", n)\n",
"print(\"a =\", a)\n",
"print(\"length =\", length)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### 繰り返しEMA計算"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ema[ 0] = 6379.00\n",
"ema[ 1] = 6379.0 + 0.5 * (6379.5 - 6379.00) = 6379.25\n",
"ema[ 2] = 6379.2 + 0.5 * (6387.0 - 6379.25) = 6383.12\n",
"ema[ 3] = 6383.1 + 0.5 * (6388.0 - 6383.12) = 6385.56\n",
"ema[ 4] = 6385.6 + 0.5 * (6388.0 - 6385.56) = 6386.78\n",
"ema[ 5] = 6386.8 + 0.5 * (6386.0 - 6386.78) = 6386.39\n",
"ema[ 6] = 6386.4 + 0.5 * (6381.0 - 6386.39) = 6383.70\n",
"ema[ 7] = 6383.7 + 0.5 * (6386.0 - 6383.70) = 6384.85\n",
"ema[ 8] = 6384.8 + 0.5 * (6383.5 - 6384.85) = 6384.17\n",
"ema[ 9] = 6384.2 + 0.5 * (6380.0 - 6384.17) = 6382.09\n",
"ema[10] = 6382.1 + 0.5 * (6380.0 - 6382.09) = 6381.04\n",
"ema[11] = 6381.0 + 0.5 * (6378.0 - 6381.04) = 6379.52\n",
"ema[12] = 6379.5 + 0.5 * (6376.0 - 6379.52) = 6377.76\n",
"ema[13] = 6377.8 + 0.5 * (6376.0 - 6377.76) = 6376.88\n",
"ema[14] = 6376.9 + 0.5 * (6375.5 - 6376.88) = 6376.19\n",
"ema[15] = 6376.2 + 0.5 * (6376.0 - 6376.19) = 6376.10\n",
"ema[16] = 6376.1 + 0.5 * (6378.0 - 6376.10) = 6377.05\n",
"ema[17] = 6377.0 + 0.5 * (6376.0 - 6377.05) = 6376.52\n",
"ema[18] = 6376.5 + 0.5 * (6374.0 - 6376.52) = 6375.26\n",
"ema[19] = 6375.3 + 0.5 * (6374.0 - 6375.26) = 6374.63\n"
]
}
],
"source": [
"# 補足説明文リスト(計算式)\n",
"messages = []\n",
"# EMA計算結果リスト\n",
"ema = []\n",
"# 最初は1分前がないので終値を設定\n",
"ema.append(close[0])\n",
"# 結果確認\n",
"message = \"ema[%2d] = %.2f\" % (0, ema[-1])\n",
"print(message)\n",
"messages.append(\"---\")\n",
"\n",
"# 終値リストの要素数の数だけ繰り返しEMAを順番に計算していく(先頭除く)\n",
"for i in range(1, length):\n",
" # 現在のEMA = 1分前のEMA+α*(現在の終値-1分前のEMA)\n",
" result = ema[-1] + a * (close[i] - ema[-1])\n",
" # EMAリストに追加\n",
" ema.append(result)\n",
" # 結果確認\n",
" message = \"%.1f + %.1f * (%.1f - %.2f)\" % (ema[-2],a,close[i],ema[-2])\n",
" print(\"ema[%2d] = \" % i + message + \" = %.2f\" % result)\n",
" messages.append(message)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### EMAをpandasで計算"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 6379.000000\n",
"1 6379.333333\n",
"2 6383.714286\n",
"3 6386.000000\n",
"4 6387.032258\n",
"5 6386.507937\n",
"6 6383.732283\n",
"7 6384.870588\n",
"8 6384.183953\n",
"9 6382.089932\n",
"10 6381.044455\n",
"11 6379.521856\n",
"12 6377.760713\n",
"13 6376.880303\n",
"14 6376.190130\n",
"15 6376.095064\n",
"16 6377.047539\n",
"17 6376.523768\n",
"18 6375.261881\n",
"19 6374.630940\n",
"dtype: float64"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import pandas as pd\n",
"# 終値リストをSeries化してEWMの平均を計算\n",
"pd_ema = pd.Series(close).ewm(span=n).mean()\n",
"display(pd_ema)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### EMA計算結果を比較"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>終値</th>\n",
" <th>計算式</th>\n",
" <th>EMA</th>\n",
" <th>pandas EMA</th>\n",
" <th>差分</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>6379.0</td>\n",
" <td>---</td>\n",
" <td>6379.000000</td>\n",
" <td>6379.000000</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>6379.5</td>\n",
" <td>6379.0 + 0.5 * (6379.5 - 6379.00)</td>\n",
" <td>6379.250000</td>\n",
" <td>6379.333333</td>\n",
" <td>-0.083333</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>6387.0</td>\n",
" <td>6379.2 + 0.5 * (6387.0 - 6379.25)</td>\n",
" <td>6383.125000</td>\n",
" <td>6383.714286</td>\n",
" <td>-0.589286</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>6388.0</td>\n",
" <td>6383.1 + 0.5 * (6388.0 - 6383.12)</td>\n",
" <td>6385.562500</td>\n",
" <td>6386.000000</td>\n",
" <td>-0.437500</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>6388.0</td>\n",
" <td>6385.6 + 0.5 * (6388.0 - 6385.56)</td>\n",
" <td>6386.781250</td>\n",
" <td>6387.032258</td>\n",
" <td>-0.251008</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>6386.0</td>\n",
" <td>6386.8 + 0.5 * (6386.0 - 6386.78)</td>\n",
" <td>6386.390625</td>\n",
" <td>6386.507937</td>\n",
" <td>-0.117312</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>6381.0</td>\n",
" <td>6386.4 + 0.5 * (6381.0 - 6386.39)</td>\n",
" <td>6383.695312</td>\n",
" <td>6383.732283</td>\n",
" <td>-0.036971</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>6386.0</td>\n",
" <td>6383.7 + 0.5 * (6386.0 - 6383.70)</td>\n",
" <td>6384.847656</td>\n",
" <td>6384.870588</td>\n",
" <td>-0.022932</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>6383.5</td>\n",
" <td>6384.8 + 0.5 * (6383.5 - 6384.85)</td>\n",
" <td>6384.173828</td>\n",
" <td>6384.183953</td>\n",
" <td>-0.010125</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>6380.0</td>\n",
" <td>6384.2 + 0.5 * (6380.0 - 6384.17)</td>\n",
" <td>6382.086914</td>\n",
" <td>6382.089932</td>\n",
" <td>-0.003018</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>6380.0</td>\n",
" <td>6382.1 + 0.5 * (6380.0 - 6382.09)</td>\n",
" <td>6381.043457</td>\n",
" <td>6381.044455</td>\n",
" <td>-0.000998</td>\n",
" </tr>\n",
" <tr>\n",
" <th>11</th>\n",
" <td>6378.0</td>\n",
" <td>6381.0 + 0.5 * (6378.0 - 6381.04)</td>\n",
" <td>6379.521729</td>\n",
" <td>6379.521856</td>\n",
" <td>-0.000127</td>\n",
" </tr>\n",
" <tr>\n",
" <th>12</th>\n",
" <td>6376.0</td>\n",
" <td>6379.5 + 0.5 * (6376.0 - 6379.52)</td>\n",
" <td>6377.760864</td>\n",
" <td>6377.760713</td>\n",
" <td>0.000151</td>\n",
" </tr>\n",
" <tr>\n",
" <th>13</th>\n",
" <td>6376.0</td>\n",
" <td>6377.8 + 0.5 * (6376.0 - 6377.76)</td>\n",
" <td>6376.880432</td>\n",
" <td>6376.880303</td>\n",
" <td>0.000129</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>6375.5</td>\n",
" <td>6376.9 + 0.5 * (6375.5 - 6376.88)</td>\n",
" <td>6376.190216</td>\n",
" <td>6376.190130</td>\n",
" <td>0.000086</td>\n",
" </tr>\n",
" <tr>\n",
" <th>15</th>\n",
" <td>6376.0</td>\n",
" <td>6376.2 + 0.5 * (6376.0 - 6376.19)</td>\n",
" <td>6376.095108</td>\n",
" <td>6376.095064</td>\n",
" <td>0.000044</td>\n",
" </tr>\n",
" <tr>\n",
" <th>16</th>\n",
" <td>6378.0</td>\n",
" <td>6376.1 + 0.5 * (6378.0 - 6376.10)</td>\n",
" <td>6377.047554</td>\n",
" <td>6377.047539</td>\n",
" <td>0.000015</td>\n",
" </tr>\n",
" <tr>\n",
" <th>17</th>\n",
" <td>6376.0</td>\n",
" <td>6377.0 + 0.5 * (6376.0 - 6377.05)</td>\n",
" <td>6376.523777</td>\n",
" <td>6376.523768</td>\n",
" <td>0.000009</td>\n",
" </tr>\n",
" <tr>\n",
" <th>18</th>\n",
" <td>6374.0</td>\n",
" <td>6376.5 + 0.5 * (6374.0 - 6376.52)</td>\n",
" <td>6375.261889</td>\n",
" <td>6375.261881</td>\n",
" <td>0.000007</td>\n",
" </tr>\n",
" <tr>\n",
" <th>19</th>\n",
" <td>6374.0</td>\n",
" <td>6375.3 + 0.5 * (6374.0 - 6375.26)</td>\n",
" <td>6374.630944</td>\n",
" <td>6374.630940</td>\n",
" <td>0.000004</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 終値 計算式 EMA pandas EMA \\\n",
"0 6379.0 --- 6379.000000 6379.000000 \n",
"1 6379.5 6379.0 + 0.5 * (6379.5 - 6379.00) 6379.250000 6379.333333 \n",
"2 6387.0 6379.2 + 0.5 * (6387.0 - 6379.25) 6383.125000 6383.714286 \n",
"3 6388.0 6383.1 + 0.5 * (6388.0 - 6383.12) 6385.562500 6386.000000 \n",
"4 6388.0 6385.6 + 0.5 * (6388.0 - 6385.56) 6386.781250 6387.032258 \n",
"5 6386.0 6386.8 + 0.5 * (6386.0 - 6386.78) 6386.390625 6386.507937 \n",
"6 6381.0 6386.4 + 0.5 * (6381.0 - 6386.39) 6383.695312 6383.732283 \n",
"7 6386.0 6383.7 + 0.5 * (6386.0 - 6383.70) 6384.847656 6384.870588 \n",
"8 6383.5 6384.8 + 0.5 * (6383.5 - 6384.85) 6384.173828 6384.183953 \n",
"9 6380.0 6384.2 + 0.5 * (6380.0 - 6384.17) 6382.086914 6382.089932 \n",
"10 6380.0 6382.1 + 0.5 * (6380.0 - 6382.09) 6381.043457 6381.044455 \n",
"11 6378.0 6381.0 + 0.5 * (6378.0 - 6381.04) 6379.521729 6379.521856 \n",
"12 6376.0 6379.5 + 0.5 * (6376.0 - 6379.52) 6377.760864 6377.760713 \n",
"13 6376.0 6377.8 + 0.5 * (6376.0 - 6377.76) 6376.880432 6376.880303 \n",
"14 6375.5 6376.9 + 0.5 * (6375.5 - 6376.88) 6376.190216 6376.190130 \n",
"15 6376.0 6376.2 + 0.5 * (6376.0 - 6376.19) 6376.095108 6376.095064 \n",
"16 6378.0 6376.1 + 0.5 * (6378.0 - 6376.10) 6377.047554 6377.047539 \n",
"17 6376.0 6377.0 + 0.5 * (6376.0 - 6377.05) 6376.523777 6376.523768 \n",
"18 6374.0 6376.5 + 0.5 * (6374.0 - 6376.52) 6375.261889 6375.261881 \n",
"19 6374.0 6375.3 + 0.5 * (6374.0 - 6375.26) 6374.630944 6374.630940 \n",
"\n",
" 差分 \n",
"0 0.000000 \n",
"1 -0.083333 \n",
"2 -0.589286 \n",
"3 -0.437500 \n",
"4 -0.251008 \n",
"5 -0.117312 \n",
"6 -0.036971 \n",
"7 -0.022932 \n",
"8 -0.010125 \n",
"9 -0.003018 \n",
"10 -0.000998 \n",
"11 -0.000127 \n",
"12 0.000151 \n",
"13 0.000129 \n",
"14 0.000086 \n",
"15 0.000044 \n",
"16 0.000015 \n",
"17 0.000009 \n",
"18 0.000007 \n",
"19 0.000004 "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# 終値リスト、計算式リスト、自作EMAリストをDataFrame化\n",
"df = pd.DataFrame([[r[0], r[1], r[2]] for r in zip(close, messages, ema)], columns=[\"終値\", \"計算式\", \"EMA\"])\n",
"# pandas EMA列を追加\n",
"df[\"pandas EMA\"] = pd_ema\n",
"# 自作EMAとpandas EMAの差分列を追加\n",
"df[\"差分\"] = df[\"EMA\"] - df[\"pandas EMA\"]\n",
"# 結果表示\n",
"display(df)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### まとめ"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"EMAは前期間の値を使って連続的に計算します。 \n",
"初回の値の設定により、計算値に差が生じる可能性がありますが、 \n",
"繰り返し計算していくことで差は縮小していきます。 \n",
"<br>\n",
"移動平均の期間 n の11倍くらい前から計算することで誤差の範囲に収束します。 \n",
"<br>\n",
"例) n=10なら、closeを10 * 11 = 110期間分取得 \n",
"期間の初めから計算することで現在のEMAはほぼ正確な値になります。 \n",
"<br>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### おまけ\n",
"処理時間を計測"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"6.11 µs ± 93.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n",
"2.43 ms ± 20.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
]
}
],
"source": [
"# 終値リスト件数\n",
"count = 10000\n",
"# 現在時刻と取得開始時刻\n",
"to_time = int(time.time())\n",
"from_time = to_time - count * 60\n",
"# OHLCVデータ取得\n",
"param = {\"period\": 1, \"from\": from_time, \"to\": to_time}\n",
"url = \"https://www.bitmex.com/api/udf/history?symbol=XBTUSD&resolution={period}&from={from}&to={to}\".format(**param)\n",
"data = requests.get(url).json()\n",
"# 終値リスト(最新のcount件数分)\n",
"close = data[\"c\"][-count:]\n",
"\n",
"# 自作EMA計算\n",
"def ema(lst, term):\n",
" ret = []\n",
" a = 2 / (term + 1)\n",
" ret.append(lst[0])\n",
" for i in range(1, length):\n",
" result = ret[-1] + a * (lst[i] - ret[-1])\n",
" ret.append(result)\n",
" return ret\n",
"\n",
"# pandas EMA計算\n",
"def pd_ema(lst, term):\n",
" return pd.Series(lst).ewm(span=term).mean()\n",
"\n",
"# 自作EMA計測\n",
"%timeit ret = ema(close, n)\n",
"# pandas EMA計測\n",
"%timeit ret = pd_ema(close, n)\n",
"\n",
"# 自作EMA計算時間計測\n",
"#start = time.perf_counter()\n",
"#ret = ema(close, n)\n",
"#elapsed_time = time.perf_counter() - start\n",
"#print(\"[自作EMA] processing time : %.5f[ms]\" % (elapsed_time * 1000))\n",
"\n",
"# pandas EMA計算時間計測\n",
"#start = time.perf_counter()\n",
"#ret = pd_ema(close, n)\n",
"#elapsed_time = time.perf_counter() - start\n",
"#print(\"[pandas EMA] processing time : %.5f[ms]\" % (elapsed_time * 1000))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.2"
},
"toc": {
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment