{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import indicators as ind #indicators.pyのインポート\n", "\n", "dataM1 = pd.read_csv('DAT_ASCII_EURUSD_M1_2015.csv', sep=';',\n", " names=('Time','Open','High','Low','Close', ''),\n", " index_col='Time', parse_dates=True)\n", "dataM1.index += pd.offsets.Hour(7) #7時間のオフセット\n", "ohlc = ind.TF_ohlc(dataM1, 'H') #1時間足データの作成" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "FastMA = ind.iMA(ohlc, 10) #エントリー用短期移動平均\n", "SlowMA = ind.iMA(ohlc, 30) #エントリー用長期移動平均\n", "ExitMA = ind.iMA(ohlc, 5) #エグジット用移動平均" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [], "source": [ "#買いエントリーシグナル\n", "BuyEntry = ((FastMA > SlowMA) & (FastMA.shift() <= SlowMA.shift())).values\n", "#売りエントリーシグナル\n", "SellEntry = ((FastMA < SlowMA) & (FastMA.shift() >= SlowMA.shift())).values\n", "#買いエグジットシグナル\n", "BuyExit = ((ohlc.Close < ExitMA) & (ohlc.Close.shift() >= ExitMA.shift())).values\n", "#売りエグジットシグナル\n", "SellExit = ((ohlc.Close > ExitMA) & (ohlc.Close.shift() <= ExitMA.shift())).values" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def Backtest(ohlc, BuyEntry, SellEntry, BuyExit, SellExit, lots=0.1, spread=2, TP=0, SL=0, Limit=0, Expiration=10):\n", " Open = ohlc.Open.values #始値\n", " Low = ohlc.Low.values #安値\n", " High = ohlc.High.values #高値\n", " Point = 0.0001 #1pipの値\n", " if(Open[0] > 50): Point = 0.01 #クロス円の1pipの値\n", " Spread = spread*Point #スプレッド\n", " Lots = lots*100000 #実際の売買量\n", " N = len(ohlc) #FXデータのサイズ\n", " \n", " LongTrade = np.zeros(N) #買いトレード情報\n", " ShortTrade = np.zeros(N) #売りトレード情報\n", "\n", " #買いエントリー価格\n", " BuyEntryS = np.hstack((False, BuyEntry[:-1])) #買いエントリーシグナルのシフト\n", " if Limit == 0: LongTrade[BuyEntryS] = Open[BuyEntryS]+Spread #成行買い\n", " else: #指値買い\n", " for i in range(N-Expiration):\n", " if BuyEntryS[i]:\n", " BuyLimit = Open[i]-Limit*Point #指値\n", " for j in range(Expiration):\n", " if Low[i+j] <= BuyLimit: #約定条件\n", " LongTrade[i+j] = BuyLimit+Spread\n", " break\n", " #買いエグジット価格\n", " BuyExitS = np.hstack((False, BuyExit[:-2], True)) #買いエグジットシグナルのシフト\n", " LongTrade[BuyExitS] = -Open[BuyExitS]\n", " \n", " #売りエントリー価格\n", " SellEntryS = np.hstack((False, SellEntry[:-1])) #売りエントリーシグナルのシフト\n", " if Limit == 0: ShortTrade[SellEntryS] = Open[SellEntryS] #成行売り\n", " else: #指値売り\n", " for i in range(N-Expiration):\n", " if SellEntryS[i]:\n", " SellLimit = Open[i]+Limit*Point #指値\n", " for j in range(Expiration):\n", " if High[i+j] >= SellLimit: #約定条件\n", " ShortTrade[i+j] = SellLimit\n", " break\n", " #売りエグジット価格\n", " SellExitS = np.hstack((False, SellExit[:-2], True)) #売りエグジットシグナルのシフト\n", " ShortTrade[SellExitS] = -(Open[SellExitS]+Spread)\n", " \n", " LongPL = np.zeros(N) # 買いポジションの損益\n", " ShortPL = np.zeros(N) # 売りポジションの損益\n", " BuyPrice = SellPrice = 0.0 # 売買価格\n", " \n", " for i in range(1,N):\n", " if LongTrade[i] > 0: #買いエントリーシグナル\n", " if BuyPrice == 0:\n", " BuyPrice = LongTrade[i]\n", " ShortTrade[i] = -BuyPrice #売りエグジット\n", " else: LongTrade[i] = 0\n", "\n", " if ShortTrade[i] > 0: #売りエントリーシグナル\n", " if SellPrice == 0:\n", " SellPrice = ShortTrade[i]\n", " LongTrade[i] = -SellPrice #買いエグジット\n", " else: ShortTrade[i] = 0\n", "\n", " if LongTrade[i] < 0: #買いエグジットシグナル\n", " if BuyPrice != 0:\n", " LongPL[i] = -(BuyPrice+LongTrade[i])*Lots #損益確定\n", " BuyPrice = 0\n", " else: LongTrade[i] = 0\n", " \n", " if ShortTrade[i] < 0: #売りエグジットシグナル\n", " if SellPrice != 0:\n", " ShortPL[i] = (SellPrice+ShortTrade[i])*Lots #損益確定\n", " SellPrice = 0\n", " else: ShortTrade[i] = 0\n", "\n", " if BuyPrice != 0 and SL > 0: #SLによる買いポジションの決済\n", " StopPrice = BuyPrice-SL*Point\n", " if Low[i] <= StopPrice:\n", " LongTrade[i] = -StopPrice\n", " LongPL[i] = -(BuyPrice+LongTrade[i])*Lots #損益確定\n", " BuyPrice = 0\n", "\n", " if BuyPrice != 0 and TP > 0: #TPによる買いポジションの決済\n", " LimitPrice = BuyPrice+TP*Point\n", " if High[i] >= LimitPrice:\n", " LongTrade[i] = -LimitPrice\n", " LongPL[i] = -(BuyPrice+LongTrade[i])*Lots #損益確定\n", " BuyPrice = 0\n", " \n", " if SellPrice != 0 and SL > 0: #SLによる売りポジションの決済\n", " StopPrice = SellPrice+SL*Point\n", " if High[i] >= StopPrice+Spread:\n", " ShortTrade[i] = -StopPrice\n", " ShortPL[i] = (SellPrice+ShortTrade[i])*Lots #損益確定\n", " SellPrice = 0\n", "\n", " if SellPrice != 0 and TP > 0: #TPによる売りポジションの決済\n", " LimitPrice = SellPrice-TP*Point\n", " if Low[i] <= LimitPrice+Spread:\n", " ShortTrade[i] = -LimitPrice\n", " ShortPL[i] = (SellPrice+ShortTrade[i])*Lots #損益確定\n", " SellPrice = 0\n", " \n", " return pd.DataFrame({'Long':LongTrade, 'Short':ShortTrade}, index=ohlc.index),\\\n", " pd.DataFrame({'Long':LongPL, 'Short':ShortPL}, index=ohlc.index)\n", "\n", "Trade, PL = Backtest(ohlc, BuyEntry, SellEntry, BuyExit, SellExit, TP=100, SL=50, Limit=20)\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "買いトレード数 = 51\n", "勝トレード数 = 19\n", "最大勝トレード = 100.0\n", "平均勝トレード = 32.33\n", "負トレード数 = 34\n", "最大負トレード = -50.0\n", "平均負トレード = -17.4\n", "勝率 = 37.25 %\n", "\n", "売りトレード数 = 43\n", "勝トレード数 = 22\n", "最大勝トレード = 100.0\n", "平均勝トレード = 33.13\n", "負トレード数 = 23\n", "最大負トレード = -50.0\n", "平均負トレード = -19.92\n", "勝率 = 51.16 %\n", "\n", "総トレード数 = 94\n", "勝トレード数 = 41\n", "最大勝トレード = 100.0\n", "平均勝トレード = 32.76\n", "負トレード数 = 57\n", "最大負トレード = -50.0\n", "平均負トレード = -18.42\n", "勝率 = 43.62 %\n", "\n", "総利益 = 1343.1\n", "総損失 = -1049.8\n", "総損益 = 293.3\n", "プロフィットファクター = 1.28\n", "平均損益 = 3.12\n", "最大ドローダウン = 192.6\n", "リカバリーファクター = 1.52\n" ] } ], "source": [ "def BacktestReport(Trade, PL):\n", " LongPL = PL['Long']\n", " LongTrades = np.count_nonzero(Trade['Long'])//2\n", " LongWinTrades = np.count_nonzero(LongPL.clip_lower(0))\n", " LongLoseTrades = np.count_nonzero(LongPL.clip_upper(0))\n", " print('買いトレード数 =', LongTrades)\n", " print('勝トレード数 =', LongWinTrades)\n", " print('最大勝トレード =', LongPL.max())\n", " print('平均勝トレード =', round(LongPL.clip_lower(0).sum()/LongWinTrades, 2))\n", " print('負トレード数 =', LongLoseTrades)\n", " print('最大負トレード =', LongPL.min())\n", " print('平均負トレード =', round(LongPL.clip_upper(0).sum()/LongLoseTrades, 2))\n", " print('勝率 =', round(LongWinTrades/LongTrades*100, 2), '%\\n')\n", "\n", " ShortPL = PL['Short']\n", " ShortTrades = np.count_nonzero(Trade['Short'])//2\n", " ShortWinTrades = np.count_nonzero(ShortPL.clip_lower(0))\n", " ShortLoseTrades = np.count_nonzero(ShortPL.clip_upper(0))\n", " print('売りトレード数 =', ShortTrades)\n", " print('勝トレード数 =', ShortWinTrades)\n", " print('最大勝トレード =', ShortPL.max())\n", " print('平均勝トレード =', round(ShortPL.clip_lower(0).sum()/ShortWinTrades, 2))\n", " print('負トレード数 =', ShortLoseTrades)\n", " print('最大負トレード =', ShortPL.min())\n", " print('平均負トレード =', round(ShortPL.clip_upper(0).sum()/ShortLoseTrades, 2))\n", " print('勝率 =', round(ShortWinTrades/ShortTrades*100, 2), '%\\n')\n", "\n", " Trades = LongTrades + ShortTrades\n", " WinTrades = LongWinTrades+ShortWinTrades\n", " LoseTrades = LongLoseTrades+ShortLoseTrades\n", " print('総トレード数 =', Trades)\n", " print('勝トレード数 =', WinTrades)\n", " print('最大勝トレード =', max(LongPL.max(), ShortPL.max()))\n", " print('平均勝トレード =', round((LongPL.clip_lower(0).sum()+ShortPL.clip_lower(0).sum())/WinTrades, 2))\n", " print('負トレード数 =', LoseTrades)\n", " print('最大負トレード =', min(LongPL.min(), ShortPL.min()))\n", " print('平均負トレード =', round((LongPL.clip_upper(0).sum()+ShortPL.clip_upper(0).sum())/LoseTrades, 2))\n", " print('勝率 =', round(WinTrades/Trades*100, 2), '%\\n')\n", "\n", " GrossProfit = LongPL.clip_lower(0).sum()+ShortPL.clip_lower(0).sum()\n", " GrossLoss = LongPL.clip_upper(0).sum()+ShortPL.clip_upper(0).sum()\n", " Profit = GrossProfit+GrossLoss\n", " Equity = (LongPL+ShortPL).cumsum()\n", " MDD = (Equity.cummax()-Equity).max()\n", " print('総利益 =', round(GrossProfit, 2))\n", " print('総損失 =', round(GrossLoss, 2))\n", " print('総損益 =', round(Profit, 2))\n", " print('プロフィットファクター =', round(-GrossProfit/GrossLoss, 2))\n", " print('平均損益 =', round(Profit/Trades, 2))\n", " print('最大ドローダウン =', round(MDD, 2))\n", " print('リカバリーファクター =', round(Profit/MDD, 2))\n", " return Equity\n", "Equity = BacktestReport(Trade, PL)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from pandas_highcharts.display import display_charts\n", "Initial = 10000 # 初期資産\n", "Equity = (PL.Long+PL.Short).cumsum() #累積損益\n", "display_charts(pd.DataFrame({'Equity':Equity+Initial}), chart_type=\"stock\", title=\"資産曲線\", figsize=(640,480), grid=True)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def PositionLine(trade):\n", " PosPeriod = 0 #ポジションの期間\n", " Position = False #ポジションの有無\n", " Line = trade.copy()\n", " for i in range(len(Line)):\n", " if trade[i] > 0: Position = True \n", " elif Position: PosPeriod += 1 # ポジションの期間をカウント\n", " if trade[i] < 0:\n", " if PosPeriod > 0:\n", " Line[i] = -trade[i]\n", " diff = (Line[i]-Line[i-PosPeriod])/PosPeriod\n", " for j in range(i-1, i-PosPeriod, -1):\n", " Line[j] = Line[j+1]-diff # ポジションの期間を補間\n", " PosPeriod = 0\n", " Position = False\n", " if trade[i] == 0 and not Position: Line[i] = 'NaN'\n", " if Line[i] < 0: Line[i] = 'NaN'\n", " return Line\n", "\n", "df = pd.DataFrame({'Open': ohlc['Open'],\n", " 'Long': PositionLine(Trade['Long'].values),\n", " 'Short': PositionLine(Trade['Short'].values)})\n", "display_charts(df, chart_type=\"stock\", title=\"トレードチャート\", figsize=(640,480), grid=True)" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python [Root]", "language": "python", "name": "Python [Root]" }, "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.5.2" } }, "nbformat": 4, "nbformat_minor": 0 }