-
-
Save magick93/f580ea12e0ae98a67f3a757c7ca778d3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"raw_mimetype": "text/html", | |
"slideshow": { | |
"slide_type": "slide" | |
} | |
}, | |
"source": [ | |
"# This program is to implement a function _FX_Volatility()_ to get volatility for Trading Symbol Selection.\n", | |
"\n", | |
"###Data source here is the MT4 exported csv file with trading time, Open, High, Low, Close and volume. For production, the data source could be from database.\n", | |
"\n", | |
"###All the language is in Python.\n", | |
"\n", | |
"\n", | |
"# " | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"##### The following is the 1st Input box, only for IPython Notebook, to show plot/chart inside the console" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"%matplotlib inline" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"#####The 2nd Input box is for importing data from CSV files.\n", | |
"Here only uses EURUSD and USDJPY as example, could be extended to all kinds of Forex symbols." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[['2004.10.20', '18:00', '1.26240', '1.26310', '1.25900', '1.26000', '472'],\n", | |
" ['2004.10.20', '19:00', '1.26000', '1.26070', '1.25820', '1.25870', '411'],\n", | |
" ['2004.10.20', '20:00', '1.25890', '1.25970', '1.25830', '1.25870', '362'],\n", | |
" ['2004.10.20', '21:00', '1.25880', '1.25930', '1.25710', '1.25830', '392'],\n", | |
" ['2004.10.20', '22:00', '1.25830', '1.25920', '1.25760', '1.25870', '338'],\n", | |
" ['2004.10.20', '23:00', '1.25870', '1.25920', '1.25760', '1.25830', '301'],\n", | |
" ['2004.10.21', '00:00', '1.25810', '1.25860', '1.25710', '1.25760', '347'],\n", | |
" ['2004.10.21', '01:00', '1.25760', '1.25830', '1.25720', '1.25800', '287'],\n", | |
" ['2004.10.21', '02:00', '1.25810', '1.25910', '1.25780', '1.25850', '340'],\n", | |
" ['2004.10.21', '03:00', '1.25870', '1.25950', '1.25780', '1.25910', '370']]" | |
] | |
}, | |
"execution_count": 2, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"\"\"\"\n", | |
"Volatility with EWMA model, Python\n", | |
"\"\"\"\n", | |
"\n", | |
"# Import some Python standard libraries\n", | |
"import csv\n", | |
"import math\n", | |
"from datetime import datetime\n", | |
"\n", | |
"# Import data from csv files, read data\n", | |
"EURUSDreader = csv.reader(open('EURUSD.csv'))\n", | |
"USDJPYreader = csv.reader(open('USDJPY.csv'))\n", | |
"\n", | |
"EURUSD = []\n", | |
"for line in EURUSDreader:\n", | |
"\tEURUSD.append(line)\n", | |
"\n", | |
"USDJPY = []\n", | |
"for line in USDJPYreader:\n", | |
"\tUSDJPY.append(line)\n", | |
"\n", | |
"# Show some details about EURUSD\n", | |
"EURUSD[0:10]\n", | |
"# The following Output box, you will see: Time, Clock, Open_price, High_price, Low_price, Close_price and Trading_Volume." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"#####The 3rd Input is for data preparation, to get time data series (EURUSD_Time, USDJPY_Time) and Close price data series (EURUSD_Close, USDJPY_Close)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"[datetime.datetime(2004, 10, 20, 18, 0),\n", | |
" datetime.datetime(2004, 10, 20, 19, 0),\n", | |
" datetime.datetime(2004, 10, 20, 20, 0),\n", | |
" datetime.datetime(2004, 10, 20, 21, 0),\n", | |
" datetime.datetime(2004, 10, 20, 22, 0),\n", | |
" datetime.datetime(2004, 10, 20, 23, 0),\n", | |
" datetime.datetime(2004, 10, 21, 0, 0),\n", | |
" datetime.datetime(2004, 10, 21, 1, 0),\n", | |
" datetime.datetime(2004, 10, 21, 2, 0),\n", | |
" datetime.datetime(2004, 10, 21, 3, 0)]" | |
] | |
}, | |
"execution_count": 3, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"# Time data processing\n", | |
"EURUSD_Time = []\n", | |
"for row in EURUSD:\n", | |
"\tEURUSD_Time.append(datetime.strptime((row[0] + \" \" + row[1]), \"%Y.%m.%d %H:%M\"))\n", | |
"\n", | |
"USDJPY_Time = []\n", | |
"for row in USDJPY:\n", | |
"\tUSDJPY_Time.append(datetime.strptime((row[0] + \" \" + row[1]), \"%Y.%m.%d %H:%M\"))\n", | |
"\n", | |
"# Close_price data processing\\\n", | |
"EURUSD_Close = []\t\n", | |
"for row in EURUSD:\n", | |
"\tEURUSD_Close.append(float(row[5]))\n", | |
"\n", | |
"USDJPY_Close = []\t\n", | |
"for row in USDJPY:\n", | |
"\tUSDJPY_Close.append(float(row[5]))\n", | |
" \n", | |
"EURUSD_Time[0:10]" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### For production, Input box [1], [2], [3] should be changed. For example, from database." | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"#####4th, we calculate the Return series of the Forex\n", | |
"Use Close_price series to calculate **Return series** of the Forex. The volatility calculation is based on Return data series.\n", | |
"\n", | |
"To calculate Return series data:\n", | |
"- create an empty list \"EURUSD_Return\"\n", | |
"- loop through EURUSD_Close, each Return is calculated from two agjacent Close_price, formula:\n", | |
"\n", | |
"###$$Return_i = log_e(Close_{i+1}) - log_e(Close_i)$$\n", | |
"\n", | |
"- append each Return item into the list EURUSD_Return.\n", | |
"\n", | |
"Java logarithm calculation reference: \n", | |
"_static double log(double a)_\n", | |
"http://docs.oracle.com/javase/7/docs/api/java/lang/Math.html (search \"natural logarithm\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# Rate of return calculation, using EURUSD as an example\n", | |
"EURUSD_Return = []\n", | |
"\n", | |
"for index in (range(len(EURUSD_Close) - 1)):\n", | |
"\ttemp = math.log(EURUSD_Close[index + 1]) - math.log(EURUSD_Close[index])\n", | |
"\tEURUSD_Return.append(temp)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"###Finally, implement the _FX_Volatility()_ function \n", | |
"\n", | |
"#####Use EWMA model to calculate volatility, to show users the latest volatility condition of the Forex product.\n", | |
"\n", | |
"EWMA model:\n", | |
"###$$\\sigma_n^2 = \\lambda\\sigma_{n-1}^2 + (1 - \\lambda)u_{n-1}^2$$\n", | |
"\n", | |
"- $\\sigma_n$: volatility at day n \n", | |
"- $u_{n - 1}$: daily percentage change in the variable\n", | |
"- $\\lambda$: the parameter to decide weights, 0 < $\\lambda$ < 1\n", | |
"\n", | |
"\n", | |
"Reference:\n", | |
"- $\\lambda$ choice: http://www.investopedia.com/articles/07/ewma.asp\n", | |
"- EWMA model for Python Pandas\n", | |
"http://pandas.pydata.org/pandas-docs/dev/generated/pandas.stats.moments.ewma.html\n", | |
"- EWMA model for Java reference:\n", | |
"\n", | |
"https://github.com/dropwizard/metrics/blob/master/metrics-core/src/main/java/com/codahale/metrics/EWMA.java\n", | |
"http://grepcode.com/file/repo1.maven.org/maven2/com.codahale.metrics/metrics-core/3.0.1/com/codahale/metrics/EWMA.java" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# Volatility using Exponetial Weighted Moving Average model, with the \"Pandas\" package\n", | |
"import pandas # Import a 3rd party package \"Pandas\"\n", | |
"\n", | |
"\n", | |
"# Function of EWMA Volatility - FX_Volatility()\n", | |
"def FX_Volatility(FX_Close_raw, FX_Time, starting_time, ending_time):\n", | |
"\t\"\"\"\n", | |
"\tFor production:\n", | |
" users should choose only starting_time and the name of FX symbol, \n", | |
"\tthe ending_time should always be the latest time in our market database,\n", | |
"\tand we do the data processing(to generate FX_Close_raw and FX_Time) for users.\n", | |
"\n", | |
"\t4 input data:\n", | |
"\t1-dimension array/list/vector of FX_Close_price series\n", | |
"\t1-dimension array/list/vector of FX_Time series\n", | |
"\ta time data of starting_time\n", | |
"\ta time data of ending_time\n", | |
"\t\"\"\"\n", | |
"\t\n", | |
"\t# Get the Close_price data within a period from starting_time to ending_time\n", | |
"\tindex_1 = FX_Time.index(starting_time)\n", | |
"\tindex_2 = FX_Time.index(ending_time) + 1\n", | |
"\tFX_Close = FX_Close_raw[index_1 : index_2]\n", | |
"\n", | |
"\t# Get the Return_series of the FX symbol\n", | |
"\tFX_Return = []\n", | |
"\n", | |
"\tfor index in (range(len(FX_Close) - 1)):\n", | |
"\t\ttemp = math.log(FX_Close[index + 1]) - math.log(FX_Close[index])\n", | |
"\t\tFX_Return.append(temp)\n", | |
"\n", | |
"\t# Use the built-in function in the Pandas package to calculate volatility series\n", | |
"\tFX_ReturnSeries = pandas.Series(FX_Return)\n", | |
"\tEWMA_Volatility = pandas.stats.moments.ewma(FX_ReturnSeries, (1/0.94-1))\n", | |
" \n", | |
"\t# The returned value is the last value of the volatility series\n", | |
"\treturn EWMA_Volatility[len(EWMA_Volatility)-1]\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"#####The last box: we show some example here to call the function and see the output." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"0.000337875882614\n", | |
"0.000665365109227\n" | |
] | |
} | |
], | |
"source": [ | |
"# Some examples to call the function\n", | |
"Volatility_example_1 = FX_Volatility(EURUSD_Close, EURUSD_Time, datetime(2014, 01, 01, 23, 0), datetime(2015, 04, 01, 07, 0))\n", | |
"print Volatility_example_1\n", | |
"\n", | |
"Volatility_example_2 = FX_Volatility(USDJPY_Close, USDJPY_Time, datetime(2014, 01, 01, 23, 0), datetime(2015, 04, 23, 23, 0))\n", | |
"print Volatility_example_2" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"# Function of EWMA Volatility - FX_Volatility()\n", | |
"def FX_Volatility_2(FX_Close_raw, FX_Time, starting_time, ending_time):\n", | |
"\t\"\"\"\n", | |
"\tFor production:\n", | |
" users should choose only starting_time and the name of FX symbol, \n", | |
"\tthe ending_time should always be the latest time in our market database,\n", | |
"\tand we do the data processing(to generate FX_Close_raw and FX_Time) for users.\n", | |
"\n", | |
"\t4 input data:\n", | |
"\t1-dimension array/list/vector of FX_Close_price series\n", | |
"\t1-dimension array/list/vector of FX_Time series\n", | |
"\ta time data of starting_time\n", | |
"\ta time data of ending_time\n", | |
"\t\"\"\"\n", | |
"\t\n", | |
"\t# Get the Close_price data within a period from starting_time to ending_time\n", | |
"\tindex_1 = FX_Time.index(starting_time)\n", | |
"\tindex_2 = FX_Time.index(ending_time) + 1\n", | |
"\tFX_Close = FX_Close_raw[index_1 : index_2]\n", | |
"\n", | |
"\t# Get the Return_series of the FX symbol\n", | |
"\tFX_Return = []\n", | |
"\n", | |
"\tfor index in (range(len(FX_Close) - 1)):\n", | |
"\t\ttemp = math.log(FX_Close[index + 1]) - math.log(FX_Close[index])\n", | |
"\t\tFX_Return.append(temp)\n", | |
"\n", | |
" # Calculate EWMA model and get the volatility\n", | |
"\tLAMBDA = 0.94\n", | |
"\tVolatility = []\n", | |
"\tVolatility.append(FX_Return[0])\n", | |
"\n", | |
"\tfor i in range(len(FX_Return)):\n", | |
"\t\ttemp_Volatility = math.sqrt(LAMBDA * Volatility[i] ** 2 + (1 - LAMBDA) * FX_Return[i] ** 2)\n", | |
"\t\tVolatility.append(temp_Volatility)\n", | |
"\n", | |
"\t# The returned value is the last value of the volatility series\n", | |
"\treturn [Volatility[len(Volatility) - 1]]" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"[0.0011404647627206502]\n", | |
"[0.0007958705970447617]\n" | |
] | |
} | |
], | |
"source": [ | |
"# Some examples to call the function\n", | |
"Volatility_example_1 = FX_Volatility_2(EURUSD_Close, EURUSD_Time, datetime(2014, 01, 01, 23, 0), datetime(2015, 04, 01, 07, 0))\n", | |
"print Volatility_example_1\n", | |
"\n", | |
"Volatility_example_2 = FX_Volatility_2(USDJPY_Close, USDJPY_Time, datetime(2014, 01, 01, 23, 0), datetime(2015, 04, 23, 23, 0))\n", | |
"print Volatility_example_2" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 2", | |
"language": "python", | |
"name": "python2" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 2 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.6" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment