I wrote a python script to send an email whenever a particular type of VIX reversal indicator triggers. Basically if the following conditions are met, it will send an email:
* If the VIX index has a NEW 15-day high today and closed below the open, then it suggests a buy indicator.
* If the VIX index has a NEW 15-day low today and closed above the open, then it suggests a sell indicator.
I decided to write this in python since I’ve never used it before. It was a fun learning experience. I was a bit taken back by the lack of statement terminators and the indenting rules, but in all I like it better than perl.
This script runs every weekday at 4:15pm (since the yahoo stock quotes are delayed 15 minutes).
Future enhancement ideas are to include the 15-day chart from stockcharts.com as an inline attachment (I have a bash script which already does this so it shouldn’t be that hard to port), as well as proper cleanup & organization of the code once/if I ever learn more python.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | #!/usr/bin/env python import sys import datetime import smtplib import ystockquote from email.mime.text import MIMEText # ticker to look up ticker = '^VIX' # number of days of historical data to fetch (not counting today) days_back = 14 email_from = 'redacted' email_to = 'redacted' # yesterday's date end = datetime.date.today() + datetime.timedelta(days= -1) # 30 days ago from today start = datetime.date.today() + datetime.timedelta(days= -30) # fetch the historical data from yahoo data = ystockquote.get_historical_prices(ticker, start.strftime("%Y%m%d"), end.strftime("%Y%m%d")) # validate that we have enough historical data to continue if len(data) < (days_back + 1): print 'Not enough historical data available to continue (need at least 15 days of market data)' sys.exit(1) current = ystockquote.get_price(ticker) open = ystockquote.get_open(ticker) high = ystockquote.get_high(ticker) low = ystockquote.get_low(ticker) ''' print 'start date is: ' + str(start) print 'end date is: ' + str(end) print 'number of days of actual market data retrieved is: ' + str((len(data) - 1)) print 'Current price: ' + str(current) print 'Open price: ' + str(open) print 'High price: ' + str(high) print 'Low price: ' + str(low) # Loop through the previous 14-days of data (the first item in the data array # is omitted because it is just header information print 'the previous 14-day of historical data:' for i in range(1, (days_back + 1)): print data[i][0] + ': High:' + data[i][2] + ' Low:' + data[i][3] ''' def isNewHigh(high, data): """ Returns True if the 'high' is higher than any of the highs in the data array passed in. Otherwise returns False """ for i in range(1, (days_back + 1)): if float(data[i][2]) >= float(high): return False return True def isNewLow(low, data): """ Returns True if the 'low' is lower than any of the lows in the data array passed in. Otherwise returns False """ for i in range(1, (days_back + 1)): if float(data[i][3]) < = float(low): return False return True def isCurrentHigherThanOpen(current, open): """ Simple check to see if the current price is greater than the open price """ return float(current) > float(open) def isCurrentLowerThanOpen(current, open): """ Simple check to see if the current price is lower than the open price """ return float(current) < float(open) buy = False sell = False # if the current price is higher than the open and today is a new 15-day low, # then this is a SELL indicator if (isCurrentHigherThanOpen(current, open) & isNewLow(low, data)): #print 'today is a 15-day low (' + str(low) + ') & the current price (' + str(current) + ') is higher than the open (' + str(open) + ')' sell = True # if the current price is lower than the open and today is a new 15-day high, # then this is a BUY indicator if (isCurrentLowerThanOpen(current, open) & isNewHigh(high, data)): #print 'today is a 15-day high (' + str(high) + ') & the current price (' + str(current) + ') is lower than the open (' + str(open) + ')' buy = True if (buy | sell): if buy: body = 'Today is a new 15-day high (' + str(high) + ') & the current price (' + str(current) + ') is lower than the open (' + str(open) + ')\n\n====>This is a VIX BUY indicator!' subject = 'VIX BUY indicator triggered' else: body = 'Today is a new 15-day low (' + str(low) + ') & the current price (' + str(current) + ') is higher than the open (' + str(open) + ')\n\n====>This is a VIX SELL indicator!' subject = 'VIX SELL indicator triggered' msg = MIMEText(body) msg['Subject'] = subject msg['From'] = email_from msg['To'] = email_to s = smtplib.SMTP('localhost') s.sendmail(email_from, email_to, msg.as_string()) s.quit() |
I took the ystockquote.py from Corey Goldberg and had to extend it slightly to include some additional information:
* day’s high price
* day’s low price
* last trade time
* last ‘real time’ trade + time (this doesn’t appear to be real time after all)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | #!/usr/bin/env python # # Copyright (c) 2007-2008, Corey Goldberg (corey@goldb.org) # # license: GNU LGPL # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. import urllib """ This is the "ystockquote" module. This module provides a Python API for retrieving stock data from Yahoo Finance. sample usage: >>> import ystockquote >>> print ystockquote.get_price('GOOG') 529.46 """ def __request(symbol, stat): url = 'http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s' % (symbol, stat) return urllib.urlopen(url).read().strip().strip('"') def get_all(symbol): """ Get all available quote data for the given ticker symbol. Returns a dictionary. """ values = __request(symbol, 'l1c1va2xj1b4j4dyekjm3m4rr5p5p6s7oahagat1k1').split(',') data = {} data['price'] = values[0] data['change'] = values[1] data['volume'] = values[2] data['avg_daily_volume'] = values[3] data['stock_exchange'] = values[4] data['market_cap'] = values[5] data['book_value'] = values[6] data['ebitda'] = values[7] data['dividend_per_share'] = values[8] data['dividend_yield'] = values[9] data['earnings_per_share'] = values[10] data['52_week_high'] = values[11] data['52_week_low'] = values[12] data['50day_moving_avg'] = values[13] data['200day_moving_avg'] = values[14] data['price_earnings_ratio'] = values[15] data['price_earnings_growth_ratio'] = values[16] data['price_sales_ratio'] = values[17] data['price_book_ratio'] = values[18] data['short_ratio'] = values[19] data['open'] = values[20] data['days_high'] = values[21] data['days_low'] = values[22] data['last_trade_time'] = values[23] data['last_trade_real_time'] = values[24] return data def get_price(symbol): return __request(symbol, 'l1') def get_change(symbol): return __request(symbol, 'c1') def get_volume(symbol): return __request(symbol, 'v') def get_avg_daily_volume(symbol): return __request(symbol, 'a2') def get_stock_exchange(symbol): return __request(symbol, 'x') def get_market_cap(symbol): return __request(symbol, 'j1') def get_book_value(symbol): return __request(symbol, 'b4') def get_ebitda(symbol): return __request(symbol, 'j4') def get_dividend_per_share(symbol): return __request(symbol, 'd') def get_dividend_yield(symbol): return __request(symbol, 'y') def get_earnings_per_share(symbol): return __request(symbol, 'e') def get_52_week_high(symbol): return __request(symbol, 'k') def get_52_week_low(symbol): return __request(symbol, 'j') def get_50day_moving_avg(symbol): return __request(symbol, 'm3') def get_200day_moving_avg(symbol): return __request(symbol, 'm4') def get_price_earnings_ratio(symbol): return __request(symbol, 'r') def get_price_earnings_growth_ratio(symbol): return __request(symbol, 'r5') def get_price_sales_ratio(symbol): return __request(symbol, 'p5') def get_price_book_ratio(symbol): return __request(symbol, 'p6') def get_short_ratio(symbol): return __request(symbol, 's7') def get_open(symbol): return __request(symbol, 'o') def get_high(symbol): return __request(symbol, 'h') def get_low(symbol): return __request(symbol, 'g') def get_last_trade_time(symbol): return __request(symbol, 't1') def get_last_real_time_trade(symbol): return __request(symbol, 'k1') def get_historical_prices(symbol, start_date, end_date): """ Get historical prices for the given ticker symbol. Date format is 'YYYYMMDD' Returns a nested list. """ url = 'http://ichart.yahoo.com/table.csv?s=%s&' % symbol + \ 'd=%s&' % str(int(end_date[4:6]) - 1) + \ 'e=%s&' % str(int(end_date[6:8])) + \ 'f=%s&' % str(int(end_date[0:4])) + \ 'g=d&' + \ 'a=%s&' % str(int(start_date[4:6]) - 1) + \ 'b=%s&' % str(int(start_date[6:8])) + \ 'c=%s&' % str(int(start_date[0:4])) + \ 'ignore=.csv' days = urllib.urlopen(url).readlines() data = [day[:-2].split(',') for day in days] return data |








0 Response to “vix reversal trigger in python”