├── throbber.gif ├── estudo_help.png ├── estudo_help2.png ├── flot ├── examples │ ├── arrow-down.gif │ ├── arrow-left.gif │ ├── arrow-up.gif │ ├── arrow-right.gif │ ├── data-eu-gdp-growth-1.json │ ├── hs-2004-27-a-large_web.jpg │ ├── layout.css │ ├── data-eu-gdp-growth-2.json │ ├── data-eu-gdp-growth-3.json │ ├── data-eu-gdp-growth-4.json │ ├── data-usa-gdp-growth.json │ ├── data-japan-gdp-growth.json │ ├── data-eu-gdp-growth-5.json │ ├── data-eu-gdp-growth.json │ ├── basic.html │ ├── image.html │ ├── thresholding.html │ ├── index.html │ ├── graph-types.html │ ├── setting-options.html │ ├── stacking.html │ ├── annotating.html │ ├── interacting.html │ ├── tracking.html │ ├── zooming.html │ ├── navigate.html │ ├── turning-series.html │ ├── visitors.html │ ├── ajax.html │ └── selection.html ├── Makefile ├── jquery.flot.threshold.min.js ├── jquery.flot.stack.min.js ├── LICENSE.txt ├── jquery.flot.crosshair.min.js ├── jquery.flot.image.min.js ├── jquery.colorhelpers.min.js ├── README.txt ├── FAQ.txt ├── jquery.flot.selection.min.js ├── PLUGINS.txt ├── jquery.flot.threshold.js ├── jquery.flot.navigate.min.js ├── jquery.flot.crosshair.js ├── jquery.flot.stack.js ├── jquery.colorhelpers.js └── jquery.flot.image.js ├── estudo3d.fshader ├── estudovenda3.php ├── estudo3d.vshader ├── volatimp.sh ├── estudo.css ├── estudolivro.css ├── estudo3.php ├── volatimp_cblc.sh ├── LICENSE ├── volatimp.js ├── taxajuros.py ├── stwatchdog.py ├── estudovenda.py ├── calcvol.py ├── estudo3d.php ├── bs.css ├── glCompat.js ├── estudo3d.wad ├── estudovenda.php ├── estudolivro.php ├── ystockquote.py ├── glUtils.js ├── blackscholes.js ├── estudo.py ├── estudo.js ├── README.txt ├── blackscholes.py ├── estudovenda_common.js └── estudo.php /throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvis-epx/brazilianoptions/HEAD/throbber.gif -------------------------------------------------------------------------------- /estudo_help.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvis-epx/brazilianoptions/HEAD/estudo_help.png -------------------------------------------------------------------------------- /estudo_help2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvis-epx/brazilianoptions/HEAD/estudo_help2.png -------------------------------------------------------------------------------- /flot/examples/arrow-down.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvis-epx/brazilianoptions/HEAD/flot/examples/arrow-down.gif -------------------------------------------------------------------------------- /flot/examples/arrow-left.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvis-epx/brazilianoptions/HEAD/flot/examples/arrow-left.gif -------------------------------------------------------------------------------- /flot/examples/arrow-up.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvis-epx/brazilianoptions/HEAD/flot/examples/arrow-up.gif -------------------------------------------------------------------------------- /flot/examples/arrow-right.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvis-epx/brazilianoptions/HEAD/flot/examples/arrow-right.gif -------------------------------------------------------------------------------- /flot/examples/data-eu-gdp-growth-1.json: -------------------------------------------------------------------------------- 1 | { 2 | label: 'Europe (EU27)', 3 | data: [[1999, 3.0], [2000, 3.9]] 4 | } 5 | -------------------------------------------------------------------------------- /flot/examples/hs-2004-27-a-large_web.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvis-epx/brazilianoptions/HEAD/flot/examples/hs-2004-27-a-large_web.jpg -------------------------------------------------------------------------------- /flot/examples/layout.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: sans-serif; 3 | font-size: 16px; 4 | margin: 50px; 5 | max-width: 800px; 6 | } 7 | -------------------------------------------------------------------------------- /flot/examples/data-eu-gdp-growth-2.json: -------------------------------------------------------------------------------- 1 | { 2 | label: 'Europe (EU27)', 3 | data: [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2]] 4 | } 5 | -------------------------------------------------------------------------------- /flot/examples/data-eu-gdp-growth-3.json: -------------------------------------------------------------------------------- 1 | { 2 | label: 'Europe (EU27)', 3 | data: [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5]] 4 | } 5 | -------------------------------------------------------------------------------- /flot/examples/data-eu-gdp-growth-4.json: -------------------------------------------------------------------------------- 1 | { 2 | label: 'Europe (EU27)', 3 | data: [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1]] 4 | } 5 | -------------------------------------------------------------------------------- /estudo3d.fshader: -------------------------------------------------------------------------------- 1 | #ifdef GL_ES 2 | precision highp float; 3 | #endif 4 | 5 | varying vec4 vColor; 6 | uniform sampler2D uSampler; 7 | 8 | void main(void) 9 | { 10 | gl_FragColor = vColor; 11 | } 12 | -------------------------------------------------------------------------------- /flot/examples/data-usa-gdp-growth.json: -------------------------------------------------------------------------------- 1 | { 2 | label: 'USA', 3 | data: [[1999, 4.4], [2000, 3.7], [2001, 0.8], [2002, 1.6], [2003, 2.5], [2004, 3.6], [2005, 2.9], [2006, 2.8], [2007, 2.0], [2008, 1.1]] 4 | } 5 | -------------------------------------------------------------------------------- /flot/examples/data-japan-gdp-growth.json: -------------------------------------------------------------------------------- 1 | { 2 | label: 'Japan', 3 | data: [[1999, -0.1], [2000, 2.9], [2001, 0.2], [2002, 0.3], [2003, 1.4], [2004, 2.7], [2005, 1.9], [2006, 2.0], [2007, 2.3], [2008, -0.7]] 4 | } 5 | -------------------------------------------------------------------------------- /flot/examples/data-eu-gdp-growth-5.json: -------------------------------------------------------------------------------- 1 | { 2 | label: 'Europe (EU27)', 3 | data: [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1], [2007, 2.9], [2008, 0.9]] 4 | } 5 | -------------------------------------------------------------------------------- /flot/examples/data-eu-gdp-growth.json: -------------------------------------------------------------------------------- 1 | { 2 | label: 'Europe (EU27)', 3 | data: [[1999, 3.0], [2000, 3.9], [2001, 2.0], [2002, 1.2], [2003, 1.3], [2004, 2.5], [2005, 2.0], [2006, 3.1], [2007, 2.9], [2008, 0.9]] 4 | } 5 | -------------------------------------------------------------------------------- /estudovenda3.php: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /estudo3d.vshader: -------------------------------------------------------------------------------- 1 | attribute vec3 aVertexPosition; 2 | attribute vec4 aColor; 3 | varying vec4 vColor; 4 | uniform mat4 uMVMatrix; 5 | uniform mat4 uPMatrix; 6 | 7 | void main(void) 8 | { 9 | gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0); 10 | vColor = aColor; 11 | } 12 | -------------------------------------------------------------------------------- /volatimp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # cd /folder 4 | killall volatimp.py >/dev/null 2>&1 5 | sleep 1 6 | STAMP=$(date '+%Y%m%d%H%M') 7 | if ./volatimp.py .; then 8 | mv -f volatimp.php.new volatimp.php 9 | # cp volatimp.php volatimp.$STAMP.php 10 | mv -f opcoes.txt.new opcoes.txt 11 | # cp opcoes.txt opcoes.txt.$STAMP 12 | fi 13 | -------------------------------------------------------------------------------- /estudo.css: -------------------------------------------------------------------------------- 1 | table#book td { 2 | padding: 0; 3 | } 4 | 5 | table#book span { 6 | padding-left: 1.5em; 7 | font-size: 90%; 8 | font-style: italic; 9 | } 10 | 11 | div#throbber { 12 | padding: 0; 13 | border: 0; 14 | margin: 0; 15 | } 16 | 17 | div#throbber img { 18 | padding: 0; 19 | border: 0; 20 | margin: 0; 21 | } 22 | -------------------------------------------------------------------------------- /estudolivro.css: -------------------------------------------------------------------------------- 1 | table#book td { 2 | padding: 0; 3 | } 4 | 5 | table#book span { 6 | padding-left: 1.5em; 7 | font-size: 90%; 8 | font-style: italic; 9 | } 10 | 11 | div#throbber { 12 | padding: 0; 13 | border: 0; 14 | margin: 0; 15 | } 16 | 17 | div#throbber img { 18 | padding: 0; 19 | border: 0; 20 | margin: 0; 21 | } 22 | -------------------------------------------------------------------------------- /estudo3.php: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /flot/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for generating minified files 2 | 3 | YUICOMPRESSOR_PATH=../yuicompressor-2.3.5.jar 4 | 5 | # if you need another compressor path, just copy the above line to a 6 | # file called Makefile.local, customize it and you're good to go 7 | -include Makefile.local 8 | 9 | .PHONY: all 10 | 11 | # we cheat and process all .js files instead of listing them 12 | all: $(patsubst %.js,%.min.js,$(filter-out %.min.js,$(wildcard *.js))) 13 | 14 | %.min.js: %.js 15 | java -jar $(YUICOMPRESSOR_PATH) $< -o $@ 16 | -------------------------------------------------------------------------------- /volatimp_cblc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # cd /folder 4 | STAMP=$(date '+%Y%m%d') 5 | 6 | # Calculate historical volatility 7 | ./calcvol.py > volatilidades.txt 8 | # cp volatilidades.txt volatilidades.txt.$STAMP 9 | 10 | ./taxajuros.py 11 | # cp taxajuros.txt taxajuros.txt.$STAMP 12 | 13 | # Get options database 14 | rm -f SEDE9999.txt 15 | if wget http://www.cblc.com.br/cblc/consultas/Arquivos/SEDE9999.txt >/dev/null 2>&1; then 16 | mv -f SEDE9999.txt cblc.txt 17 | # cp cblc.txt cblc.txt.$STAMP 18 | else 19 | echo "Could not download option database from CBLC" 20 | fi 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This code can be reused in any fashion, provided the author is mentioned. 2 | Third-party code has been included in this repository; please refer to the 3 | specific licenses. 4 | 5 | Este código pode ser utilizado para quaisquer fins, desde que haja menção do autor. 6 | Código de terceiros está incluído neste repositório; por favor verifique as 7 | condições de licença do mesmo. 8 | 9 | THIRD-PARTY CODE LIST / CODIGO DE TERCEIROS 10 | 11 | flot/ 12 | glCompat.js 13 | glUtils.js 14 | sylvester.js 15 | 16 | Please drop a note if you find any other 3rd-party code not 17 | explicitly listed above. 18 | -------------------------------------------------------------------------------- /volatimp.js: -------------------------------------------------------------------------------- 1 | var calcwin = null; 2 | var sd = null; 3 | 4 | function export_calc(K, spread, S, t, s, r, cost) 5 | { 6 | var tt = new Date(); 7 | tt.setTime(tt.getTime() + t*365*24*60*60*1000); 8 | sd = [K, spread, S, tt, s*100.0, r*100.0, cost]; 9 | if (! calcwin) { 10 | calcwin = window.open("https://epxx.co/ctb/bscalc.php", target="_blank"); 11 | } else { 12 | calc_senddata(); 13 | } 14 | return false; 15 | } 16 | 17 | function calc_senddata() 18 | { 19 | if (calcwin && calcwin.set_defaults && sd) { 20 | calcwin.set_defaults(sd[0], sd[1], sd[2], sd[3], sd[4], sd[5], sd[6], true); 21 | } 22 | sd = null; 23 | } 24 | 25 | function calc_closed() 26 | { 27 | calcwin = null; 28 | sd = null; 29 | } 30 | 31 | function calc_opened() 32 | { 33 | if (sd) { 34 | calc_senddata(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /taxajuros.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import urllib 5 | import sys 6 | import re 7 | 8 | try: 9 | s = urllib.urlopen("http://www.bcb.gov.br/?COPOMJUROS").read() 10 | except: 11 | print "Nao pude ler pagina juros do BCB" 12 | sys.exit(1) 13 | 14 | exp = re.compile("[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9] *- *") 15 | 16 | res = exp.search(s) 17 | 18 | if not res: 19 | print "Nao achei data corrente" 20 | sys.exit(1) 21 | 22 | s = s[res.end(0):res.end(0) + 200] 23 | 24 | exp = re.compile("([0-9]+,[0-9]+) *") 25 | 26 | res = exp.search(s) 27 | 28 | if not res: 29 | print "Nao achei taxa" 30 | sys.exit(1) 31 | 32 | taxa = float(s[res.start(1):res.end(1)].replace(",", ".")) 33 | 34 | if taxa > 30 or taxa < 5: 35 | print "Taxa estranha %f - nao usando" % taxa 36 | sys.exit(1) 37 | 38 | open("taxajuros.txt", "w").write("%f" % taxa) 39 | -------------------------------------------------------------------------------- /flot/jquery.flot.threshold.min.js: -------------------------------------------------------------------------------- 1 | (function(B){var A={series:{threshold:null}};function C(D){function E(L,S,M){if(!S.threshold){return }var F=M.pointsize,I,O,N,G,K,H=B.extend({},S);H.datapoints={points:[],pointsize:F};H.label=null;H.color=S.threshold.color;H.threshold=null;H.originSeries=S;H.data=[];var P=S.threshold.below,Q=M.points,R=S.lines.show;threspoints=[];newpoints=[];for(I=0;I0&&Q[I-F]!=null){var J=(O-Q[I-F])/(N-Q[I-F+1])*(P-N)+O;K.push(J);K.push(P);for(m=2;m0){L.getData().push(H)}}D.hooks.processDatapoints.push(E)}B.plot.plugins.push({init:C,options:A,name:"threshold",version:"1.0"})})(jQuery); -------------------------------------------------------------------------------- /flot/jquery.flot.stack.min.js: -------------------------------------------------------------------------------- 1 | (function(B){var A={series:{stack:null}};function C(F){function D(J,I){var H=null;for(var G=0;G=Y.length){break}U=N.length;if(V>=S.length||S[V]==null||Y[X]==null){for(m=0;ma){if(O&&X>0&&Y[X-T]!=null){I=Q+(Y[X-T+1]-Q)*(a-R)/(Y[X-T]-R);N.push(a);N.push(I+Z);for(m=2;m0&&S[V-T]!=null){M=Z+(S[V-T+1]-Z)*(R-a)/(S[V-T]-a)}N[U+1]+=M;X+=T}}if(U!=N.length&&K){N[U+2]+=M}}if(J&&U!=N.length&&U>0&&N[U]!=null&&N[U]!=N[U-T]&&N[U+1]!=N[U-T+1]){for(m=0;m 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Flot Examples

13 | 14 |
15 | 16 |

Simple example. You don't need to specify much to get an 17 | attractive look. Put in a placeholder, make sure you set its 18 | dimensions (otherwise the plot library will barf) and call the 19 | plot function with the data. The axes are automatically 20 | scaled.

21 | 22 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /flot/jquery.flot.image.min.js: -------------------------------------------------------------------------------- 1 | (function(D){var B={series:{images:{show:false,alpha:1,anchor:"corner"}}};D.plot.image={};D.plot.image.loadDataImages=function(G,F,K){var J=[],H=[];var I=F.series.images.show;D.each(G,function(L,M){if(!(I||M.images.show)){return }if(M.data){M=M.data}D.each(M,function(N,O){if(typeof O[0]=="string"){J.push(O[0]);H.push(O)}})});D.plot.image.load(J,function(L){D.each(H,function(N,O){var M=O[0];if(L[M]){O[0]=L[M]}});K()})};D.plot.image.load=function(H,I){var G=H.length,F={};if(G==0){I({})}D.each(H,function(K,J){var L=function(){--G;F[J]=this;if(G==0){I(F)}};D("").load(L).error(L).attr("src",J)})};function A(H,F){var G=H.getPlotOffset();D.each(H.getData(),function(O,P){var X=P.datapoints.points,I=P.datapoints.pointsize;for(var O=0;OK){N=K;K=M;M=N}if(V>T){N=T;T=V;V=N}if(P.images.anchor=="center"){N=0.5*(K-M)/(Q.width-1);M-=N;K+=N;N=0.5*(T-V)/(Q.height-1);V-=N;T+=N}if(M==K||V==T||M>=W.max||K<=W.min||V>=S.max||T<=S.min){continue}var L=0,U=0,J=Q.width,R=Q.height;if(MW.max){J+=(J-L)*(W.max-K)/(K-M);K=W.max}if(VS.max){U+=(U-R)*(S.max-T)/(T-V);T=S.max}M=W.p2c(M);K=W.p2c(K);V=S.p2c(V);T=S.p2c(T);if(M>K){N=K;K=M;M=N}if(V>T){N=T;T=V;V=N}N=F.globalAlpha;F.globalAlpha*=P.images.alpha;F.drawImage(Q,L,U,J-L,R-U,M+G.left,V+G.top,K-M,T-V);F.globalAlpha=N}})}function C(I,F,G,H){if(!F.images.show){return }H.format=[{required:true},{x:true,number:true,required:true},{y:true,number:true,required:true},{x:true,number:true,required:true},{y:true,number:true,required:true}]}function E(F){F.hooks.processRawData.push(C);F.hooks.draw.push(A)}D.plot.plugins.push({init:E,options:B,name:"image",version:"1.1"})})(jQuery); -------------------------------------------------------------------------------- /flot/examples/image.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Flot Examples

14 | 15 |
16 | 17 |

The Cat's Eye Nebula (picture from Hubble).

18 | 19 |

With the image plugin, you can plot images. This is for example 20 | useful for getting ticks on complex prerendered visualizations. 21 | Instead of inputting data points, you put in the images and where 22 | their two opposite corners are supposed to be in plot space.

23 | 24 |

Images represent a little further complication because you need 25 | to make sure they are loaded before you can use them (Flot skips 26 | incomplete images). The plugin comes with a couple of helpers 27 | for doing that.

28 | 29 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /flot/examples/thresholding.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Flot Examples

14 | 15 |
16 | 17 |

With the threshold plugin, you can apply a specific color to 18 | the part of a data series below a threshold. This is can be useful 19 | for highlighting negative values, e.g. when displaying net results 20 | or what's in stock.

21 | 22 |

23 | 24 | 25 | 26 |

27 | 28 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /stwatchdog.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | import ystockquote 5 | import smtplib 6 | import time 7 | import email 8 | from email.mime.text import MIMEText 9 | 10 | # TODO: detect and notify problems in Yahoo 11 | # TODO: keep tickets and ranges in separate file, detect change 12 | 13 | UNKNOWN = 0 14 | BETWEEN = 1 15 | ABOVE = 2 16 | BELOW = 3 17 | 18 | SECONDS = 1 19 | MINUTES = 60*SECONDS 20 | HOURS = 60*MINUTES 21 | DAYS = 24*HOURS 22 | 23 | symbols = {"PETR4.SA": [39.40, 41.40]} 24 | status = {} 25 | 26 | for symbol in symbols.keys(): 27 | status[symbol] = UNKNOWN 28 | 29 | FROM = "email@email.com" 30 | TO = ["email@email.com"] 31 | 32 | def send_warning(txt): 33 | print " Sending message: ", txt 34 | 35 | msg = MIMEText('$') 36 | msg['Subject'] = txt 37 | msg['From'] = FROM 38 | msg['To'] = ", ".join(TO) 39 | 40 | try: 41 | server = smtplib.SMTP("localhost") 42 | server.sendmail(FROM, TO, msg.as_string()) 43 | server.quit() 44 | print " Message sent" 45 | except Exception, e: 46 | print " Message not sent" 47 | print " ", e 48 | 49 | def handle_symbol(symbol, low, high): 50 | try: 51 | current = float(ystockquote.get_price(symbol)) 52 | except Exception, e: 53 | print e 54 | current = 0.00 55 | 56 | if current <= 0.00: 57 | return 58 | 59 | print "Symbol %s = %.2f" % (symbol, current) 60 | 61 | if (current <= low) and (status[symbol] != BELOW): 62 | status[symbol] = BELOW 63 | send_warning("%s down to %.2f" % (symbol, current)) 64 | elif (current >= high) and (status[symbol] != ABOVE): 65 | status[symbol] = ABOVE 66 | send_warning("%s up to %.2f" % (symbol, current)) 67 | 68 | 69 | print "Starting" 70 | send_warning("Watchdog up") 71 | uptime = 0 72 | freq = 15 * MINUTES 73 | 74 | # we die at 23:00 to be resurrected at 00:00 75 | while time.localtime(time.time())[3] != 23: 76 | print "Ping", time.ctime(time.time()) 77 | for symbol in symbols.keys(): 78 | handle_symbol(symbol, *symbols[symbol]) 79 | time.sleep(freq) 80 | uptime += freq 81 | now = time.gmtime(time.time()) 82 | if uptime > 24 * HOURS and now[3] >= 15 and now[6] <= 4: 83 | uptime = 0 84 | send_warning("Watchdog ping") 85 | -------------------------------------------------------------------------------- /flot/examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Flot Examples

13 | 14 |

Here are some examples for Flot, the Javascript charting library for jQuery:

15 | 16 | 22 | 23 |

Being interactive:

24 | 25 | 31 | 32 |

Some more esoteric features:

33 | 34 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /flot/examples/graph-types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Flot Examples

13 | 14 |
15 | 16 |

Flot supports lines, points, filled areas, bars and any 17 | combinations of these, in the same plot and even on the same data 18 | series.

19 | 20 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /flot/examples/setting-options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Flot Examples

13 | 14 |
15 | 16 |

There are plenty of options you can set to control the precise 17 | looks of your plot. You can control the axes, the legend, the 18 | default graph type, the look of grid, etc.

19 | 20 |

The idea is that Flot goes to great lengths to provide sensible 21 | defaults which you can then customize as needed for your 22 | particular application. If you've found a use case where the 23 | defaults can be improved, please don't hesitate to give your 24 | feedback.

25 | 26 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /estudovenda.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import math 4 | from blackscholes import * 5 | 6 | debug = False 7 | 8 | def lista_opcoes(): 9 | mapa = {} 10 | S = 50.00 11 | r = 0.09 12 | s = 0.30 13 | acao = "XPTO" 14 | 15 | for K in range(-2, +4, +2): 16 | K += S 17 | # data-base: 18/3. Venctos: 19/4 e 17/5 18 | for serie, t in [("D", 32), ("E", 60), ("O", 32), ("P", 60)]: 19 | tipo = serie >= "M" and 2 or 1 20 | tk = acao + serie + ("%2d" % K) 21 | mapa[tk] = [tk, tipo, None, S, K, r, s, t / 365.0] 22 | 23 | return mapa 24 | 25 | 26 | def classify(papel, dados): 27 | # codigo, tipo, premium, S, K, r, s, t, delta, gama, theta, vega, prob 28 | # dados[1] = int(dados[1]) 29 | # for i in range(2, len(dados)): 30 | # dados[i] = float(dados[i]) 31 | obj = Opcao(papel, dados[1], dados[2:8]) 32 | return obj 33 | 34 | 35 | def classify_map(mapa): 36 | for papel in mapa.keys(): 37 | mapa[papel] = classify(papel, mapa[papel]) 38 | 39 | 40 | def nome_acao(opcao): 41 | # nome falso para a acao 42 | return opcao[0:4]+"Z00" 43 | 44 | 45 | def cria_acao_subjacente(nome, opcao): 46 | # modela acao subjacente como se fosse uma opcao de compra com K=0 47 | # premium, S, K, r, s, t 48 | dados = [opcao.S_orig(), opcao.S_orig(), 0, opcao.r(), 0, 9999] 49 | acao = Opcao(nome, 1, dados) 50 | return acao 51 | 52 | 53 | def cria_acoes_subjacentes(mapa): 54 | for papel in mapa.keys(): 55 | acao = nome_acao(papel) 56 | if acao not in mapa.keys(): 57 | mapa[acao] = cria_acao_subjacente(acao, mapa[papel]) 58 | 59 | def Ditems(): 60 | global debug 61 | debug = True 62 | return items() 63 | 64 | def items(): 65 | result = {} 66 | mapa = lista_opcoes() 67 | classify_map(mapa) 68 | cria_acoes_subjacentes(mapa) 69 | lista = mapa.keys() 70 | lista.sort() 71 | 72 | for papel in lista: 73 | if len(papel) != 7: 74 | continue 75 | acao = papel[0:4] 76 | serie = papel[4] 77 | strike = papel[5:7] 78 | opcao = mapa[papel] 79 | if not result.has_key(acao): 80 | result[acao] = {} 81 | if not result[acao].has_key(serie): 82 | result[acao][serie] = {} 83 | result[acao][serie]["data"] = {} 84 | result[acao][serie]["default_strike"] = strike 85 | result[acao][serie]["strike_value"] = 99999999999.0 86 | result[acao][serie]["data"][strike] = opcao.dvc() 87 | if opcao.S_orig() < opcao.K(): 88 | if opcao.K() < result[acao][serie]["strike_value"]: 89 | result[acao][serie]["default_strike"] = strike 90 | result[acao][serie]["strike_value"] = opcao.K() 91 | 92 | return result 93 | 94 | print items() 95 | -------------------------------------------------------------------------------- /flot/examples/stacking.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Flot Examples

14 | 15 |
16 | 17 |

With the stack plugin, you can have Flot stack the 18 | series. This is useful if you wish to display both a total and the 19 | constituents it is made of. The only requirement is that you provide 20 | the input sorted on x.

21 | 22 |

23 | 24 | 25 |

26 | 27 |

28 | 29 | 30 | 31 |

32 | 33 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /flot/jquery.colorhelpers.min.js: -------------------------------------------------------------------------------- 1 | (function(){jQuery.color={};jQuery.color.make=function(E,D,B,C){var F={};F.r=E||0;F.g=D||0;F.b=B||0;F.a=C!=null?C:1;F.add=function(I,H){for(var G=0;G=1){return"rgb("+[F.r,F.g,F.b].join(",")+")"}else{return"rgba("+[F.r,F.g,F.b,F.a].join(",")+")"}};F.normalize=function(){function G(I,J,H){return JH?H:J)}F.r=G(0,parseInt(F.r),255);F.g=G(0,parseInt(F.g),255);F.b=G(0,parseInt(F.b),255);F.a=G(0,F.a,1);return F};F.clone=function(){return jQuery.color.make(F.r,F.b,F.g,F.a)};return F.normalize()};jQuery.color.extract=function(C,B){var D;do{D=C.css(B).toLowerCase();if(D!=""&&D!="transparent"){break}C=C.parent()}while(!jQuery.nodeName(C.get(0),"body"));if(D=="rgba(0, 0, 0, 0)"){D="transparent"}return jQuery.color.parse(D)};jQuery.color.parse=function(E){var D,B=jQuery.color.make;if(D=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(E)){return B(parseInt(D[1],10),parseInt(D[2],10),parseInt(D[3],10))}if(D=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(E)){return B(parseInt(D[1],10),parseInt(D[2],10),parseInt(D[3],10),parseFloat(D[4]))}if(D=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(E)){return B(parseFloat(D[1])*2.55,parseFloat(D[2])*2.55,parseFloat(D[3])*2.55)}if(D=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(E)){return B(parseFloat(D[1])*2.55,parseFloat(D[2])*2.55,parseFloat(D[3])*2.55,parseFloat(D[4]))}if(D=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(E)){return B(parseInt(D[1],16),parseInt(D[2],16),parseInt(D[3],16))}if(D=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(E)){return B(parseInt(D[1]+D[1],16),parseInt(D[2]+D[2],16),parseInt(D[3]+D[3],16))}var C=jQuery.trim(E).toLowerCase();if(C=="transparent"){return B(255,255,255,0)}else{D=A[C];return B(D[0],D[1],D[2])}};var A={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(); -------------------------------------------------------------------------------- /calcvol.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import ystockquote 5 | import datetime 6 | import math 7 | import time 8 | 9 | symbols = ["VALE5", "PETR4", "OIBR4", "BVMF3", "OGXP3"] 10 | now = datetime.date.today() - datetime.timedelta(1) 11 | then = now - datetime.timedelta(75) 12 | now = "%04d%02d%02d" % (now.year, now.month, now.day) 13 | then = "%04d%02d%02d" % (then.year, then.month, then.day) 14 | 15 | def average(li): 16 | return sum(li) / len(li) 17 | 18 | for symbol in symbols: 19 | for retries in range(1, 5): 20 | book = ystockquote.get_historical_prices(symbol+".SA", then, now) 21 | 22 | # Detect vectors of interesting columns 23 | try: 24 | High = book[0].index('High') 25 | Low = book[0].index('Low') 26 | Close = book[0].index('Close') 27 | Volume = book[0].index('Volume') 28 | break 29 | except ValueError: 30 | pass 31 | time.sleep(retries) 32 | else: 33 | continue 34 | 35 | 36 | # Remove header 37 | del book[0] 38 | 39 | # removes all days with zero volume 40 | while True: 41 | for row in book: 42 | if int(row[Volume]) <= 0: 43 | book.remove(row) 44 | # List iterator invalidated, restart 45 | break 46 | else: 47 | # no removal, task done 48 | break 49 | 50 | # Sort by date, ascendng 51 | book.sort(lambda a, b: cmp(a[0], b[0])) 52 | 53 | # Leaves 22 latest rows 54 | del book[0:-22] 55 | 56 | highest = 0.01 57 | lowest = 99999999999999999.0 58 | earnings = [] 59 | earnings2 = [] 60 | 61 | for i in range(1, len(book)): 62 | day_high = float(book[i][High]) 63 | day_low = float(book[i][Low]) 64 | day_close = float(book[i][Close]) 65 | day_ant_close = float(book[i-1][Close]) 66 | 67 | highest = max(highest, day_high) 68 | lowest = min(lowest, day_low) 69 | day_earnings = math.log(day_close / day_ant_close) 70 | earnings.append(day_earnings) 71 | earnings2.append(day_earnings ** 2) 72 | 73 | n = len(earnings) 74 | 75 | earnings_average = average(earnings) 76 | earnings2_average = average(earnings2) 77 | 78 | if n <= 1: 79 | continue 80 | 81 | # Volatily calculated as the standard deviation of earnings 82 | vol1 = math.sqrt(n * (earnings2_average - earnings_average ** 2) / (n - 1)) 83 | vol1 *= math.sqrt(252) 84 | 85 | # Double-check of standard deviation calculation 86 | vol11 = math.sqrt(sum((earning - earnings_average) ** 2 for earning in earnings) / (n - 1)) 87 | vol11 *= math.sqrt(252) 88 | 89 | if abs(vol1 - vol11) > 0.0001: 90 | continue 91 | 92 | # Volatility calculated by the extreme value method 93 | vol2 = math.log(highest / lowest) * 0.601 94 | vol2 *= math.sqrt(12.0) 95 | 96 | print "%s %.2f %.2f" % (symbol, vol1*100, vol2*100) 97 | 98 | -------------------------------------------------------------------------------- /flot/README.txt: -------------------------------------------------------------------------------- 1 | About 2 | ----- 3 | 4 | Flot is a Javascript plotting library for jQuery. Read more at the 5 | website: 6 | 7 | http://code.google.com/p/flot/ 8 | 9 | Take a look at the examples linked from above, they should give a good 10 | impression of what Flot can do and the source code of the examples is 11 | probably the fastest way to learn how to use Flot. 12 | 13 | 14 | Installation 15 | ------------ 16 | 17 | Just include the Javascript file after you've included jQuery. 18 | 19 | Note that you need to get a version of Excanvas (e.g. the one bundled 20 | with Flot) which is canvas emulation on Internet Explorer. You can 21 | include the excanvas script like this: 22 | 23 | 24 | 25 | If it's not working on your development IE 6.0, check that it has 26 | support for VML which excanvas is relying on. It appears that some 27 | stripped down versions used for test environments on virtual machines 28 | lack the VML support. 29 | 30 | Also note that you need at least jQuery 1.2.6 (but at least jQuery 31 | 1.3.2 is recommended for interactive charts because of performance 32 | improvements in event handling). 33 | 34 | 35 | Basic usage 36 | ----------- 37 | 38 | Create a placeholder div to put the graph in: 39 | 40 |
41 | 42 | You need to set the width and height of this div, otherwise the plot 43 | library doesn't know how to scale the graph. You can do it inline like 44 | this: 45 | 46 |
47 | 48 | You can also do it with an external stylesheet. Make sure that the 49 | placeholder isn't within something with a display:none CSS property - 50 | in that case, Flot has trouble measuring label dimensions which 51 | results in garbled looks and might have trouble measuring the 52 | placeholder dimensions which is fatal (it'll throw an exception). 53 | 54 | Then when the div is ready in the DOM, which is usually on document 55 | ready, run the plot function: 56 | 57 | $.plot($("#placeholder"), data, options); 58 | 59 | Here, data is an array of data series and options is an object with 60 | settings if you want to customize the plot. Take a look at the 61 | examples for some ideas of what to put in or look at the reference 62 | in the file "API.txt". Here's a quick example that'll draw a line from 63 | (0, 0) to (1, 1): 64 | 65 | $.plot($("#placeholder"), [ [[0, 0], [1, 1]] ], { yaxis: { max: 1 } }); 66 | 67 | The plot function immediately draws the chart and then returns a plot 68 | object with a couple of methods. 69 | 70 | 71 | What's with the name? 72 | --------------------- 73 | 74 | First: it's pronounced with a short o, like "plot". Not like "flawed". 75 | 76 | So "Flot" rhymes with "plot". 77 | 78 | And if you look up "flot" in a Danish-to-English dictionary, some up 79 | the words that come up are "good-looking", "attractive", "stylish", 80 | "smart", "impressive", "extravagant". One of the main goals with Flot 81 | is pretty looks. 82 | -------------------------------------------------------------------------------- /estudo3d.php: -------------------------------------------------------------------------------- 1 | 2 | '); ?> 3 | 4 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 |
--
36 |
37 | throbber 38 |
39 |
--
--
--
58 |
59 | 60 |
61 | 62 | 63 |
64 | Choose a non-zero quantity for at least one option, at rightmost combo, 65 | in order to plot the graph. 66 | Use the arrows and PgUp/PgDn to navigate. The 3D code is based on 67 | "Learning WebGL" examples at 68 | http://learningwebgl.com/blog/. 69 | 70 | 71 | -------------------------------------------------------------------------------- /flot/examples/annotating.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Flot Examples

13 | 14 |
15 | 16 |

Flot has support for simple background decorations such as 17 | lines and rectangles. They can be useful for marking up certain 18 | areas. You can easily add any HTML you need with standard DOM 19 | manipulation, e.g. for labels. For drawing custom shapes there is 20 | also direct access to the canvas.

21 | 22 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /flot/FAQ.txt: -------------------------------------------------------------------------------- 1 | Frequently asked questions 2 | -------------------------- 3 | 4 | Q: How much data can Flot cope with? 5 | 6 | A: Flot will happily draw everything you send to it so the answer 7 | depends on the browser. The excanvas emulation used for IE (built with 8 | VML) makes IE by far the slowest browser so be sure to test with that 9 | if IE users are in your target group. 10 | 11 | 1000 points is not a problem, but as soon as you start having more 12 | points than the pixel width, you should probably start thinking about 13 | downsampling/aggregation as this is near the resolution limit of the 14 | chart anyway. If you downsample server-side, you also save bandwidth. 15 | 16 | 17 | Q: Flot isn't working when I'm using JSON data as source! 18 | 19 | A: Actually, Flot loves JSON data, you just got the format wrong. 20 | Double check that you're not inputting strings instead of numbers, 21 | like [["0", "-2.13"], ["5", "4.3"]]. This is most common mistake, and 22 | the error might not show up immediately because Javascript can do some 23 | conversion automatically. 24 | 25 | 26 | Q: Can I export the graph? 27 | 28 | A: This is a limitation of the canvas technology. There's a hook in 29 | the canvas object for getting an image out, but you won't get the tick 30 | labels. And it's not likely to be supported by IE. At this point, your 31 | best bet is probably taking a screenshot, e.g. with PrtScn. 32 | 33 | 34 | Q: The bars are all tiny in time mode? 35 | 36 | A: It's not really possible to determine the bar width automatically. 37 | So you have to set the width with the barWidth option which is NOT in 38 | pixels, but in the units of the x axis (or the y axis for horizontal 39 | bars). For time mode that's milliseconds so the default value of 1 40 | makes the bars 1 millisecond wide. 41 | 42 | 43 | Q: Can I use Flot with libraries like Mootools or Prototype? 44 | 45 | A: Yes, Flot supports it out of the box and it's easy! Just use jQuery 46 | instead of $, e.g. call jQuery.plot instead of $.plot and use 47 | jQuery(something) instead of $(something). As a convenience, you can 48 | put in a DOM element for the graph placeholder where the examples and 49 | the API documentation are using jQuery objects. 50 | 51 | Depending on how you include jQuery, you may have to add one line of 52 | code to prevent jQuery from overwriting functions from the other 53 | libraries, see the documentation in jQuery ("Using jQuery with other 54 | libraries") for details. 55 | 56 | 57 | Q: Flot doesn't work with [widget framework xyz]! 58 | 59 | A: The problem is most likely within the framework, or your use of the 60 | framework. 61 | 62 | The only non-standard thing used by Flot is the canvas tag; otherwise 63 | it is simply a series of absolute positioned divs within the 64 | placeholder tag you put in. If this is not working, it's probably 65 | because the framework you're using is doing something weird with the 66 | DOM. As a last resort, you might try replotting and see if it helps. 67 | 68 | If you find there's a specific thing we can do to Flot to help, feel 69 | free to submit a bug report. Otherwise, you're welcome to ask for help 70 | on the mailing list, but please don't submit a bug report to Flot - 71 | try the framework instead. 72 | -------------------------------------------------------------------------------- /bs.css: -------------------------------------------------------------------------------- 1 | .fincalc fieldset 2 | { 3 | border: 1px solid #781351; 4 | } 5 | 6 | .fincalc table { 7 | margin-left : 0; 8 | border-width: 0px; 9 | } 10 | 11 | .fincalc td { 12 | padding-right : 3px; 13 | padding-bottom : 3px; 14 | text-align: left; 15 | } 16 | 17 | .fincalc table.spread { 18 | border-width: 0px; 19 | border-style: solid; 20 | border-collapse: collapse; 21 | } 22 | 23 | .fincalc table.spread td { 24 | border-width: 1px; 25 | border-color: #000; 26 | padding: 3px; 27 | border-style: solid; 28 | text-align: right; 29 | width: 6em; 30 | } 31 | 32 | .fincalc table.spread th { 33 | border-width: 1px; 34 | border-color: #000; 35 | padding: 3px; 36 | border-style: solid; 37 | text-align: right; 38 | width: 6em; 39 | } 40 | 41 | .fincalc table.book { 42 | border-width: 0px; 43 | border-style: solid; 44 | border-collapse: collapse; 45 | } 46 | 47 | .fincalc table.book td { 48 | border-width: 1px; 49 | padding: 3px; 50 | border-style: solid; 51 | border-color: #000; 52 | text-align: right; 53 | width: 5em; 54 | } 55 | 56 | .fincalc table.book th { 57 | border-width: 1px; 58 | padding: 3px; 59 | border-style: solid; 60 | border-color: #000; 61 | text-align: right; 62 | width: 5em; 63 | } 64 | 65 | .fincalc table.book tr.atm { 66 | background-color: #FFFFD0; 67 | } 68 | 69 | .fincalc table.book tr.itm { 70 | background-color: #F0F0FF; 71 | } 72 | 73 | .fincalc table.book tr.otm { 74 | background-color: #FFFFFF; 75 | } 76 | 77 | .fincalc table.book th.premium { 78 | color: #0A0; 79 | } 80 | 81 | .fincalc table.book th.intrinsic { 82 | color: #F00; 83 | } 84 | 85 | .fincalc table.book th.intrinseco { 86 | color: #EE0; 87 | } 88 | 89 | .fincalc table.book th.delta { 90 | color: #00F; 91 | } 92 | 93 | .fincalc table.book th.gamma { 94 | color: #0CC; 95 | } 96 | 97 | .fincalc table.book th.theta { 98 | color: #F0F; 99 | } 100 | 101 | .fincalc table.book th.vega { 102 | color: #F80; 103 | } 104 | 105 | .fincalc table.book th.rho { 106 | color: #880; 107 | } 108 | 109 | .fincalc table.covered { 110 | border-width: 0px; 111 | border-style: solid; 112 | border-collapse: collapse; 113 | } 114 | 115 | .fincalc table.covered td { 116 | border-width: 1px; 117 | padding: 3px; 118 | border-color: #000; 119 | border-style: solid; 120 | text-align: right; 121 | width: 7em; 122 | } 123 | 124 | .fincalc table.covered th { 125 | border-width: 1px; 126 | padding: 3px; 127 | border-style: solid; 128 | border-color: #000; 129 | text-align: right; 130 | width: 7em; 131 | } 132 | 133 | .fincalc legend 134 | { 135 | color: #fff; 136 | background: #ffa20c; 137 | border: 1px solid #781351; 138 | padding: 2px 6px 139 | } 140 | 141 | .fincalc input 142 | { 143 | text-align: right; 144 | border: 1px solid #999999; 145 | font-weight: bold; 146 | padding: 4px; 147 | } 148 | 149 | .mybutton { 150 | width: 5em; 151 | background-color: #E9E9E9; 152 | height: 2em; 153 | font-weight: bold; 154 | } 155 | 156 | .mybutton_0 { 157 | width: 5em; 158 | background-color: #E9E9E9; 159 | height: 2em; 160 | font-weight: bold; 161 | } 162 | 163 | .mybutton_1 { 164 | width: 5em; 165 | background-color: #FFFF00; 166 | height: 2em; 167 | font-weight: bold; 168 | } 169 | 170 | .blueform 171 | { 172 | background-color: #B0FFFF; 173 | } 174 | 175 | .yellowform 176 | { 177 | background-color: #FFFFA9; 178 | } 179 | -------------------------------------------------------------------------------- /flot/jquery.flot.selection.min.js: -------------------------------------------------------------------------------- 1 | (function(A){function B(J){var O={first:{x:-1,y:-1},second:{x:-1,y:-1},show:false,active:false};var L={};function D(Q){if(O.active){J.getPlaceholder().trigger("plotselecting",[F()]);K(Q)}}function M(Q){if(Q.which!=1){return }document.body.focus();if(document.onselectstart!==undefined&&L.onselectstart==null){L.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!==undefined&&L.ondrag==null){L.ondrag=document.ondrag;document.ondrag=function(){return false}}C(O.first,Q);O.active=true;A(document).one("mouseup",I)}function I(Q){if(document.onselectstart!==undefined){document.onselectstart=L.onselectstart}if(document.ondrag!==undefined){document.ondrag=L.ondrag}O.active=false;K(Q);if(E()){H()}else{J.getPlaceholder().trigger("plotunselected",[]);J.getPlaceholder().trigger("plotselecting",[null])}return false}function F(){if(!E()){return null}var R=Math.min(O.first.x,O.second.x),Q=Math.max(O.first.x,O.second.x),T=Math.max(O.first.y,O.second.y),S=Math.min(O.first.y,O.second.y);var U={};var V=J.getAxes();if(V.xaxis.used){U.xaxis={from:V.xaxis.c2p(R),to:V.xaxis.c2p(Q)}}if(V.x2axis.used){U.x2axis={from:V.x2axis.c2p(R),to:V.x2axis.c2p(Q)}}if(V.yaxis.used){U.yaxis={from:V.yaxis.c2p(T),to:V.yaxis.c2p(S)}}if(V.y2axis.used){U.y2axis={from:V.y2axis.c2p(T),to:V.y2axis.c2p(S)}}return U}function H(){var Q=F();J.getPlaceholder().trigger("plotselected",[Q]);var R=J.getAxes();if(R.xaxis.used&&R.yaxis.used){J.getPlaceholder().trigger("selected",[{x1:Q.xaxis.from,y1:Q.yaxis.from,x2:Q.xaxis.to,y2:Q.yaxis.to}])}}function G(R,S,Q){return SQ?Q:S)}function C(U,R){var T=J.getOptions();var S=J.getPlaceholder().offset();var Q=J.getPlotOffset();U.x=G(0,R.pageX-S.left-Q.left,J.width());U.y=G(0,R.pageY-S.top-Q.top,J.height());if(T.selection.mode=="y"){U.x=U==O.first?0:J.width()}if(T.selection.mode=="x"){U.y=U==O.first?0:J.height()}}function K(Q){if(Q.pageX==null){return }C(O.second,Q);if(E()){O.show=true;J.triggerRedrawOverlay()}else{P(true)}}function P(Q){if(O.show){O.show=false;J.triggerRedrawOverlay();if(!Q){J.getPlaceholder().trigger("plotunselected",[])}}}function N(R,Q){var T,S,U=J.getAxes();var V=J.getOptions();if(V.selection.mode=="y"){O.first.x=0;O.second.x=J.width()}else{T=R.xaxis?U.xaxis:(R.x2axis?U.x2axis:U.xaxis);S=R.xaxis||R.x2axis||{from:R.x1,to:R.x2};O.first.x=T.p2c(Math.min(S.from,S.to));O.second.x=T.p2c(Math.max(S.from,S.to))}if(V.selection.mode=="x"){O.first.y=0;O.second.y=J.height()}else{T=R.yaxis?U.yaxis:(R.y2axis?U.y2axis:U.yaxis);S=R.yaxis||R.y2axis||{from:R.y1,to:R.y2};O.first.y=T.p2c(Math.min(S.from,S.to));O.second.y=T.p2c(Math.max(S.from,S.to))}O.show=true;J.triggerRedrawOverlay();if(!Q){H()}}function E(){var Q=5;return Math.abs(O.second.x-O.first.x)>=Q&&Math.abs(O.second.y-O.first.y)>=Q}J.clearSelection=P;J.setSelection=N;J.getSelection=F;J.hooks.bindEvents.push(function(R,Q){var S=R.getOptions();if(S.selection.mode!=null){Q.mousemove(D)}if(S.selection.mode!=null){Q.mousedown(M)}});J.hooks.drawOverlay.push(function(T,Y){if(O.show&&E()){var R=T.getPlotOffset();var Q=T.getOptions();Y.save();Y.translate(R.left,R.top);var U=A.color.parse(Q.selection.color);Y.strokeStyle=U.scale("a",0.8).toString();Y.lineWidth=1;Y.lineJoin="round";Y.fillStyle=U.scale("a",0.4).toString();var W=Math.min(O.first.x,O.second.x),V=Math.min(O.first.y,O.second.y),X=Math.abs(O.second.x-O.first.x),S=Math.abs(O.second.y-O.first.y);Y.fillRect(W,V,X,S);Y.strokeRect(W,V,X,S);Y.restore()}})}A.plot.plugins.push({init:B,options:{selection:{mode:null,color:"#e8cfac"}},name:"selection",version:"1.0"})})(jQuery); -------------------------------------------------------------------------------- /glCompat.js: -------------------------------------------------------------------------------- 1 | // Code based on "WebGL Lessons", http://learningwebgl.com 2 | 3 | 4 | var gl; 5 | 6 | function initGL() 7 | { 8 | var canvas = document.getElementById("arena"); 9 | 10 | try { 11 | gl = canvas.getContext("webkit-3d"); 12 | } catch (e) { 13 | // pass 14 | } 15 | 16 | if (!gl) { 17 | try { 18 | gl = canvas.getContext("experimental-webgl"); 19 | } catch (e) { 20 | // pass 21 | } 22 | } 23 | 24 | if (!gl) { 25 | try { 26 | gl = canvas.getContext("moz-webgl"); 27 | } catch (e) { 28 | // pass 29 | } 30 | } 31 | 32 | if (!gl) { 33 | alert("Could not initialise WebGL, sorry :-("); 34 | return; 35 | } 36 | 37 | // This temporary code provides support for Google Chrome, which 38 | // as of 30 Nov 2009 does not support the new names for the 39 | // functions to get shader/program parameters (among other things). 40 | // It should be unnecessary soon, and is only a partial fix 41 | // in the meantime (as, for example, there's no way to get shader 42 | // or program parameters that are vectors of integers). 43 | // See http://learningwebgl.com/blog/?p=1082 for details. 44 | if (!gl.getProgramParameter) { 45 | gl.getProgramParameter = gl.getProgrami 46 | } 47 | if (!gl.getShaderParameter) { 48 | gl.getShaderParameter = gl.getShaderi 49 | } 50 | // End of Chrome compatibility code 51 | } 52 | 53 | var mvMatrix; 54 | var mvMatrixStack = []; 55 | 56 | function mvPushMatrix(m) 57 | { 58 | if (m) { 59 | mvMatrixStack.push(m.dup()); 60 | mvMatrix = m.dup(); 61 | } else { 62 | mvMatrixStack.push(mvMatrix.dup()); 63 | } 64 | } 65 | 66 | function mvPopMatrix() 67 | { 68 | if (mvMatrixStack.length == 0) 69 | throw "Invalid popMatrix!"; 70 | mvMatrix = mvMatrixStack.pop(); 71 | return mvMatrix; 72 | } 73 | 74 | function loadIdentity() 75 | { 76 | mvMatrix = Matrix.I(4); 77 | } 78 | 79 | function multMatrix(m) 80 | { 81 | mvMatrix = mvMatrix.x(m); 82 | } 83 | 84 | function mvTranslate(v) 85 | { 86 | var m = Matrix.Translation($V([v[0], v[1], v[2]])).ensure4x4(); 87 | multMatrix(m); 88 | } 89 | 90 | function mvRotate(ang, v) 91 | { 92 | var arad = ang * Math.PI / 180.0; 93 | var m = Matrix.Rotation(arad, $V([v[0], v[1], v[2]])).ensure4x4(); 94 | multMatrix(m); 95 | } 96 | 97 | var pMatrix; 98 | 99 | function perspective(fovy, aspect, znear, zfar) 100 | { 101 | pMatrix = makePerspective(fovy, aspect, znear, zfar) 102 | } 103 | 104 | function getShader(gl, id) 105 | { 106 | var str = ""; 107 | 108 | var shader; 109 | 110 | if (id == "fshader") { 111 | shader = gl.createShader(gl.FRAGMENT_SHADER); 112 | } else if (id == "vshader") { 113 | shader = gl.createShader(gl.VERTEX_SHADER); 114 | } else { 115 | return null; 116 | } 117 | 118 | var request = new XMLHttpRequest(); 119 | request.open("GET", "estudo3d." + id, false); 120 | request.send(); 121 | str = request.responseText; 122 | 123 | gl.shaderSource(shader, str); 124 | gl.compileShader(shader); 125 | 126 | if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { 127 | alert(gl.getShaderInfoLog(shader)); 128 | return null; 129 | } 130 | 131 | return shader; 132 | } 133 | 134 | -------------------------------------------------------------------------------- /flot/examples/interacting.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Flot Examples

13 | 14 |
15 | 16 |

One of the goals of Flot is to support user interactions. Try 17 | pointing and clicking on the points.

18 | 19 |

Mouse hovers at 20 | (0, 0).

21 | 22 |

A tooltip is easy to build with a bit of jQuery code and the 23 | data returned from the plot.

24 | 25 |

Enable tooltip

26 | 27 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /estudo3d.wad: -------------------------------------------------------------------------------- 1 | 2 | NUMPOLLIES 36 3 | 4 | // Floor 1 5 | -3.0 0.0 -3.0 0.0 6.0 6 | -3.0 0.0 3.0 0.0 0.0 7 | 3.0 0.0 3.0 6.0 0.0 8 | 9 | -3.0 0.0 -3.0 0.0 6.0 10 | 3.0 0.0 -3.0 6.0 6.0 11 | 3.0 0.0 3.0 6.0 0.0 12 | 13 | // Ceiling 1 14 | -3.0 1.0 -3.0 0.0 6.0 15 | -3.0 1.0 3.0 0.0 0.0 16 | 3.0 1.0 3.0 6.0 0.0 17 | -3.0 1.0 -3.0 0.0 6.0 18 | 3.0 1.0 -3.0 6.0 6.0 19 | 3.0 1.0 3.0 6.0 0.0 20 | 21 | // A1 22 | 23 | -2.0 1.0 -2.0 0.0 1.0 24 | -2.0 0.0 -2.0 0.0 0.0 25 | -0.5 0.0 -2.0 1.5 0.0 26 | -2.0 1.0 -2.0 0.0 1.0 27 | -0.5 1.0 -2.0 1.5 1.0 28 | -0.5 0.0 -2.0 1.5 0.0 29 | 30 | // A2 31 | 32 | 2.0 1.0 -2.0 2.0 1.0 33 | 2.0 0.0 -2.0 2.0 0.0 34 | 0.5 0.0 -2.0 0.5 0.0 35 | 2.0 1.0 -2.0 2.0 1.0 36 | 0.5 1.0 -2.0 0.5 1.0 37 | 0.5 0.0 -2.0 0.5 0.0 38 | 39 | // B1 40 | 41 | -2.0 1.0 2.0 2.0 1.0 42 | -2.0 0.0 2.0 2.0 0.0 43 | -0.5 0.0 2.0 0.5 0.0 44 | -2.0 1.0 2.0 2.0 1.0 45 | -0.5 1.0 2.0 0.5 1.0 46 | -0.5 0.0 2.0 0.5 0.0 47 | 48 | // B2 49 | 50 | 2.0 1.0 2.0 2.0 1.0 51 | 2.0 0.0 2.0 2.0 0.0 52 | 0.5 0.0 2.0 0.5 0.0 53 | 2.0 1.0 2.0 2.0 1.0 54 | 0.5 1.0 2.0 0.5 1.0 55 | 0.5 0.0 2.0 0.5 0.0 56 | 57 | // C1 58 | 59 | -2.0 1.0 -2.0 0.0 1.0 60 | -2.0 0.0 -2.0 0.0 0.0 61 | -2.0 0.0 -0.5 1.5 0.0 62 | -2.0 1.0 -2.0 0.0 1.0 63 | -2.0 1.0 -0.5 1.5 1.0 64 | -2.0 0.0 -0.5 1.5 0.0 65 | 66 | // C2 67 | 68 | -2.0 1.0 2.0 2.0 1.0 69 | -2.0 0.0 2.0 2.0 0.0 70 | -2.0 0.0 0.5 0.5 0.0 71 | -2.0 1.0 2.0 2.0 1.0 72 | -2.0 1.0 0.5 0.5 1.0 73 | -2.0 0.0 0.5 0.5 0.0 74 | 75 | // D1 76 | 77 | 2.0 1.0 -2.0 0.0 1.0 78 | 2.0 0.0 -2.0 0.0 0.0 79 | 2.0 0.0 -0.5 1.5 0.0 80 | 2.0 1.0 -2.0 0.0 1.0 81 | 2.0 1.0 -0.5 1.5 1.0 82 | 2.0 0.0 -0.5 1.5 0.0 83 | 84 | // D2 85 | 86 | 2.0 1.0 2.0 2.0 1.0 87 | 2.0 0.0 2.0 2.0 0.0 88 | 2.0 0.0 0.5 0.5 0.0 89 | 2.0 1.0 2.0 2.0 1.0 90 | 2.0 1.0 0.5 0.5 1.0 91 | 2.0 0.0 0.5 0.5 0.0 92 | 93 | // Upper hallway - L 94 | -0.5 1.0 -3.0 0.0 1.0 95 | -0.5 0.0 -3.0 0.0 0.0 96 | -0.5 0.0 -2.0 1.0 0.0 97 | -0.5 1.0 -3.0 0.0 1.0 98 | -0.5 1.0 -2.0 1.0 1.0 99 | -0.5 0.0 -2.0 1.0 0.0 100 | 101 | // Upper hallway - R 102 | 0.5 1.0 -3.0 0.0 1.0 103 | 0.5 0.0 -3.0 0.0 0.0 104 | 0.5 0.0 -2.0 1.0 0.0 105 | 0.5 1.0 -3.0 0.0 1.0 106 | 0.5 1.0 -2.0 1.0 1.0 107 | 0.5 0.0 -2.0 1.0 0.0 108 | 109 | // Lower hallway - L 110 | -0.5 1.0 3.0 0.0 1.0 111 | -0.5 0.0 3.0 0.0 0.0 112 | -0.5 0.0 2.0 1.0 0.0 113 | -0.5 1.0 3.0 0.0 1.0 114 | -0.5 1.0 2.0 1.0 1.0 115 | -0.5 0.0 2.0 1.0 0.0 116 | 117 | // Lower hallway - R 118 | 0.5 1.0 3.0 0.0 1.0 119 | 0.5 0.0 3.0 0.0 0.0 120 | 0.5 0.0 2.0 1.0 0.0 121 | 0.5 1.0 3.0 0.0 1.0 122 | 0.5 1.0 2.0 1.0 1.0 123 | 0.5 0.0 2.0 1.0 0.0 124 | 125 | 126 | // Left hallway - Lw 127 | 128 | -3.0 1.0 0.5 1.0 1.0 129 | -3.0 0.0 0.5 1.0 0.0 130 | -2.0 0.0 0.5 0.0 0.0 131 | -3.0 1.0 0.5 1.0 1.0 132 | -2.0 1.0 0.5 0.0 1.0 133 | -2.0 0.0 0.5 0.0 0.0 134 | 135 | // Left hallway - Hi 136 | 137 | -3.0 1.0 -0.5 1.0 1.0 138 | -3.0 0.0 -0.5 1.0 0.0 139 | -2.0 0.0 -0.5 0.0 0.0 140 | -3.0 1.0 -0.5 1.0 1.0 141 | -2.0 1.0 -0.5 0.0 1.0 142 | -2.0 0.0 -0.5 0.0 0.0 143 | 144 | // Right hallway - Lw 145 | 146 | 3.0 1.0 0.5 1.0 1.0 147 | 3.0 0.0 0.5 1.0 0.0 148 | 2.0 0.0 0.5 0.0 0.0 149 | 3.0 1.0 0.5 1.0 1.0 150 | 2.0 1.0 0.5 0.0 1.0 151 | 2.0 0.0 0.5 0.0 0.0 152 | 153 | // Right hallway - Hi 154 | 155 | 3.0 1.0 -0.5 1.0 1.0 156 | 3.0 0.0 -0.5 1.0 0.0 157 | 2.0 0.0 -0.5 0.0 0.0 158 | 3.0 1.0 -0.5 1.0 1.0 159 | 2.0 1.0 -0.5 0.0 1.0 160 | 2.0 0.0 -0.5 0.0 0.0 -------------------------------------------------------------------------------- /flot/PLUGINS.txt: -------------------------------------------------------------------------------- 1 | Writing plugins 2 | --------------- 3 | 4 | To make a new plugin, create an init function and a set of options (if 5 | needed), stuff it into an object and put it in the $.plot.plugins 6 | array. For example: 7 | 8 | function myCoolPluginInit(plot) { plot.coolstring = "Hello!" }; 9 | var myCoolOptions = { coolstuff: { show: true } } 10 | $.plot.plugins.push({ init: myCoolPluginInit, options: myCoolOptions }); 11 | 12 | // now when $.plot is called, the returned object will have the 13 | // attribute "coolstring" 14 | 15 | Now, given that the plugin might run in many different places, it's 16 | a good idea to avoid leaking names. We can avoid this by wrapping the 17 | above lines in an anonymous function which we call immediately, like 18 | this: (function () { inner code ... })(). To make it even more robust 19 | in case $ is not bound to jQuery but some other Javascript library, we 20 | can write it as 21 | 22 | (function ($) { 23 | // plugin definition 24 | // ... 25 | })(jQuery); 26 | 27 | Here is a simple debug plugin which alerts each of the series in the 28 | plot. It has a single option that control whether it is enabled and 29 | how much info to output: 30 | 31 | (function ($) { 32 | function init(plot) { 33 | var debugLevel = 1; 34 | 35 | function checkDebugEnabled(plot, options) { 36 | if (options.debug) { 37 | debugLevel = options.debug; 38 | 39 | plot.hooks.processDatapoints.push(alertSeries); 40 | } 41 | } 42 | 43 | function alertSeries(plot, series, datapoints) { 44 | var msg = "series " + series.label; 45 | if (debugLevel > 1) 46 | msg += " with " + series.data.length + " points"; 47 | alert(msg); 48 | } 49 | 50 | plot.hooks.processOptions.push(checkDebugEnabled); 51 | } 52 | 53 | var options = { debug: 0 }; 54 | 55 | $.plot.plugins.push({ 56 | init: init, 57 | options: options, 58 | name: "simpledebug", 59 | version: "0.1" 60 | }); 61 | })(jQuery); 62 | 63 | We also define "name" and "version". It's not used by Flot, but might 64 | be helpful for other plugins in resolving dependencies. 65 | 66 | Put the above in a file named "jquery.flot.debug.js", include it in an 67 | HTML page and then it can be used with: 68 | 69 | $.plot($("#placeholder"), [...], { debug: 2 }); 70 | 71 | This simple plugin illustrates a couple of points: 72 | 73 | - It uses the anonymous function trick to avoid name pollution. 74 | - It can be enabled/disabled through an option. 75 | - Variables in the init function can be used to store plot-specific 76 | state between the hooks. 77 | 78 | 79 | Options guidelines 80 | ================== 81 | 82 | Plugins should always support appropriate options to enable/disable 83 | them because the plugin user may have several plots on the same page 84 | where only one should use the plugin. 85 | 86 | If the plugin needs series-specific options, you can put them in 87 | "series" in the options object, e.g. 88 | 89 | var options = { 90 | series: { 91 | downsample: { 92 | algorithm: null, 93 | maxpoints: 1000 94 | } 95 | } 96 | } 97 | 98 | Then they will be copied by Flot into each series, providing the 99 | defaults in case the plugin user doesn't specify any. Again, in most 100 | cases it's probably a good idea if the plugin is turned off rather 101 | than on per default, just like most of the powerful features in Flot. 102 | 103 | Think hard and long about naming the options. These names are going to 104 | be public API, and code is going to depend on them if the plugin is 105 | successful. 106 | -------------------------------------------------------------------------------- /estudovenda.php: -------------------------------------------------------------------------------- 1 | 2 | '); ?> 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
--
27 |
28 | 29 |
30 |
--
--
--
49 |
50 |
51 |
52 |
53 |
54 | 60 |
61 |
62 | 70 |
71 |
72 | 76 |
77 |
78 | prazos 79 |
80 |
81 | data 82 |
83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /flot/examples/tracking.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Flot Examples

14 | 15 |
16 | 17 |

You can add crosshairs that'll track the mouse position, either 18 | on both axes or as here on only one.

19 | 20 |

If you combine it with listening on hover events, you can use 21 | it to track the intersection on the curves by interpolating 22 | the data points (look at the legend).

23 | 24 |

25 | 26 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /flot/jquery.flot.threshold.js: -------------------------------------------------------------------------------- 1 | /* 2 | Flot plugin for thresholding data. Controlled through the option 3 | "threshold" in either the global series options 4 | 5 | series: { 6 | threshold: { 7 | below: number 8 | color: colorspec 9 | } 10 | } 11 | 12 | or in a specific series 13 | 14 | $.plot($("#placeholder"), [{ data: [ ... ], threshold: { ... }}]) 15 | 16 | The data points below "below" are drawn with the specified color. This 17 | makes it easy to mark points below 0, e.g. for budget data. 18 | 19 | Internally, the plugin works by splitting the data into two series, 20 | above and below the threshold. The extra series below the threshold 21 | will have its label cleared and the special "originSeries" attribute 22 | set to the original series. You may need to check for this in hover 23 | events. 24 | */ 25 | 26 | (function ($) { 27 | var options = { 28 | series: { threshold: null } // or { below: number, color: color spec} 29 | }; 30 | 31 | function init(plot) { 32 | function thresholdData(plot, s, datapoints) { 33 | if (!s.threshold) 34 | return; 35 | 36 | var ps = datapoints.pointsize, i, x, y, p, prevp, 37 | thresholded = $.extend({}, s); // note: shallow copy 38 | 39 | thresholded.datapoints = { points: [], pointsize: ps }; 40 | thresholded.label = null; 41 | thresholded.color = s.threshold.color; 42 | thresholded.threshold = null; 43 | thresholded.originSeries = s; 44 | thresholded.data = []; 45 | 46 | var below = s.threshold.below, 47 | origpoints = datapoints.points, 48 | addCrossingPoints = s.lines.show; 49 | 50 | threspoints = []; 51 | newpoints = []; 52 | 53 | for (i = 0; i < origpoints.length; i += ps) { 54 | x = origpoints[i] 55 | y = origpoints[i + 1]; 56 | 57 | prevp = p; 58 | if (y < below) 59 | p = threspoints; 60 | else 61 | p = newpoints; 62 | 63 | if (addCrossingPoints && prevp != p && x != null 64 | && i > 0 && origpoints[i - ps] != null) { 65 | var interx = (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]) * (below - y) + x; 66 | prevp.push(interx); 67 | prevp.push(below); 68 | for (m = 2; m < ps; ++m) 69 | prevp.push(origpoints[i + m]); 70 | 71 | p.push(null); // start new segment 72 | p.push(null); 73 | for (m = 2; m < ps; ++m) 74 | p.push(origpoints[i + m]); 75 | p.push(interx); 76 | p.push(below); 77 | for (m = 2; m < ps; ++m) 78 | p.push(origpoints[i + m]); 79 | } 80 | 81 | p.push(x); 82 | p.push(y); 83 | } 84 | 85 | datapoints.points = newpoints; 86 | thresholded.datapoints.points = threspoints; 87 | 88 | if (thresholded.datapoints.points.length > 0) 89 | plot.getData().push(thresholded); 90 | 91 | // FIXME: there are probably some edge cases left in bars 92 | } 93 | 94 | plot.hooks.processDatapoints.push(thresholdData); 95 | } 96 | 97 | $.plot.plugins.push({ 98 | init: init, 99 | options: options, 100 | name: 'threshold', 101 | version: '1.0' 102 | }); 103 | })(jQuery); 104 | -------------------------------------------------------------------------------- /flot/examples/zooming.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Flot Examples

14 | 15 |
16 |
17 |
18 | 19 |
20 |
21 | 22 |

23 |
24 | 25 |

The selection support makes 26 | pretty advanced zooming schemes possible. With a few lines of code, 27 | the small overview plot to the right has been connected to the large 28 | plot. Try selecting a rectangle on either of them.

29 | 30 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /estudolivro.php: -------------------------------------------------------------------------------- 1 | 2 | '); ?> 3 | 4 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
--
34 |
35 | 36 |
37 |
--
--
--
56 |
57 |
58 |
59 |
60 |
61 | 67 |
68 |
69 | 77 |
78 |
79 | 83 |
84 |
85 | prazos 86 |
87 |
88 | data 89 |
90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /flot/jquery.flot.navigate.min.js: -------------------------------------------------------------------------------- 1 | (function(R){R.fn.drag=function(A,B,C){if(B){this.bind("dragstart",A)}if(C){this.bind("dragend",C)}return !A?this.trigger("drag"):this.bind("drag",B?B:A)};var M=R.event,L=M.special,Q=L.drag={not:":input",distance:0,which:1,dragging:false,setup:function(A){A=R.extend({distance:Q.distance,which:Q.which,not:Q.not},A||{});A.distance=N(A.distance);M.add(this,"mousedown",O,A);if(this.attachEvent){this.attachEvent("ondragstart",J)}},teardown:function(){M.remove(this,"mousedown",O);if(this===Q.dragging){Q.dragging=Q.proxy=false}P(this,true);if(this.detachEvent){this.detachEvent("ondragstart",J)}}};L.dragstart=L.dragend={setup:function(){},teardown:function(){}};function O(A){var B=this,C,D=A.data||{};if(D.elem){B=A.dragTarget=D.elem;A.dragProxy=Q.proxy||B;A.cursorOffsetX=D.pageX-D.left;A.cursorOffsetY=D.pageY-D.top;A.offsetX=A.pageX-A.cursorOffsetX;A.offsetY=A.pageY-A.cursorOffsetY}else{if(Q.dragging||(D.which>0&&A.which!=D.which)||R(A.target).is(D.not)){return }}switch(A.type){case"mousedown":R.extend(D,R(B).offset(),{elem:B,target:A.target,pageX:A.pageX,pageY:A.pageY});M.add(document,"mousemove mouseup",O,D);P(B,false);Q.dragging=null;return false;case !Q.dragging&&"mousemove":if(N(A.pageX-D.pageX)+N(A.pageY-D.pageY)Z[1]))){return }a.min=X;a.max=T}K(G,F,"xaxis");K(G,F,"x2axis");K(P,O,"yaxis");K(P,O,"y2axis");D.setupGrid();D.draw();if(!M.preventEvent){D.getPlaceholder().trigger("plotzoom",[D])}};D.pan=function(I){var F=+I.left,J=+I.top,K=D.getAxes(),H=D.getOptions();if(isNaN(F)){F=0}if(isNaN(J)){J=0}function G(R,M){var O=K[M],Q=H[M],N,L;if(!O.used){return }N=O.c2p(O.p2c(O.min)+R),L=O.c2p(O.p2c(O.max)+R);var P=Q.panRange;if(P){if(P[0]!=null&&P[0]>N){R=P[0]-N;N+=R;L+=R}if(P[1]!=null&&P[1] 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 27 | 28 | 29 |

Flot Examples

30 | 31 |
32 | 33 |

34 | 35 |

With the navigate plugin it is easy to add panning and zooming. 36 | Drag to pan, double click to zoom (or use the mouse scrollwheel).

37 | 38 |

The plugin fires events (useful for synchronizing several 39 | plots) and adds a couple of public methods so you can easily build 40 | a little user interface around it, like the little buttons at the 41 | top right in the plot.

42 | 43 | 44 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /ystockquote.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright (c) 2007-2008, Corey Goldberg (corey@goldb.org) 4 | # 5 | # license: GNU LGPL 6 | # 7 | # This library is free software; you can redistribute it and/or 8 | # modify it under the terms of the GNU Lesser General Public 9 | # License as published by the Free Software Foundation; either 10 | # version 2.1 of the License, or (at your option) any later version. 11 | 12 | 13 | import urllib 14 | 15 | 16 | """ 17 | This is the "ystockquote" module. 18 | 19 | This module provides a Python API for retrieving stock data from Yahoo Finance. 20 | 21 | sample usage: 22 | >>> import ystockquote 23 | >>> print ystockquote.get_price('GOOG') 24 | 529.46 25 | """ 26 | 27 | 28 | def __request(symbol, stat): 29 | url = 'http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s' % (symbol, stat) 30 | return urllib.urlopen(url).read().strip().strip('"') 31 | 32 | 33 | def get_all(symbol): 34 | """ 35 | Get all available quote data for the given ticker symbol. 36 | 37 | Returns a dictionary. 38 | """ 39 | values = __request(symbol, 'l1c1va2xj1b4j4dyekjm3m4rr5p5p6s7').split(',') 40 | data = {} 41 | data['price'] = values[0] 42 | data['change'] = values[1] 43 | data['volume'] = values[2] 44 | data['avg_daily_volume'] = values[3] 45 | data['stock_exchange'] = values[4] 46 | data['market_cap'] = values[5] 47 | data['book_value'] = values[6] 48 | data['ebitda'] = values[7] 49 | data['dividend_per_share'] = values[8] 50 | data['dividend_yield'] = values[9] 51 | data['earnings_per_share'] = values[10] 52 | data['52_week_high'] = values[11] 53 | data['52_week_low'] = values[12] 54 | data['50day_moving_avg'] = values[13] 55 | data['200day_moving_avg'] = values[14] 56 | data['price_earnings_ratio'] = values[15] 57 | data['price_earnings_growth_ratio'] = values[16] 58 | data['price_sales_ratio'] = values[17] 59 | data['price_book_ratio'] = values[18] 60 | data['short_ratio'] = values[19] 61 | return data 62 | 63 | 64 | def get_price(symbol): 65 | return __request(symbol, 'l1') 66 | 67 | 68 | def get_change(symbol): 69 | return __request(symbol, 'c1') 70 | 71 | 72 | def get_volume(symbol): 73 | return __request(symbol, 'v') 74 | 75 | 76 | def get_avg_daily_volume(symbol): 77 | return __request(symbol, 'a2') 78 | 79 | 80 | def get_stock_exchange(symbol): 81 | return __request(symbol, 'x') 82 | 83 | 84 | def get_market_cap(symbol): 85 | return __request(symbol, 'j1') 86 | 87 | 88 | def get_book_value(symbol): 89 | return __request(symbol, 'b4') 90 | 91 | 92 | def get_ebitda(symbol): 93 | return __request(symbol, 'j4') 94 | 95 | 96 | def get_dividend_per_share(symbol): 97 | return __request(symbol, 'd') 98 | 99 | 100 | def get_dividend_yield(symbol): 101 | return __request(symbol, 'y') 102 | 103 | 104 | def get_earnings_per_share(symbol): 105 | return __request(symbol, 'e') 106 | 107 | 108 | def get_52_week_high(symbol): 109 | return __request(symbol, 'k') 110 | 111 | 112 | def get_52_week_low(symbol): 113 | return __request(symbol, 'j') 114 | 115 | 116 | def get_50day_moving_avg(symbol): 117 | return __request(symbol, 'm3') 118 | 119 | 120 | def get_200day_moving_avg(symbol): 121 | return __request(symbol, 'm4') 122 | 123 | 124 | def get_price_earnings_ratio(symbol): 125 | return __request(symbol, 'r') 126 | 127 | 128 | def get_price_earnings_growth_ratio(symbol): 129 | return __request(symbol, 'r5') 130 | 131 | 132 | def get_price_sales_ratio(symbol): 133 | return __request(symbol, 'p5') 134 | 135 | 136 | def get_price_book_ratio(symbol): 137 | return __request(symbol, 'p6') 138 | 139 | 140 | def get_short_ratio(symbol): 141 | return __request(symbol, 's7') 142 | 143 | 144 | def get_historical_prices(symbol, start_date, end_date): 145 | """ 146 | Get historical prices for the given ticker symbol. 147 | Date format is 'YYYYMMDD' 148 | 149 | Returns a nested list. 150 | """ 151 | url = 'http://ichart.yahoo.com/table.csv?s=%s&' % symbol + \ 152 | 'd=%s&' % str(int(end_date[4:6]) - 1) + \ 153 | 'e=%s&' % str(int(end_date[6:8])) + \ 154 | 'f=%s&' % str(int(end_date[0:4])) + \ 155 | 'g=d&' + \ 156 | 'a=%s&' % str(int(start_date[4:6]) - 1) + \ 157 | 'b=%s&' % str(int(start_date[6:8])) + \ 158 | 'c=%s&' % str(int(start_date[0:4])) + \ 159 | 'ignore=.csv' 160 | days = urllib.urlopen(url).readlines() 161 | data = [day[:-2].split(',') for day in days] 162 | return data 163 | 164 | -------------------------------------------------------------------------------- /flot/examples/turning-series.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Flot Examples

13 | 14 |
15 | 16 |

Here is an example with real data: military budgets for 17 | various countries in constant (2005) million US dollars (source: SIPRI).

18 | 19 |

Since all data is available client-side, it's pretty easy to 20 | make the plot interactive. Try turning countries on/off with the 21 | checkboxes below.

22 | 23 |

Show:

24 | 25 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /flot/examples/visitors.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Flot Examples

14 | 15 |
16 | 17 |

Visitors per day to the Flot homepage. Weekends are colored. Try zooming. 18 | The plot below shows an overview.

19 | 20 |
21 | 22 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /flot/examples/ajax.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 |

Flot Examples

13 | 14 |
15 | 16 |

Example of loading data dynamically with AJAX. Percentage change in GDP (source: Eurostat). Click the buttons below.

17 | 18 |

The data is fetched over HTTP, in this case directly from text 19 | files. Usually the URL would point to some web server handler 20 | (e.g. a PHP page or Java/.NET/Python/Ruby on Rails handler) that 21 | extracts it from a database and serializes it to JSON.

22 | 23 |

24 | - 25 | data - 26 | 27 |

28 | 29 |

30 | - 31 | data - 32 | 33 |

34 | 35 |

36 | - 37 | data - 38 | 39 |

40 | 41 |

If you combine AJAX with setTimeout, you can poll the server 42 | for new data.

43 | 44 |

45 | 46 |

47 | 48 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /flot/examples/selection.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Flot Examples 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Flot Examples

14 | 15 |
16 | 17 |

1000 kg. CO2 emissions per year per capita for various countries (source: Wikipedia).

18 | 19 |

Flot supports selections through the selection plugin. 20 | You can enable rectangular selection 21 | or one-dimensional selection if the user should only be able to 22 | select on one axis. Try left-click and drag on the plot above 23 | where selection on the x axis is enabled.

24 | 25 |

You selected:

26 | 27 |

The plot command returns a plot object you can use to control 28 | the selection. Click the buttons below.

29 | 30 |

31 |

32 | 33 |

Selections are really useful for zooming. Just replot the 34 | chart with min and max values for the axes set to the values 35 | in the "plotselected" event triggered. Enable the checkbox 36 | below and select a region again.

37 | 38 |

Zoom to selection.

39 | 40 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /flot/jquery.flot.crosshair.js: -------------------------------------------------------------------------------- 1 | /* 2 | Flot plugin for showing a crosshair, thin lines, when the mouse hovers 3 | over the plot. 4 | 5 | crosshair: { 6 | mode: null or "x" or "y" or "xy" 7 | color: color 8 | lineWidth: number 9 | } 10 | 11 | Set the mode to one of "x", "y" or "xy". The "x" mode enables a 12 | vertical crosshair that lets you trace the values on the x axis, "y" 13 | enables a horizontal crosshair and "xy" enables them both. "color" is 14 | the color of the crosshair (default is "rgba(170, 0, 0, 0.80)"), 15 | "lineWidth" is the width of the drawn lines (default is 1). 16 | 17 | The plugin also adds four public methods: 18 | 19 | - setCrosshair(pos) 20 | 21 | Set the position of the crosshair. Note that this is cleared if 22 | the user moves the mouse. "pos" should be on the form { x: xpos, 23 | y: ypos } (or x2 and y2 if you're using the secondary axes), which 24 | is coincidentally the same format as what you get from a "plothover" 25 | event. If "pos" is null, the crosshair is cleared. 26 | 27 | - clearCrosshair() 28 | 29 | Clear the crosshair. 30 | 31 | - lockCrosshair(pos) 32 | 33 | Cause the crosshair to lock to the current location, no longer 34 | updating if the user moves the mouse. Optionally supply a position 35 | (passed on to setCrosshair()) to move it to. 36 | 37 | Example usage: 38 | var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } }; 39 | $("#graph").bind("plothover", function (evt, position, item) { 40 | if (item) { 41 | // Lock the crosshair to the data point being hovered 42 | myFlot.lockCrosshair({ x: item.datapoint[0], y: item.datapoint[1] }); 43 | } 44 | else { 45 | // Return normal crosshair operation 46 | myFlot.unlockCrosshair(); 47 | } 48 | }); 49 | 50 | - unlockCrosshair() 51 | 52 | Free the crosshair to move again after locking it. 53 | */ 54 | 55 | (function ($) { 56 | var options = { 57 | crosshair: { 58 | mode: null, // one of null, "x", "y" or "xy", 59 | color: "rgba(170, 0, 0, 0.80)", 60 | lineWidth: 1 61 | } 62 | }; 63 | 64 | function init(plot) { 65 | // position of crosshair in pixels 66 | var crosshair = { x: -1, y: -1, locked: false }; 67 | 68 | plot.setCrosshair = function setCrosshair(pos) { 69 | if (!pos) 70 | crosshair.x = -1; 71 | else { 72 | var axes = plot.getAxes(); 73 | 74 | crosshair.x = Math.max(0, Math.min(pos.x != null ? axes.xaxis.p2c(pos.x) : axes.x2axis.p2c(pos.x2), plot.width())); 75 | crosshair.y = Math.max(0, Math.min(pos.y != null ? axes.yaxis.p2c(pos.y) : axes.y2axis.p2c(pos.y2), plot.height())); 76 | } 77 | 78 | plot.triggerRedrawOverlay(); 79 | }; 80 | 81 | plot.clearCrosshair = plot.setCrosshair; // passes null for pos 82 | 83 | plot.lockCrosshair = function lockCrosshair(pos) { 84 | if (pos) 85 | plot.setCrosshair(pos); 86 | crosshair.locked = true; 87 | } 88 | 89 | plot.unlockCrosshair = function unlockCrosshair() { 90 | crosshair.locked = false; 91 | } 92 | 93 | plot.hooks.bindEvents.push(function (plot, eventHolder) { 94 | if (!plot.getOptions().crosshair.mode) 95 | return; 96 | 97 | eventHolder.mouseout(function () { 98 | if (crosshair.x != -1) { 99 | crosshair.x = -1; 100 | plot.triggerRedrawOverlay(); 101 | } 102 | }); 103 | 104 | eventHolder.mousemove(function (e) { 105 | if (plot.getSelection && plot.getSelection()) { 106 | crosshair.x = -1; // hide the crosshair while selecting 107 | return; 108 | } 109 | 110 | if (crosshair.locked) 111 | return; 112 | 113 | var offset = plot.offset(); 114 | crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width())); 115 | crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height())); 116 | plot.triggerRedrawOverlay(); 117 | }); 118 | }); 119 | 120 | plot.hooks.drawOverlay.push(function (plot, ctx) { 121 | var c = plot.getOptions().crosshair; 122 | if (!c.mode) 123 | return; 124 | 125 | var plotOffset = plot.getPlotOffset(); 126 | 127 | ctx.save(); 128 | ctx.translate(plotOffset.left, plotOffset.top); 129 | 130 | if (crosshair.x != -1) { 131 | ctx.strokeStyle = c.color; 132 | ctx.lineWidth = c.lineWidth; 133 | ctx.lineJoin = "round"; 134 | 135 | ctx.beginPath(); 136 | if (c.mode.indexOf("x") != -1) { 137 | ctx.moveTo(crosshair.x, 0); 138 | ctx.lineTo(crosshair.x, plot.height()); 139 | } 140 | if (c.mode.indexOf("y") != -1) { 141 | ctx.moveTo(0, crosshair.y); 142 | ctx.lineTo(plot.width(), crosshair.y); 143 | } 144 | ctx.stroke(); 145 | } 146 | ctx.restore(); 147 | }); 148 | } 149 | 150 | $.plot.plugins.push({ 151 | init: init, 152 | options: options, 153 | name: 'crosshair', 154 | version: '1.0' 155 | }); 156 | })(jQuery); 157 | -------------------------------------------------------------------------------- /glUtils.js: -------------------------------------------------------------------------------- 1 | // augment Sylvester some 2 | Matrix.Translation = function (v) 3 | { 4 | if (v.elements.length == 2) { 5 | var r = Matrix.I(3); 6 | r.elements[2][0] = v.elements[0]; 7 | r.elements[2][1] = v.elements[1]; 8 | return r; 9 | } 10 | 11 | if (v.elements.length == 3) { 12 | var r = Matrix.I(4); 13 | r.elements[0][3] = v.elements[0]; 14 | r.elements[1][3] = v.elements[1]; 15 | r.elements[2][3] = v.elements[2]; 16 | return r; 17 | } 18 | 19 | throw "Invalid length for Translation"; 20 | } 21 | 22 | Matrix.prototype.flatten = function () 23 | { 24 | var result = []; 25 | if (this.elements.length == 0) 26 | return []; 27 | 28 | 29 | for (var j = 0; j < this.elements[0].length; j++) 30 | for (var i = 0; i < this.elements.length; i++) 31 | result.push(this.elements[i][j]); 32 | return result; 33 | } 34 | 35 | Matrix.prototype.ensure4x4 = function() 36 | { 37 | if (this.elements.length == 4 && 38 | this.elements[0].length == 4) 39 | return this; 40 | 41 | if (this.elements.length > 4 || 42 | this.elements[0].length > 4) 43 | return null; 44 | 45 | for (var i = 0; i < this.elements.length; i++) { 46 | for (var j = this.elements[i].length; j < 4; j++) { 47 | if (i == j) 48 | this.elements[i].push(1); 49 | else 50 | this.elements[i].push(0); 51 | } 52 | } 53 | 54 | for (var i = this.elements.length; i < 4; i++) { 55 | if (i == 0) 56 | this.elements.push([1, 0, 0, 0]); 57 | else if (i == 1) 58 | this.elements.push([0, 1, 0, 0]); 59 | else if (i == 2) 60 | this.elements.push([0, 0, 1, 0]); 61 | else if (i == 3) 62 | this.elements.push([0, 0, 0, 1]); 63 | } 64 | 65 | return this; 66 | }; 67 | 68 | Matrix.prototype.make3x3 = function() 69 | { 70 | if (this.elements.length != 4 || 71 | this.elements[0].length != 4) 72 | return null; 73 | 74 | return Matrix.create([[this.elements[0][0], this.elements[0][1], this.elements[0][2]], 75 | [this.elements[1][0], this.elements[1][1], this.elements[1][2]], 76 | [this.elements[2][0], this.elements[2][1], this.elements[2][2]]]); 77 | }; 78 | 79 | Vector.prototype.flatten = function () 80 | { 81 | return this.elements; 82 | }; 83 | 84 | function mht(m) { 85 | var s = ""; 86 | if (m.length == 16) { 87 | for (var i = 0; i < 4; i++) { 88 | s += "[" + m[i*4+0].toFixed(4) + "," + m[i*4+1].toFixed(4) + "," + m[i*4+2].toFixed(4) + "," + m[i*4+3].toFixed(4) + "]
"; 89 | } 90 | } else if (m.length == 9) { 91 | for (var i = 0; i < 3; i++) { 92 | s += "[" + m[i*3+0].toFixed(4) + "," + m[i*3+1].toFixed(4) + "," + m[i*3+2].toFixed(4) + "]
"; 93 | } 94 | } else { 95 | return m.toString(); 96 | } 97 | return s; 98 | } 99 | 100 | // 101 | // gluLookAt 102 | // 103 | function makeLookAt(ex, ey, ez, 104 | cx, cy, cz, 105 | ux, uy, uz) 106 | { 107 | var eye = $V([ex, ey, ez]); 108 | var center = $V([cx, cy, cz]); 109 | var up = $V([ux, uy, uz]); 110 | 111 | var mag; 112 | 113 | var z = eye.subtract(center).toUnitVector(); 114 | var x = up.cross(z).toUnitVector(); 115 | var y = z.cross(x).toUnitVector(); 116 | 117 | var m = $M([[x.e(1), x.e(2), x.e(3), 0], 118 | [y.e(1), y.e(2), y.e(3), 0], 119 | [z.e(1), z.e(2), z.e(3), 0], 120 | [0, 0, 0, 1]]); 121 | 122 | var t = $M([[1, 0, 0, -ex], 123 | [0, 1, 0, -ey], 124 | [0, 0, 1, -ez], 125 | [0, 0, 0, 1]]); 126 | return m.x(t); 127 | } 128 | 129 | // 130 | // glOrtho 131 | // 132 | function makeOrtho(left, right, 133 | bottom, top, 134 | znear, zfar) 135 | { 136 | var tx = -(right+left)/(right-left); 137 | var ty = -(top+bottom)/(top-bottom); 138 | var tz = -(zfar+znear)/(zfar-znear); 139 | 140 | return $M([[2/(right-left), 0, 0, tx], 141 | [0, 2/(top-bottom), 0, ty], 142 | [0, 0, -2/(zfar-znear), tz], 143 | [0, 0, 0, 1]]); 144 | } 145 | 146 | // 147 | // gluPerspective 148 | // 149 | function makePerspective(fovy, aspect, znear, zfar) 150 | { 151 | var ymax = znear * Math.tan(fovy * Math.PI / 360.0); 152 | var ymin = -ymax; 153 | var xmin = ymin * aspect; 154 | var xmax = ymax * aspect; 155 | 156 | return makeFrustum(xmin, xmax, ymin, ymax, znear, zfar); 157 | } 158 | 159 | // 160 | // glFrustum 161 | // 162 | function makeFrustum(left, right, 163 | bottom, top, 164 | znear, zfar) 165 | { 166 | var X = 2*znear/(right-left); 167 | var Y = 2*znear/(top-bottom); 168 | var A = (right+left)/(right-left); 169 | var B = (top+bottom)/(top-bottom); 170 | var C = -(zfar+znear)/(zfar-znear); 171 | var D = -2*zfar*znear/(zfar-znear); 172 | 173 | return $M([[X, 0, A, 0], 174 | [0, Y, B, 0], 175 | [0, 0, C, D], 176 | [0, 0, -1, 0]]); 177 | } 178 | 179 | // 180 | // glOrtho 181 | // 182 | function makeOrtho(left, right, bottom, top, znear, zfar) 183 | { 184 | var tx = - (right + left) / (right - left); 185 | var ty = - (top + bottom) / (top - bottom); 186 | var tz = - (zfar + znear) / (zfar - znear); 187 | 188 | return $M([[2 / (right - left), 0, 0, tx], 189 | [0, 2 / (top - bottom), 0, ty], 190 | [0, 0, -2 / (zfar - znear), tz], 191 | [0, 0, 0, 1]]); 192 | } 193 | 194 | -------------------------------------------------------------------------------- /flot/jquery.flot.stack.js: -------------------------------------------------------------------------------- 1 | /* 2 | Flot plugin for stacking data sets, i.e. putting them on top of each 3 | other, for accumulative graphs. Note that the plugin assumes the data 4 | is sorted on x. Also note that stacking a mix of positive and negative 5 | values in most instances doesn't make sense (so it looks weird). 6 | 7 | Two or more series are stacked when their "stack" attribute is set to 8 | the same key (which can be any number or string or just "true"). To 9 | specify the default stack, you can set 10 | 11 | series: { 12 | stack: null or true or key (number/string) 13 | } 14 | 15 | or specify it for a specific series 16 | 17 | $.plot($("#placeholder"), [{ data: [ ... ], stack: true ]) 18 | 19 | The stacking order is determined by the order of the data series in 20 | the array (later series end up on top of the previous). 21 | 22 | Internally, the plugin modifies the datapoints in each series, adding 23 | an offset to the y value. For line series, extra data points are 24 | inserted through interpolation. For bar charts, the second y value is 25 | also adjusted. 26 | */ 27 | 28 | (function ($) { 29 | var options = { 30 | series: { stack: null } // or number/string 31 | }; 32 | 33 | function init(plot) { 34 | function findMatchingSeries(s, allseries) { 35 | var res = null 36 | for (var i = 0; i < allseries.length; ++i) { 37 | if (s == allseries[i]) 38 | break; 39 | 40 | if (allseries[i].stack == s.stack) 41 | res = allseries[i]; 42 | } 43 | 44 | return res; 45 | } 46 | 47 | function stackData(plot, s, datapoints) { 48 | if (s.stack == null) 49 | return; 50 | 51 | var other = findMatchingSeries(s, plot.getData()); 52 | if (!other) 53 | return; 54 | 55 | var ps = datapoints.pointsize, 56 | points = datapoints.points, 57 | otherps = other.datapoints.pointsize, 58 | otherpoints = other.datapoints.points, 59 | newpoints = [], 60 | px, py, intery, qx, qy, bottom, 61 | withlines = s.lines.show, withbars = s.bars.show, 62 | withsteps = withlines && s.lines.steps, 63 | i = 0, j = 0, l; 64 | 65 | while (true) { 66 | if (i >= points.length) 67 | break; 68 | 69 | l = newpoints.length; 70 | 71 | if (j >= otherpoints.length 72 | || otherpoints[j] == null 73 | || points[i] == null) { 74 | // degenerate cases 75 | for (m = 0; m < ps; ++m) 76 | newpoints.push(points[i + m]); 77 | i += ps; 78 | } 79 | else { 80 | // cases where we actually got two points 81 | px = points[i]; 82 | py = points[i + 1]; 83 | qx = otherpoints[j]; 84 | qy = otherpoints[j + 1]; 85 | bottom = 0; 86 | 87 | if (px == qx) { 88 | for (m = 0; m < ps; ++m) 89 | newpoints.push(points[i + m]); 90 | 91 | newpoints[l + 1] += qy; 92 | bottom = qy; 93 | 94 | i += ps; 95 | j += otherps; 96 | } 97 | else if (px > qx) { 98 | // we got past point below, might need to 99 | // insert interpolated extra point 100 | if (withlines && i > 0 && points[i - ps] != null) { 101 | intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px); 102 | newpoints.push(qx); 103 | newpoints.push(intery + qy) 104 | for (m = 2; m < ps; ++m) 105 | newpoints.push(points[i + m]); 106 | bottom = qy; 107 | } 108 | 109 | j += otherps; 110 | } 111 | else { 112 | for (m = 0; m < ps; ++m) 113 | newpoints.push(points[i + m]); 114 | 115 | // we might be able to interpolate a point below, 116 | // this can give us a better y 117 | if (withlines && j > 0 && otherpoints[j - ps] != null) 118 | bottom = qy + (otherpoints[j - ps + 1] - qy) * (px - qx) / (otherpoints[j - ps] - qx); 119 | 120 | newpoints[l + 1] += bottom; 121 | 122 | i += ps; 123 | } 124 | 125 | if (l != newpoints.length && withbars) 126 | newpoints[l + 2] += bottom; 127 | } 128 | 129 | // maintain the line steps invariant 130 | if (withsteps && l != newpoints.length && l > 0 131 | && newpoints[l] != null 132 | && newpoints[l] != newpoints[l - ps] 133 | && newpoints[l + 1] != newpoints[l - ps + 1]) { 134 | for (m = 0; m < ps; ++m) 135 | newpoints[l + ps + m] = newpoints[l + m]; 136 | newpoints[l + 1] = newpoints[l - ps + 1]; 137 | } 138 | } 139 | 140 | datapoints.points = newpoints; 141 | } 142 | 143 | plot.hooks.processDatapoints.push(stackData); 144 | } 145 | 146 | $.plot.plugins.push({ 147 | init: init, 148 | options: options, 149 | name: 'stack', 150 | version: '1.0' 151 | }); 152 | })(jQuery); 153 | -------------------------------------------------------------------------------- /blackscholes.js: -------------------------------------------------------------------------------- 1 | // ## -*- coding: utf-8 -*- 2 | 3 | /*jslint browser:true, sub:true, white:false */ 4 | 5 | // Taken from book "Black Scholes and Beyond" 6 | 7 | var kd1 = 0.0498673470; 8 | var kd3 = 0.0032776263; 9 | var kd5 = 0.0000488906; 10 | var kd2 = 0.0211410061; 11 | var kd4 = 0.0000380036; 12 | var kd6 = 0.0000053830; 13 | 14 | function normdistacum(x) 15 | { 16 | if (x < 0) { 17 | return 1 - normdistacum(-x); 18 | } 19 | var n = 1.0 - 0.5*Math.pow(1 + kd1*x + kd2*Math.pow(x,2) + kd3*Math.pow(x,3) + kd4*Math.pow(x,4) + kd5*Math.pow(x,5) + kd6*Math.pow(x,6),-16); 20 | return n; 21 | } 22 | 23 | function normdist(x) 24 | { 25 | var n = Math.exp(-(Math.pow(x,2)/2)); 26 | n /= Math.pow((2*Math.PI),0.5); 27 | return n; 28 | } 29 | 30 | function d1(spot, strike, interest, time, volatility) 31 | { 32 | if (volatility < 0.0000001) { 33 | return 9999999999.9; 34 | } 35 | var x = Math.log(spot/strike) + (interest + Math.pow(volatility,2)/2) * time; 36 | x /= volatility * Math.pow(time, 0.5); 37 | return x; 38 | } 39 | 40 | function d2(spot, strike, interest, time, volatility) 41 | { 42 | var x = d1(spot, strike, interest, time, volatility) - volatility*Math.pow(time,0.5); 43 | return x; 44 | } 45 | 46 | function opremium(spot, strike, interest, time, volatility) 47 | { 48 | if (time < 0.1 / 365) { 49 | return Math.max(spot - strike, 0); 50 | } 51 | var D1 = d1(spot, strike, interest, time, volatility); 52 | var nd1 = normdistacum(D1); 53 | var D2 = d2(spot, strike, interest, time, volatility); 54 | var nd2 = normdistacum(D2); 55 | return nd1*spot - Math.exp(-interest*time)*nd2*strike; 56 | } 57 | 58 | function putzopremium(spot, strike, interest, time, volatility) 59 | { 60 | if (time < 0.1 / 365) { 61 | return Math.max(strike - spot, 0); 62 | } 63 | var D1 = d1(spot, strike, interest, time, volatility); 64 | var nd1 = normdistacum(-D1); 65 | var D2 = d2(spot, strike, interest, time, volatility); 66 | var nd2 = normdistacum(-D2); 67 | return -nd1*spot + Math.exp(-interest*time)*nd2*strike; 68 | } 69 | 70 | 71 | function odelta(spot, strike, interest, time, volatility) 72 | { 73 | var x = normdistacum(d1(spot, strike, interest, time, volatility)); 74 | return x; 75 | } 76 | 77 | function putzodelta(spot, strike, interest, time, volatility) 78 | { 79 | var x = normdistacum(d1(spot, strike, interest, time, volatility)) - 1; 80 | return x; 81 | } 82 | 83 | function ogamma(spot, strike, interest, time, volatility) 84 | { 85 | var D1 = d1(spot, strike, interest, time, volatility); 86 | var x = (D1); 87 | x /= spot * volatility * Math.pow(time, 0.5); 88 | return x; 89 | } 90 | 91 | function putzogamma(spot, strike, interest, time, volatility) 92 | { 93 | var D1 = d1(spot, strike, interest, time, volatility); 94 | var x = normdist(D1); 95 | x /= spot * volatility * Math.pow(time, 0.5); 96 | return x; 97 | } 98 | 99 | function otheta(spot, strike, interest, time, volatility) 100 | { 101 | var D1 = d1(spot, strike, interest, time, volatility); 102 | var D2 = d2(spot, strike, interest, time, volatility); 103 | var x = - spot*normdist(D1)*volatility; 104 | x /= 2*Math.pow(time, 0.5); 105 | x -= interest*strike*Math.exp(-interest*time)*normdistacum(D2); 106 | return x; 107 | } 108 | 109 | function putzotheta(spot, strike, interest, time, volatility) 110 | { 111 | var D1 = d1(spot, strike, interest, time, volatility); 112 | var D2 = d2(spot, strike, interest, time, volatility); 113 | var x = - spot*normdist(D1)*volatility; 114 | x /= 2*Math.pow(time, 0.5); 115 | x += interest*strike*Math.exp(-interest*time)*normdistacum(-D2); 116 | return x; 117 | } 118 | 119 | function ovega(spot, strike, interest, time, volatility) 120 | { 121 | var D1 = d1(spot, strike, interest, time, volatility); 122 | var x = spot*Math.sqrt(time)*normdist(D1); 123 | return x; 124 | } 125 | 126 | function putzovega(spot, strike, interest, time, volatility) 127 | { 128 | var D1 = d1(spot, strike, interest, time, volatility); 129 | var x = spot*Math.sqrt(time)*normdist(D1); 130 | return x; 131 | } 132 | 133 | function orho(spot, strike, interest, time, volatility) 134 | { 135 | var D2 = d2(spot, strike, interest, time, volatility); 136 | var x = strike*time*Math.exp(-interest*time)*normdistacum(D2); 137 | return x; 138 | } 139 | 140 | function putzorho(spot, strike, interest, time, volatility) 141 | { 142 | var D2 = d2(spot, strike, interest, time, volatility); 143 | var x = -strike*time*Math.exp(-interest*time)*normdistacum(-D2); 144 | return x; 145 | } 146 | 147 | 148 | function normal_strike(spot, strike, interest, time, volatility) 149 | { 150 | // Returns a normalized strike price, with average=0 and standard dev=1 151 | if (volatility < 0.0000001) { 152 | return 9999999999.9; 153 | } 154 | var x = Math.log(strike/spot) - (interest - Math.pow(volatility,2)/2) * time; 155 | x /= volatility*Math.pow(time,0.5); 156 | return x; 157 | } 158 | 159 | function stock_price_probability(strike1, strike2, spot, interest, volatility, time) 160 | { 161 | time = Math.max(time, 0.0001); 162 | volatility = Math.max(volatility, 0.001); 163 | strike1 = Math.max(strike1, 0.01); 164 | strike2 = Math.max(strike2, 0.01); 165 | var prob1 = normdistacum(normal_strike(spot, strike1, interest, time, volatility)); 166 | var prob2 = normdistacum(normal_strike(spot, strike2, interest, time, volatility)); 167 | return prob2 - prob1; 168 | } 169 | 170 | function stock_price_probability_max(spread, spot, interest, volatility, time) 171 | { 172 | // Determines the maximum probability that stock_price_probability() will return, 173 | // given a spread between strike prices (strike1 and strike2) 174 | 175 | // strike = average of expected future price 176 | var strike = spot*Math.exp((interest - Math.pow(volatility,2)/2)*time); 177 | var p = stock_price_probability(strike-spread, strike+spread, spot, interest, volatility, time); 178 | return p; 179 | } 180 | 181 | function to_days(r) 182 | { 183 | return r * 365.0; 184 | } 185 | 186 | function to_years(r_days) 187 | { 188 | return r_days / 365.0; 189 | } 190 | -------------------------------------------------------------------------------- /flot/jquery.colorhelpers.js: -------------------------------------------------------------------------------- 1 | /* Plugin for jQuery for working with colors. 2 | * 3 | * Version 1.0. 4 | * 5 | * Inspiration from jQuery color animation plugin by John Resig. 6 | * 7 | * Released under the MIT license by Ole Laursen, October 2009. 8 | * 9 | * Examples: 10 | * 11 | * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() 12 | * var c = $.color.extract($("#mydiv"), 'background-color'); 13 | * console.log(c.r, c.g, c.b, c.a); 14 | * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" 15 | * 16 | * Note that .scale() and .add() work in-place instead of returning 17 | * new objects. 18 | */ 19 | 20 | (function() { 21 | jQuery.color = {}; 22 | 23 | // construct color object with some convenient chainable helpers 24 | jQuery.color.make = function (r, g, b, a) { 25 | var o = {}; 26 | o.r = r || 0; 27 | o.g = g || 0; 28 | o.b = b || 0; 29 | o.a = a != null ? a : 1; 30 | 31 | o.add = function (c, d) { 32 | for (var i = 0; i < c.length; ++i) 33 | o[c.charAt(i)] += d; 34 | return o.normalize(); 35 | }; 36 | 37 | o.scale = function (c, f) { 38 | for (var i = 0; i < c.length; ++i) 39 | o[c.charAt(i)] *= f; 40 | return o.normalize(); 41 | }; 42 | 43 | o.toString = function () { 44 | if (o.a >= 1.0) { 45 | return "rgb("+[o.r, o.g, o.b].join(",")+")"; 46 | } else { 47 | return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")"; 48 | } 49 | }; 50 | 51 | o.normalize = function () { 52 | function clamp(min, value, max) { 53 | return value < min ? min: (value > max ? max: value); 54 | } 55 | 56 | o.r = clamp(0, parseInt(o.r), 255); 57 | o.g = clamp(0, parseInt(o.g), 255); 58 | o.b = clamp(0, parseInt(o.b), 255); 59 | o.a = clamp(0, o.a, 1); 60 | return o; 61 | }; 62 | 63 | o.clone = function () { 64 | return jQuery.color.make(o.r, o.b, o.g, o.a); 65 | }; 66 | 67 | return o.normalize(); 68 | } 69 | 70 | // extract CSS color property from element, going up in the DOM 71 | // if it's "transparent" 72 | jQuery.color.extract = function (elem, css) { 73 | var c; 74 | do { 75 | c = elem.css(css).toLowerCase(); 76 | // keep going until we find an element that has color, or 77 | // we hit the body 78 | if (c != '' && c != 'transparent') 79 | break; 80 | elem = elem.parent(); 81 | } while (!jQuery.nodeName(elem.get(0), "body")); 82 | 83 | // catch Safari's way of signalling transparent 84 | if (c == "rgba(0, 0, 0, 0)") 85 | c = "transparent"; 86 | 87 | return jQuery.color.parse(c); 88 | } 89 | 90 | // parse CSS color string (like "rgb(10, 32, 43)" or "#fff"), 91 | // returns color object 92 | jQuery.color.parse = function (str) { 93 | var res, m = jQuery.color.make; 94 | 95 | // Look for rgb(num,num,num) 96 | if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str)) 97 | return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10)); 98 | 99 | // Look for rgba(num,num,num,num) 100 | if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)) 101 | return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4])); 102 | 103 | // Look for rgb(num%,num%,num%) 104 | if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str)) 105 | return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55); 106 | 107 | // Look for rgba(num%,num%,num%,num) 108 | if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)) 109 | return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4])); 110 | 111 | // Look for #a0b1c2 112 | if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str)) 113 | return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16)); 114 | 115 | // Look for #fff 116 | if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str)) 117 | return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16)); 118 | 119 | // Otherwise, we're most likely dealing with a named color 120 | var name = jQuery.trim(str).toLowerCase(); 121 | if (name == "transparent") 122 | return m(255, 255, 255, 0); 123 | else { 124 | res = lookupColors[name]; 125 | return m(res[0], res[1], res[2]); 126 | } 127 | } 128 | 129 | var lookupColors = { 130 | aqua:[0,255,255], 131 | azure:[240,255,255], 132 | beige:[245,245,220], 133 | black:[0,0,0], 134 | blue:[0,0,255], 135 | brown:[165,42,42], 136 | cyan:[0,255,255], 137 | darkblue:[0,0,139], 138 | darkcyan:[0,139,139], 139 | darkgrey:[169,169,169], 140 | darkgreen:[0,100,0], 141 | darkkhaki:[189,183,107], 142 | darkmagenta:[139,0,139], 143 | darkolivegreen:[85,107,47], 144 | darkorange:[255,140,0], 145 | darkorchid:[153,50,204], 146 | darkred:[139,0,0], 147 | darksalmon:[233,150,122], 148 | darkviolet:[148,0,211], 149 | fuchsia:[255,0,255], 150 | gold:[255,215,0], 151 | green:[0,128,0], 152 | indigo:[75,0,130], 153 | khaki:[240,230,140], 154 | lightblue:[173,216,230], 155 | lightcyan:[224,255,255], 156 | lightgreen:[144,238,144], 157 | lightgrey:[211,211,211], 158 | lightpink:[255,182,193], 159 | lightyellow:[255,255,224], 160 | lime:[0,255,0], 161 | magenta:[255,0,255], 162 | maroon:[128,0,0], 163 | navy:[0,0,128], 164 | olive:[128,128,0], 165 | orange:[255,165,0], 166 | pink:[255,192,203], 167 | purple:[128,0,128], 168 | violet:[128,0,128], 169 | red:[255,0,0], 170 | silver:[192,192,192], 171 | white:[255,255,255], 172 | yellow:[255,255,0] 173 | }; 174 | })(); 175 | -------------------------------------------------------------------------------- /estudo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import math 4 | from blackscholes import * 5 | 6 | debug = False 7 | 8 | def le_arquivo_volatimp(time_spot): 9 | if time_spot == "current": 10 | time_spot = "" 11 | else: 12 | time_spot = "." + time_spot 13 | mapa = {} 14 | for linha in open("opcoes.txt" + time_spot).readlines(): 15 | lista = linha.split(" ") 16 | if lista[0]: 17 | mapa[lista[0]] = lista 18 | return mapa 19 | 20 | 21 | def classify(papel, dados): 22 | # codigo, tipo, premium, S, K, r, s, t, delta, gama, theta, vega, prob 23 | dados[1] = int(dados[1]) 24 | for i in range(2, len(dados)): 25 | dados[i] = float(dados[i]) 26 | obj = Opcao(papel, dados[1], dados[2:8]) 27 | return obj 28 | 29 | 30 | def classify_map(mapa): 31 | for papel in mapa.keys(): 32 | mapa[papel] = classify(papel, mapa[papel]) 33 | 34 | 35 | def nome_acao(opcao): 36 | # nome falso para a acao 37 | return opcao[0:4]+"Z00" 38 | 39 | 40 | def cria_acao_subjacente(nome, opcao): 41 | # modela acao subjacente como se fosse uma opcao de compra com K=0 42 | # premium, S, K, r, s, t 43 | dados = [opcao.S_orig(), opcao.S_orig(), 0, opcao.r(), 0, 9999] 44 | acao = Opcao(nome, 1, dados) 45 | return acao 46 | 47 | 48 | def cria_acoes_subjacentes(mapa): 49 | for papel in mapa.keys(): 50 | acao = nome_acao(papel) 51 | if acao not in mapa.keys(): 52 | mapa[acao] = cria_acao_subjacente(acao, mapa[papel]) 53 | 54 | def Ditems(time_spot): 55 | global debug 56 | debug = True 57 | return items(time_spot) 58 | 59 | def items(time_spot): 60 | result = {} 61 | mapa = le_arquivo_volatimp(time_spot) 62 | classify_map(mapa) 63 | cria_acoes_subjacentes(mapa) 64 | lista = mapa.keys() 65 | lista.sort() 66 | 67 | for papel in lista: 68 | if len(papel) != 7: 69 | continue 70 | acao = papel[0:4] 71 | serie = papel[4] 72 | strike = papel[5:7] 73 | opcao = mapa[papel] 74 | if not result.has_key(acao): 75 | result[acao] = {} 76 | if not result[acao].has_key(serie): 77 | result[acao][serie] = {} 78 | result[acao][serie]["data"] = {} 79 | result[acao][serie]["default_strike"] = strike 80 | result[acao][serie]["strike_value"] = 99999999999.0 81 | result[acao][serie]["data"][strike] = opcao.dvc() 82 | if opcao.S_orig() < opcao.K(): 83 | if opcao.K() < result[acao][serie]["strike_value"]: 84 | result[acao][serie]["default_strike"] = strike 85 | result[acao][serie]["strike_value"] = opcao.K() 86 | 87 | return result 88 | 89 | 90 | def rgb(cor): 91 | return '#%02x%02x%02x' % (cor[0] * 255, cor[1] * 255, cor[2] * 255) 92 | 93 | cbase = ((0.0, (0.0, 0.0, 1.0)), (0.25, (0.0, 1.0, 1.0)), (0.5, (0.0, 0.25, 0.0)), (0.75, (1.0, 1.0, 0.0)), (1.001, (1.0, 0.0, 0.0))) 94 | 95 | def _interpolate(c1, c2, pos): 96 | return (c1[0] * (1.0 - pos) + c2[0] * pos, \ 97 | c1[1] * (1.0 - pos) + c2[1] * pos, \ 98 | c1[2] * (1.0 - pos) + c2[2] * pos) 99 | 100 | def color_interpolate(pos): 101 | i = 0 102 | while 1: 103 | c1 = cbase[i] 104 | c2 = cbase[i+1] 105 | if c1[0] >= pos or pos <= c2[0]: 106 | break 107 | i += 1 108 | pos = (pos - c1[0]) / (c2[0] - c1[0]) 109 | return _interpolate(c1[1], c2[1], pos) 110 | 111 | 112 | def calc_cores(Tlist): 113 | if len(Tlist) <= 1: 114 | return [ rgb(color_interpolate(1.0)) ] 115 | return [rgb(color_interpolate(float(i) / (len(Tlist) - 1))) for i in range(0, len(Tlist))] 116 | 117 | 118 | def readargs(mapa, args): 119 | papeis = [] 120 | qtdes = {} 121 | if len(args) % 2 != 0: 122 | raise Exception("Bad arguments: %s" % args) 123 | for i in range(0, len(args)-1, 2): 124 | papel = args[i] 125 | try: 126 | qtde = int(args[i+1]) 127 | except ValueError: 128 | raise Exception("Bad arguments (i): %s" % args); 129 | if qtde == 0: 130 | continue 131 | if not mapa.has_key(papel): 132 | raise Exception("Papel nao existe %s" % papel) 133 | if qtdes.has_key(papel): 134 | qtdes[papel] += qtde 135 | else: 136 | papeis.append(papel) 137 | qtdes[papel] = qtde 138 | return (papeis, qtdes) 139 | 140 | def Dcalc(time_spot): 141 | global debug 142 | debug = True 143 | return calc(time_spot) 144 | 145 | def calc(time_spot): 146 | mapa = le_arquivo_volatimp(time_spot) 147 | classify_map(mapa) 148 | cria_acoes_subjacentes(mapa) 149 | papeis, qtdes = readargs(mapa, sys.argv[3:]) 150 | if not papeis: 151 | return {"graph": [], "infos": []} 152 | 153 | infos = {} 154 | for papel in papeis: 155 | infos[papel] = mapa[papel].dvc() 156 | 157 | graficos = [] 158 | # pega opcao com menor numero de dias para vencimento 159 | t = 99999 160 | for papel in papeis: 161 | opcao = mapa[papel] 162 | t = min(t, opcao.t_dias()) 163 | 164 | if t > 3650: 165 | t = 0 166 | 167 | t_inicial = t 168 | 169 | Tlist = [] 170 | step = 2.0 171 | if t > 1: 172 | step = 2.0 ** (math.log(t) / math.log(2) / 4) 173 | step = max(2.0, step) 174 | while t > 1: 175 | Tlist.append(t) 176 | t = t / step 177 | Tlist.append(0) 178 | 179 | Sorig = mapa[papeis[0]].S_orig() 180 | Smin = Sorig * 0.9 181 | Smax = Sorig * 1.1 182 | Vmin = 99999 183 | Vmax = -99999 184 | cor = calc_cores(Tlist) 185 | 186 | grafico = [] 187 | Step = (Smax - Smin) / 40.0 - 0.00001 188 | S = Smin 189 | while S < Smax: 190 | y = mapa[papeis[0]].p_exercicio(Sorig, S) * 100.0 191 | grafico.append([round(S, 2), y]) 192 | S += Step 193 | 194 | graficos.append({"data": grafico, "color": "#d0d0d0", "yaxis": 2, "label": "p = 000.00%"}) 195 | 196 | i = 0 197 | for t in Tlist: 198 | grafico = [] 199 | graficos.append({"color": cor[i], "label": "%dd = 000.00" % round(t), "data": grafico}) 200 | i += 1 201 | S = Smin 202 | 203 | while S < Smax: 204 | premio = 0 205 | for papel in papeis: 206 | opcao = mapa[papel] 207 | opcao.push() 208 | if papel[4] != "Z": 209 | # relativo pois alguma opcao pode ter vencimento mais 210 | # longo que o intervalo analisado 211 | opcao.set_t_dias(opcao.t_dias() - (t_inicial - t)) 212 | # relativo pois a opcao pode ser sobre acao diferente 213 | premio += opcao.premio(opcao.S_orig() + (S - Sorig)) * qtdes[papel] 214 | opcao.pop() 215 | 216 | grafico.append([round(S,2), round(premio, 2)]) 217 | S += Step 218 | Vmax = max(Vmax, premio) 219 | Vmin = min(Vmin, premio) 220 | 221 | graficos.append({"data": [[Sorig, Vmin], [Sorig, Vmax]], "color": "#404040", 222 | "label": "@000.00"}) 223 | return {"graph": graficos, "infos": infos} 224 | 225 | handlers = {"items": items, "Ditems": Ditems} 226 | 227 | def main(): 228 | try: 229 | if len(sys.argv) < 3: 230 | raise Exception("Argument error") 231 | req = sys.argv[1] 232 | time_spot = sys.argv[2] 233 | handler = handlers[req] 234 | txt = handler(time_spot) 235 | except Exception, e: 236 | if debug: 237 | raise 238 | print "{'err': '%s %s'}" % (str(type(e)), str(e).replace("'", "\\'").replace('"', '\\"')) 239 | return 240 | 241 | try: 242 | print txt 243 | except: 244 | pass 245 | 246 | main() 247 | -------------------------------------------------------------------------------- /estudo.js: -------------------------------------------------------------------------------- 1 | function hex(dec_cor) 2 | { 3 | var h = Math.max(0, Math.min(Math.round(dec_cor * 256), 255)).toString(16); 4 | while (h.length < 2) { 5 | h = "0" + h; 6 | } 7 | return h; 8 | } 9 | 10 | function rgb(cor) 11 | { 12 | var res = "#" + hex(cor[0]) + hex(cor[1]) + hex(cor[2]); 13 | return res; 14 | } 15 | 16 | var cbase = [[0.00, [0.0, 0.00, 1.0]], 17 | [0.25, [0.0, 0.85, 0.85]], 18 | [0.50, [0.0, 0.65, 0.0]], 19 | [0.75, [1.0, 1.00, 0.0]], 20 | [1.001, [1.0, 0.00, 0.0]]]; 21 | 22 | function _interpolate(c1, c2, pos) 23 | { 24 | return [c1[0] * (1.0 - pos) + c2[0] * pos, 25 | c1[1] * (1.0 - pos) + c2[1] * pos, 26 | c1[2] * (1.0 - pos) + c2[2] * pos]; 27 | } 28 | 29 | function color_interpolate(pos) 30 | { 31 | var i = 0; 32 | while (true) { 33 | c1 = cbase[i]; 34 | c2 = cbase[i+1]; 35 | if (c1[0] >= pos || pos <= c2[0]) { 36 | break; 37 | } 38 | i += 1; 39 | } 40 | pos = (pos - c1[0]) / (c2[0] - c1[0]); 41 | return _interpolate(c1[1], c2[1], pos); 42 | } 43 | 44 | 45 | function calc_cores(Tlist) 46 | { 47 | if (Tlist.length <= 1) { 48 | return [ rgb(color_interpolate(1.0)) ]; 49 | } 50 | 51 | cores = []; 52 | 53 | for (var i = 0; i < Tlist.length; ++i) { 54 | cores.push(rgb(color_interpolate(i / (Tlist.length - 1)))); 55 | } 56 | 57 | return cores; 58 | } 59 | 60 | function mastigar(params) 61 | { 62 | var graficos = []; 63 | 64 | var papeis = params.papeis; 65 | var qtdes = params.qtdes; 66 | 67 | if (papeis.length <= 0) { 68 | return graficos; 69 | } 70 | 71 | // pega opcao com menor numero de dias para vencimento 72 | var t = 99999; 73 | for(var pi = 0; pi < papeis.length; ++pi) { 74 | var papel = papeis[pi]; 75 | var opcao = mapa[papel]; 76 | t = Math.min(t, opcao.t_dias); 77 | } 78 | 79 | if (t > 3650) { 80 | t = 0; 81 | } 82 | 83 | var t_inicial = t; 84 | var Tlist = []; 85 | var step = 2.0; 86 | if (t > 1) { 87 | step = Math.pow(2.0, (Math.log(t) / Math.log(2) / 3.75)); 88 | } 89 | step = Math.max(2.0, step); 90 | while (t > 1) { 91 | Tlist.push(t); 92 | t = t / step; 93 | } 94 | Tlist.push(0); 95 | 96 | Sorig = mapa[papeis[0]].Sorig; 97 | Smin = Sorig * 0.9; 98 | Smax = Sorig * 1.1; 99 | Vmin = 99999.0; 100 | Vmax = -99999.0; 101 | cor = calc_cores(Tlist); 102 | 103 | var grafico = []; 104 | Step = (Smax - Smin) / 40.0 - 0.00001; 105 | S = Smin; 106 | while (S < Smax) { 107 | var y = stock_price_probability(0, S, Sorig, 108 | mapa[papeis[0]].r, 109 | mapa[papeis[0]].s, 110 | mapa[papeis[0]].t) * 100; 111 | if (mapa[papeis[0]].tipo === 1) { 112 | y = 100 - y; 113 | } 114 | grafico.push([Math.round(S*100)/100, y]); 115 | S += Step; 116 | } 117 | 118 | graficos.push({"data": grafico, "color":"#d0d0d0", 119 | "yaxis": 2, "label": "p = 000.00%"}); 120 | 121 | var i = 0; 122 | 123 | for(var ti = 0; ti < Tlist.length; ++ti) { 124 | t = Tlist[ti]; 125 | grafico = []; 126 | graficos.push({"color": cor[i], 127 | "label": Math.round(t) + "d = 000.00", 128 | "data": grafico}); 129 | i += 1; 130 | S = Smin; 131 | 132 | while (S < Smax) { 133 | var premio = 0; 134 | for (pi = 0; pi < papeis.length; ++pi) { 135 | papel = papeis[pi]; 136 | opcao = mapa[papel]; 137 | var t_dias = 0; 138 | if (papel.charAt(4) != 'Z') { 139 | t_dias = opcao.t_dias - (t_inicial - t); 140 | } 141 | if (opcao.tipo === 1) { 142 | premio += opremium(opcao.Sorig + (S - Sorig), opcao.K, 143 | opcao.r, to_years(t_dias), opcao.s) * qtdes[pi]; 144 | } else { 145 | premio += putzopremium(opcao.Sorig + (S - Sorig), opcao.K, 146 | opcao.r, to_years(t_dias), opcao.s) * qtdes[pi]; 147 | } 148 | } 149 | 150 | grafico.push([Math.round(S*100)/100, Math.round(premio*100)/100]); 151 | S += Step; 152 | Vmax = Math.max(Vmax, premio); 153 | Vmin = Math.min(Vmin, premio); 154 | } 155 | } 156 | 157 | graficos.push({"data": [[Sorig, Vmin], [Sorig, Vmax]], "color": "#404040", 158 | "label": "@000.00"}); 159 | return graficos; 160 | } 161 | 162 | var plot = null; 163 | var updateLegendTimeout = null; 164 | var latestPosition = null; 165 | var legends = null; 166 | 167 | function cleanLegend() 168 | { 169 | if (! updateLegendTimeout && plot) { 170 | var dataset = plot.getData(); 171 | for (var i = 0; i < legends.length; ++i) { 172 | var series = dataset[i]; 173 | legends.eq(i).text(series.label.replace("= 000.00", "").replace("000.00", "")); 174 | } 175 | } 176 | } 177 | 178 | function prepara_legendas() 179 | { 180 | legends = $("#graph .legendLabel"); 181 | legends.each(function () { 182 | // fix the widths so they don't jump around 183 | $(this).css('width', $(this).width()); 184 | }); 185 | 186 | updateLegendTimeout = null; 187 | latestPosition = null; 188 | setTimeout(cleanLegend, 10); 189 | } 190 | 191 | function updateLegend() 192 | { 193 | updateLegendTimeout = null; 194 | 195 | if (! plot) { 196 | return; 197 | } 198 | 199 | var pos = latestPosition; 200 | 201 | if (! pos) { 202 | return; 203 | } 204 | 205 | var axes = plot.getAxes(); 206 | if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max || pos.y < 207 | axes.yaxis.min || pos.y > axes.yaxis.max) { 208 | return; 209 | } 210 | 211 | var i, j, dataset = plot.getData(); 212 | for (i = 0; i < dataset.length - 1; ++i) { 213 | var series = dataset[i]; 214 | 215 | // find the nearest points, x-wise 216 | for (j = 1; j < series.data.length; ++j) { 217 | if (series.data[j][0] > pos.x) { 218 | break; 219 | } 220 | } 221 | 222 | // now interpolate 223 | var y, p1 = series.data[j - 1], p2 = series.data[j]; 224 | if (p1 === null) { 225 | y = p2[1]; 226 | } else if (p2 === null) { 227 | y = p1[1]; 228 | } else { 229 | y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]); 230 | } 231 | 232 | legends.eq(i).text(series.label.replace("000.00", y.toFixed(2))); 233 | } 234 | i = dataset.length - 1; 235 | var se = dataset[i]; 236 | legends.eq(i).text(se.label.replace("000.00", pos.x.toFixed(2))); 237 | } 238 | 239 | function init2() 240 | { 241 | $("#graph").bind("plothover", function (event, pos, item) { 242 | latestPosition = pos; 243 | if (! updateLegendTimeout) { 244 | updateLegendTimeout = setTimeout(updateLegend, 50); 245 | } 246 | }); 247 | 248 | $("#graph").bind("plotpan", function (event, plot) { 249 | prepara_legendas(); 250 | }); 251 | 252 | $("#graph").bind("plotzoom", function (event, plot) { 253 | prepara_legendas(); 254 | }); 255 | } 256 | 257 | function plota_graficos(dados) 258 | { 259 | $('#graph').html(""); 260 | 261 | if (dados.length <= 0) { 262 | return; 263 | } 264 | 265 | var cfg = {crosshair: { mode: "xy", color: "#c000c0" }, 266 | grid: { hoverable: true, autoHighlight: false }, 267 | zoom: {interactive: true}, 268 | pan: {interactive: true}, 269 | y2axis: {min: 0.0}}; 270 | 271 | plot = $.plot($("#graph"), dados, cfg); 272 | 273 | prepara_legendas(); 274 | } 275 | 276 | function redimensionado() 277 | { 278 | $('#graph').html(""); 279 | $('#graph').height($('#graph').width() / 16 * 10); 280 | calc(); 281 | } 282 | -------------------------------------------------------------------------------- /flot/jquery.flot.image.js: -------------------------------------------------------------------------------- 1 | /* 2 | Flot plugin for plotting images, e.g. useful for putting ticks on a 3 | prerendered complex visualization. 4 | 5 | The data syntax is [[image, x1, y1, x2, y2], ...] where (x1, y1) and 6 | (x2, y2) are where you intend the two opposite corners of the image to 7 | end up in the plot. Image must be a fully loaded Javascript image (you 8 | can make one with new Image()). If the image is not complete, it's 9 | skipped when plotting. 10 | 11 | There are two helpers included for retrieving images. The easiest work 12 | the way that you put in URLs instead of images in the data (like 13 | ["myimage.png", 0, 0, 10, 10]), then call $.plot.image.loadData(data, 14 | options, callback) where data and options are the same as you pass in 15 | to $.plot. This loads the images, replaces the URLs in the data with 16 | the corresponding images and calls "callback" when all images are 17 | loaded (or failed loading). In the callback, you can then call $.plot 18 | with the data set. See the included example. 19 | 20 | A more low-level helper, $.plot.image.load(urls, callback) is also 21 | included. Given a list of URLs, it calls callback with an object 22 | mapping from URL to Image object when all images are loaded or have 23 | failed loading. 24 | 25 | Options for the plugin are 26 | 27 | series: { 28 | images: { 29 | show: boolean 30 | anchor: "corner" or "center" 31 | alpha: [0,1] 32 | } 33 | } 34 | 35 | which can be specified for a specific series 36 | 37 | $.plot($("#placeholder"), [{ data: [ ... ], images: { ... } ]) 38 | 39 | Note that because the data format is different from usual data points, 40 | you can't use images with anything else in a specific data series. 41 | 42 | Setting "anchor" to "center" causes the pixels in the image to be 43 | anchored at the corner pixel centers inside of at the pixel corners, 44 | effectively letting half a pixel stick out to each side in the plot. 45 | 46 | 47 | A possible future direction could be support for tiling for large 48 | images (like Google Maps). 49 | 50 | */ 51 | 52 | (function ($) { 53 | var options = { 54 | series: { 55 | images: { 56 | show: false, 57 | alpha: 1, 58 | anchor: "corner" // or "center" 59 | } 60 | } 61 | }; 62 | 63 | $.plot.image = {}; 64 | 65 | $.plot.image.loadDataImages = function (series, options, callback) { 66 | var urls = [], points = []; 67 | 68 | var defaultShow = options.series.images.show; 69 | 70 | $.each(series, function (i, s) { 71 | if (!(defaultShow || s.images.show)) 72 | return; 73 | 74 | if (s.data) 75 | s = s.data; 76 | 77 | $.each(s, function (i, p) { 78 | if (typeof p[0] == "string") { 79 | urls.push(p[0]); 80 | points.push(p); 81 | } 82 | }); 83 | }); 84 | 85 | $.plot.image.load(urls, function (loadedImages) { 86 | $.each(points, function (i, p) { 87 | var url = p[0]; 88 | if (loadedImages[url]) 89 | p[0] = loadedImages[url]; 90 | }); 91 | 92 | callback(); 93 | }); 94 | } 95 | 96 | $.plot.image.load = function (urls, callback) { 97 | var missing = urls.length, loaded = {}; 98 | if (missing == 0) 99 | callback({}); 100 | 101 | $.each(urls, function (i, url) { 102 | var handler = function () { 103 | --missing; 104 | 105 | loaded[url] = this; 106 | 107 | if (missing == 0) 108 | callback(loaded); 109 | }; 110 | 111 | $('').load(handler).error(handler).attr('src', url); 112 | }); 113 | } 114 | 115 | function draw(plot, ctx) { 116 | var plotOffset = plot.getPlotOffset(); 117 | 118 | $.each(plot.getData(), function (i, series) { 119 | var points = series.datapoints.points, 120 | ps = series.datapoints.pointsize; 121 | 122 | for (var i = 0; i < points.length; i += ps) { 123 | var img = points[i], 124 | x1 = points[i + 1], y1 = points[i + 2], 125 | x2 = points[i + 3], y2 = points[i + 4], 126 | xaxis = series.xaxis, yaxis = series.yaxis, 127 | tmp; 128 | 129 | // actually we should check img.complete, but it 130 | // appears to be a somewhat unreliable indicator in 131 | // IE6 (false even after load event) 132 | if (!img || img.width <= 0 || img.height <= 0) 133 | continue; 134 | 135 | if (x1 > x2) { 136 | tmp = x2; 137 | x2 = x1; 138 | x1 = tmp; 139 | } 140 | if (y1 > y2) { 141 | tmp = y2; 142 | y2 = y1; 143 | y1 = tmp; 144 | } 145 | 146 | // if the anchor is at the center of the pixel, expand the 147 | // image by 1/2 pixel in each direction 148 | if (series.images.anchor == "center") { 149 | tmp = 0.5 * (x2-x1) / (img.width - 1); 150 | x1 -= tmp; 151 | x2 += tmp; 152 | tmp = 0.5 * (y2-y1) / (img.height - 1); 153 | y1 -= tmp; 154 | y2 += tmp; 155 | } 156 | 157 | // clip 158 | if (x1 == x2 || y1 == y2 || 159 | x1 >= xaxis.max || x2 <= xaxis.min || 160 | y1 >= yaxis.max || y2 <= yaxis.min) 161 | continue; 162 | 163 | var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height; 164 | if (x1 < xaxis.min) { 165 | sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1); 166 | x1 = xaxis.min; 167 | } 168 | 169 | if (x2 > xaxis.max) { 170 | sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1); 171 | x2 = xaxis.max; 172 | } 173 | 174 | if (y1 < yaxis.min) { 175 | sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1); 176 | y1 = yaxis.min; 177 | } 178 | 179 | if (y2 > yaxis.max) { 180 | sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1); 181 | y2 = yaxis.max; 182 | } 183 | 184 | x1 = xaxis.p2c(x1); 185 | x2 = xaxis.p2c(x2); 186 | y1 = yaxis.p2c(y1); 187 | y2 = yaxis.p2c(y2); 188 | 189 | // the transformation may have swapped us 190 | if (x1 > x2) { 191 | tmp = x2; 192 | x2 = x1; 193 | x1 = tmp; 194 | } 195 | if (y1 > y2) { 196 | tmp = y2; 197 | y2 = y1; 198 | y1 = tmp; 199 | } 200 | 201 | tmp = ctx.globalAlpha; 202 | ctx.globalAlpha *= series.images.alpha; 203 | ctx.drawImage(img, 204 | sx1, sy1, sx2 - sx1, sy2 - sy1, 205 | x1 + plotOffset.left, y1 + plotOffset.top, 206 | x2 - x1, y2 - y1); 207 | ctx.globalAlpha = tmp; 208 | } 209 | }); 210 | } 211 | 212 | function processRawData(plot, series, data, datapoints) { 213 | if (!series.images.show) 214 | return; 215 | 216 | // format is Image, x1, y1, x2, y2 (opposite corners) 217 | datapoints.format = [ 218 | { required: true }, 219 | { x: true, number: true, required: true }, 220 | { y: true, number: true, required: true }, 221 | { x: true, number: true, required: true }, 222 | { y: true, number: true, required: true } 223 | ]; 224 | } 225 | 226 | function init(plot) { 227 | plot.hooks.processRawData.push(processRawData); 228 | plot.hooks.draw.push(draw); 229 | } 230 | 231 | $.plot.plugins.push({ 232 | init: init, 233 | options: options, 234 | name: 'image', 235 | version: '1.1' 236 | }); 237 | })(jQuery); 238 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | Instruções resumidas - gerador de volatilidades implícitas de opções 2 | -------------------------------------------------------------------- 3 | 4 | 5 | FUNCIONAMENTO BASICO 6 | -------------------- 7 | 8 | O gerador é um conjunto de scripts que pega dados de diversas fontes, 9 | e gera uma página Web com diversos dados a respeito de opções, inclusive 10 | suas volatilidades implícitas. 11 | 12 | Uma vez configurado o ambiente, o gerador é bastante auto-suficiente, ele 13 | foi desenvolvido para funcionar sem necessidade de intervenção. Apenas 14 | mudanças no rol de opções exigem alterações nos scripts. 15 | 16 | O uso 'normal' do gerador consiste simplesmente em rodar o script 17 | volatimp_cblc.sh uma vez por dia, e depois rodar o script volatimp.sh 18 | periodicamente, para atualizar a página Web (volatimp.php) com as 19 | cotações mais recentes. 20 | 21 | O script volatimp_cblc.sh, como o nome sugere, obtém um arquivo da CBLC 22 | que contém alguns dados das séries de opções autorizadas (strike, 23 | data de vencimento, ticket, entre outras). Ele também roda o programa 24 | calcvol.py, que obtém a série histórica das ações subjacentes via 25 | Yahoo, com o objetivo de calcular a volatilidade histórica. 26 | 27 | O script volatimp.sh não faz muito mais que invocar o programa volatimp.py, 28 | que por sua vez obtém as cotações mais recentes das opções (via site 29 | Bovespa) e gera a página 'volatimp.php', além de um arquivo-texto com os 30 | mesmos dados. 31 | 32 | 33 | FONTES DE INFORMAÇÃO 34 | -------------------- 35 | 36 | Conforme foi dito, são utilizadas as seguintes fontes: CBLC, Yahoo e 37 | site Bovespa. Das três, a única "oficial" e confiável é a CBLC. As 38 | outras duas são serviços livres, com atraso variável e que podem sair 39 | do ar a qualquer momento. 40 | 41 | Em particular a obtenção de cotações de opções via site Bovespa é um 42 | truque "sujo", e que falha bastante. O ideal para um uso "sério" deste 43 | gerador seria utilizar uma fonte de dados mais confiável (provavelmente 44 | paga). Isto implicaria em modificar os programas calcvol.py e volatimp.py. 45 | 46 | 47 | COMO CONFIGURAR AS OPÇÕES/SÉRIES QUE VÃO PARA A PÁGINA 48 | ------------------------------------------------------ 49 | 50 | É preciso modificar os scripts calcvol.py e volatimp.py. Ambos têm uma 51 | tabela de ações subjacentes (e.g. PETR4, VALE5). As opções destas ações 52 | é que vão aparecer na página final. 53 | 54 | Por padrão, 2 séries de opções (deste mês e do próximo) são exibidas. 55 | O dia do vencimento é determinado automaticamente. Se quiser mais 56 | séries futuras, mude a variável 'meses', logo no início do programa 57 | calcvol.py 58 | 59 | 60 | TAXA DE JUROS 61 | ------------- 62 | 63 | A taxa de juros também é obtida automaticamente do site do Banco central 64 | pelo script taxajuros.py, e armazenada no arquivo taxajuros.txt. Caso haja 65 | problemas com o script, a última taxa contida em taxajuros.txt é 66 | utilizada. 67 | 68 | 69 | ESTUDO GRÁFICO 70 | -------------- 71 | 72 | Além das volatilidades implícitas, há uma página de estudo gráfico das opções, 73 | que mostra como o valor do prêmio vai comportar-se conforme vai chegando o 74 | vencimento. Permite também 'montar' operações com diversas opções e ver 75 | o comportamento do conjunto todo. 76 | 77 | Este estudo (página estudo.php) depende do arquivo-texto 'opcoes.txt', que 78 | também é gerado pelo programa 'volatimp.py'. 79 | 80 | Os scripts volatimp_cblc.sh e volatimp.sh também encarregam-se de salvar versões 81 | antigas de todos os arquivos gerados, de forma a ser possível analisar cenários 82 | passados. 83 | 84 | Se o gerador de volatilidades implícitas estiver funcionando bem, o estudo também 85 | deverá funcionar ok. 86 | 87 | Há diversas versões do estudo gráfico: 88 | 89 | estudo.php: padrão. 90 | 91 | estudolivro.php: permite passar um parâmetro que lê versões antigas do arquivo 92 | opcoes.txt. Isto é interessante quando é necessário gerar sempre o mesmo 93 | gráfico de forma estável, ou quando quisermos consultar um estudo passado 94 | (ou seja, baseado numa situação de mercado passada). 95 | 96 | Como o próprio nome sugere, utilizei esta versão para gerar os gráficos contidos 97 | em meu livro "Ganhando dinheiro com opções". 98 | 99 | estudo3d.php: tentativa de fazer o gráfico em 3D em vez de usar diversas linhas 100 | 101 | estudovenda.php: estudo com opções de venda simuladas. 102 | 103 | 104 | TECNOLOGIA 105 | ---------- 106 | 107 | Todo o gerador foi escrito utilizando linguagens interpretadas. Ao todo, 108 | quatro linguagens foram usadas: Python, PHP, Javascript e Shell; 109 | cada uma onde mais bem desempenha seu papel. 110 | 111 | Os scripts volatimp_cblc.sh e volatimp.sh são escritos em Shell, e foram 112 | feitos para serem executados periodicamente (crontab). Se você quiser 113 | portar o gerador para Windows, deverá traduzir estes scripts para alguma 114 | tecnologia de scripting do Windows (que eu não conheço, mas existe). 115 | 116 | 117 | VERSÕES ANTIGAS 118 | --------------- 119 | 120 | Como já foi dito, os scripts Shell salvam versões antigas de todos os 121 | arquivos gerados, para consulta posterior. 122 | 123 | Para que não haja conflitos, cada arquivo "velho" tem um nome único, 124 | baseado na data e hora. 125 | 126 | Por exemplo, o arquivo 'opcoes.txt' gerado no dia 30/09/2011 às 15:13 127 | é copiado para opcoes.txt.201109301513. 128 | 129 | Desde que o script 'volatimp.sh' não seja rodado mais que uma vez por 130 | minuto, o esquema guarda toda a informação antiga. (E se for necessário 131 | rodá-lo mais que uma vez por minuto, é fácil modificar o script para 132 | que ele guarde arquivos com precisão de segundo ou centésimo.) 133 | 134 | Os arquivos gerados pelo script volatimp_cblc.sh levam apenas a data, 135 | não a hora, porque são gerados apenas uma vez por dia, e (presumo) 136 | seus dados nunca mudam durante o dia. 137 | 138 | 139 | 140 | LISTA DE ARQUIVOS 141 | ----------------- 142 | 143 | volatimp_cblc.sh Script que obtém o arquivo CBLC e chama calcvol.py (volatilidades opções) 144 | e também obtém a taxa de juros 145 | calcvol.py Programa que calcula volatilidades das ações 146 | volatilidades.txt Volatilidades das ações, calculadas por calcvol.py 147 | volatilidades.txt.* Versões antigas do arquivo acima 148 | cblc.txt Arquivo com dados das opções, obtido da CBLC 149 | cblc.txt.* Versões antigas do arquivo CBLC 150 | taxajuros.txt Taxa-base de juros 151 | taxajuros.txt.* Versões antigas do arquivo de juros 152 | 153 | volatimp.sh Script que chama volatimp.py (volatilidades implícitas) 154 | volatimp.py Programa que calcula volatilidades implícitas das opções 155 | e gera a página 'volatimp.php' 156 | 157 | taxajuros.py Script que obtém a taxa de juros e preenche taxajuros.txt. 158 | 159 | blackscholes.py Módulo auxiliar aos programas acima (Black-Scholes) 160 | ystockquote.py Idem (Serve para obter série histórica das ações via Yahoo!) 161 | volatimp.js Script auxiliar da página volatimp.php 162 | 163 | volatimp.php A página de volatilidades implícitas de opções 164 | 165 | volatimp.*.php Cópias antigas da página acima. O script volatimp.sh 166 | guarda um arquivo com data/hora de cada página gerada. 167 | 168 | opcoes.txt Arquivo com dados (gregas etc.) das opções. Este arquivo 169 | é gerado para alimentar o estudo gráfico (visto mais abaixo) 170 | 171 | opcoes.txt.* Cópias antigas do arquivo opcoes.txt. Serve para o estudo 172 | gráfico e também pode servir para análise posterior dos dados 173 | (algotrading etc.) 174 | 175 | *.pyc Tipo de arquivo gerado ao executar um programa .py 176 | (pode ser ignorado ou apagado) 177 | 178 | arp.css Arquivo auxiliar da página volatimp.php 179 | bs.css Idem 180 | lib.php Idem 181 | 182 | Daqui para frente, os arquivos não têm mais relação direta com a página 183 | de volatilidades implícitas. 184 | 185 | estudo.php Página de estudo gráfico de opções 186 | Faz uso dos dados de 'opcoes.txt', gerados pelo 187 | script volatimp.py. 188 | 189 | estudo_common.js Arquivo auxiliar da página estudo.php 190 | estudo.js Idem 191 | estudo.css Idem 192 | estudo.py Invocado para obter os dados de 'opcoes.txt' 193 | estudo3.php Trampolim PHP para invocar estudo.py 194 | 195 | blackscholes.js Arquivo auxiliar da página estudo.php 196 | throbber.gif Idem 197 | jquery.js Biblioteca jQuery 198 | jquery.jstore-all.js Plug-in jStore para jQuery 199 | flot Plug-in flot para jQuery (gerador de gráficos) 200 | 201 | estudo3d.php Estudo gráfico em 3D (ou pelo menos uma tentativa) 202 | estudo3d.fshader Arquivo auxiliar do estudo 3D 203 | estudo3d.js Idem 204 | estudo3d.vshader Idem 205 | estudo3d.wad Idem 206 | 207 | estudolivro.php Estudo gráfico, pode ler versões antigas dos arquivos 208 | de modo a obter sempre o mesmo gráfico (já que o 209 | arquivo mais atual está sempre sendo atualizado) 210 | estudolivro.js Arquivo auxiliar do estudo acima 211 | 212 | estudovenda.php Estudo gráfico para opções de venda 213 | estudovenda.js Arquivo auxiliar do estudo acima 214 | estudovenda.py Idem 215 | estudovenda3.php Idem 216 | estudovenda_common.js Idem 217 | 218 | stwatchdog.py Protótipo de robô para monitorar 'stops' 219 | -------------------------------------------------------------------------------- /blackscholes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | import math 5 | 6 | def d1(S, K, r, s, t): 7 | return (math.log(S/float(K)) + (r+(s*s)/2.0)*t) / (s*math.sqrt(t)) 8 | 9 | def d2(S, K, r, s, t): 10 | return d1(S, K, r, s, t) - s*math.sqrt(t) 11 | 12 | def N(x): 13 | if x < 0: 14 | return 1.0 - N(-x) 15 | xp = x 16 | p = 1.0 + N.kd1 * xp 17 | xp *= x 18 | p += N.kd2 * xp 19 | xp *= x 20 | p += N.kd3 * xp 21 | xp *= x 22 | p += N.kd4 * xp 23 | xp *= x 24 | p += N.kd5 * xp 25 | xp *= x 26 | p += N.kd6 * xp 27 | p *= p 28 | p *= p 29 | p *= p 30 | p *= p 31 | return 1.0 - 0.5 * (1.0 / p) 32 | 33 | N.kd1 = 0.0498673470 34 | N.kd3 = 0.0032776263 35 | N.kd5 = 0.0000488906 36 | N.kd2 = 0.0211410061 37 | N.kd4 = 0.0000380036 38 | N.kd6 = 0.0000053830 39 | 40 | def dN(x): 41 | n = math.exp(-(x*x/2.0)) 42 | n /= math.sqrt(2*math.pi) 43 | return n 44 | 45 | def Call(S, K, r, s, t): 46 | if t < 0.0000000001 or s < 0.00000000001: 47 | return max(S - K, 0.0) 48 | return S*N(d1(S, K, r, s, t)) - K*math.exp(-r*t)*N(d2(S, K, r, s, t)) 49 | 50 | def Put(S, K, r, s, t): 51 | if t < 0.0000000001 or s < 0.00000000001: 52 | return max(K - S, 0.0) 53 | return - S*N(-d1(S, K, r, s, t)) + K*math.exp(-r*t)*N(-d2(S, K, r, s, t)) 54 | 55 | def implied_volatility(type, premium, S, K, r, s_dummy, t): 56 | if S <= 0.000001 or K <= 0.000001 or t <= 0.000001 or premium <= 0.000001: 57 | return 0.0 58 | 59 | s = 0.35 60 | 61 | for cycle in range(0, 120): 62 | ext_premium = type(S, K, r, s, t) 63 | if abs(premium - ext_premium) < 0.005: 64 | return s 65 | ext_vega = type.vega(S, K, r, s, t) 66 | # print S, K, r, s, t, premium, ext_premium, ext_vega 67 | if ext_vega < 0.0000001: 68 | # Avoids zero division if stuck 69 | ext_vega = 0.0000001 70 | 71 | s_new = s - (ext_premium - premium) / ext_vega 72 | if abs(s_new - s) > 1.00: 73 | # estimated s is too different from previous; 74 | # it is better to go linearly, since 75 | # vega is too small to give a good guess 76 | if s_new > s: 77 | s += 1.0 78 | else: 79 | s -= 1.0 80 | else: 81 | s = s_new 82 | 83 | if s < 0.0: 84 | # No volatility < 0% 85 | s = 0.0001 86 | if s > 99.99: 87 | # No point calculating volatilities > 9999%/year 88 | return 100.0 89 | 90 | return 0.0 91 | 92 | def CallDelta(S, K, r, s, t): 93 | x = N(d1(S, K, r, s, t)) 94 | return x 95 | 96 | def PutDelta(S, K, r, s, t): 97 | x = N(d1(S, K, r, s, t)) - 1.0 98 | return x 99 | 100 | def CallGamma(S, K, r, s, t): 101 | D1 = d1(S, K, r, s, t) 102 | x = dN(D1) 103 | x /= S * s * math.sqrt(t) 104 | return x 105 | 106 | def PutGamma(S, K, r, s, t): 107 | D1 = d1(S, K, r, s, t) 108 | x = dN(D1) 109 | x /= S * s * math.sqrt(t) 110 | return x 111 | 112 | def CallTheta(S, K, r, s, t): 113 | D1 = d1(S, K, r, s, t) 114 | D2 = d2(S, K, r, s, t) 115 | x = - S*dN(D1)*s 116 | x /= 2.0 * math.sqrt(t) 117 | x -= r*K*math.exp(-r*t)*N(D2) 118 | return x 119 | 120 | def PutTheta(S, K, r, s, t): 121 | D1 = d1(S, K, r, s, t) 122 | D2 = d2(S, K, r, s, t) 123 | x = - S*dN(D1)*s 124 | x /= 2.0 * math.sqrt(t) 125 | x += r*K*math.exp(-r*t)*N(-D2) 126 | return x 127 | 128 | def CallVega(S, K, r, s, t): 129 | D1 = d1(S, K, r, s, t) 130 | x = S*math.sqrt(t)*dN(D1) 131 | return x 132 | 133 | def PutVega(S, K, r, s, t): 134 | D1 = d1(S, K, r, s, t) 135 | x = S*math.sqrt(t)*dN(D1) 136 | return x 137 | 138 | def normal_strike(S, K, r, s, t): 139 | if s < 0.0000001: 140 | return 9999999999.9 141 | x = math.log(float(K)/S) - (r - (s*s)/2.0) * t 142 | x /= s * math.sqrt(t) 143 | return x 144 | 145 | def stock_price_probability_below_K(S, K, r, s, t): 146 | t = max(t, 0.0001) 147 | s = max(s, 0.0001) 148 | K = max(K, 0.0001) 149 | return N(normal_strike(S, K, r, s, t)) 150 | 151 | def stock_price_dprobability_below_K(S, K, r, s, t): 152 | t = max(t, 0.0001) 153 | s = max(s, 0.0001) 154 | K = max(K, 0.0001) 155 | return dN(normal_strike(S, K, r, s, t)) 156 | 157 | def stock_price_dprobability_above_K(S, K, r, s, t): 158 | t = max(t, 0.0001) 159 | s = max(s, 0.0001) 160 | K = max(K, 0.0001) 161 | return dN(-normal_strike(S, K, r, s, t)) 162 | 163 | def CallProb(S, K, r, s, t): 164 | return 1.0 - stock_price_probability_below_K(S, K, r, s, t) 165 | 166 | def CalldProb(S, K, r, s, t): 167 | return stock_price_dprobability_above_K(S, K, r, s, t) 168 | 169 | def PutProb(S, K, r, s, t): 170 | return stock_price_probability_below_K(S, K, r, s, t) 171 | 172 | def PutdProb(S, K, r, s, t): 173 | return stock_price_dprobability_below_K(S, K, r, s, t) 174 | 175 | Call.delta = CallDelta 176 | Call.gamma = CallGamma 177 | Call.theta = CallTheta 178 | Call.vega = CallVega 179 | Call.prob = CallProb 180 | Call.dprob = CalldProb 181 | 182 | Put.delta = PutDelta 183 | Put.gamma = PutGamma 184 | Put.theta = PutTheta 185 | Put.vega = PutVega 186 | Put.prob = PutProb 187 | Put.dprob = PutdProb 188 | 189 | class Opcao(object): 190 | def __init__(this, papel, tipo, data): 191 | this.papel = papel 192 | this.tipo = {1: Call, 2: Put}[tipo] 193 | this.Spremio = data[0] 194 | this.SS = data[1] 195 | this.data = data[2:] 196 | this.originaldata = data[3:] 197 | this.stack = [] 198 | old_s = this.s() 199 | this.update_volatility() 200 | if old_s != 0 and abs(this.s() - old_s) > 0.01: 201 | raise Exception("Informed implied volatility too different: %f x %f" % (old_s, this.s())) 202 | 203 | def dvc(this): 204 | tipo = 1 205 | if this.is_put(): 206 | tipo = 2 207 | return {"K": this.K(), "s": this.s(), "r": this.r(), "t": this.t(), \ 208 | "t_dias": this.t_dias(), "Sorig": this.S_orig(), "tipo": tipo, 209 | "premio": this.Spremio} 210 | 211 | def update_volatility(this): 212 | this.set_s(implied_volatility(this.tipo, this.Spremio, this.SS, *this.data)) 213 | 214 | def premio(this, S=0): 215 | if S == 0: 216 | S = this.SS 217 | return this.tipo(S, *this.data) 218 | 219 | def premio_orig(this): 220 | return this.Spremio 221 | 222 | def delta(this, S=0): 223 | if S == 0: 224 | S = this.SS 225 | return tipo.delta(S, *this.data) 226 | 227 | def gamma(this, S=0): 228 | if S == 0: 229 | S = this.SS 230 | return tipo.gamma(S, *this.data) 231 | 232 | def theta(this, S=0): 233 | if S == 0: 234 | S = this.SS 235 | return tipo.theta(S, *this.data) 236 | 237 | def vega(this, S=0): 238 | if S == 0: 239 | S = this.SS 240 | return tipo.vega(S, *this.data) 241 | 242 | def p_exercicio(this, S, K): 243 | return this.tipo.prob(S, K, this.r(), this.s(), this.t()) 244 | 245 | def dp_exercicio(this, S, K): 246 | return this.tipo.dprob(S, K, this.r(), this.s(), this.t()) 247 | 248 | def S_orig(this): 249 | return this.SS 250 | 251 | def K(this): 252 | return this.data[0] 253 | 254 | def r(this): 255 | return this.data[1] 256 | 257 | def s(this): 258 | return this.data[2] 259 | 260 | def t(this): 261 | return this.data[3] 262 | 263 | def t_dias(this): 264 | return this.para_dia(this.t()) 265 | 266 | def push(this): 267 | this.stack.append(this.data[:]) 268 | 269 | def pop(this): 270 | this.data = this.stack.pop() 271 | 272 | def set_K(this, v): 273 | this.data[0] = v 274 | 275 | def set_r(this, v): 276 | this.data[1] = v 277 | 278 | def set_s(this, v): 279 | this.data[2] = v 280 | 281 | def set_t(this, v): 282 | this.data[3] = v 283 | 284 | def set_t_dias(this, v): 285 | this.set_t(this.para_ano(v)) 286 | 287 | def para_dia(this, v): 288 | return v * 365.0 289 | 290 | def para_ano(this, v): 291 | return v / 365.0 292 | 293 | def is_put(this): 294 | return this.tipo is Put 295 | 296 | def is_call(this): 297 | return this.tipo is Call 298 | 299 | testes = ( 300 | (950.0, 1000.0, 0.09, 0.30, 30.0 / 365.0, 16.25, 58.88), 301 | (1000.0, 1000.0, 0.09, 0.30, 30.0 / 365.0, 37.99, 30.62), 302 | (1100.0, 1000.0, 0.09, 0.30, 30.0 / 365.0, 112.47, 5.10), 303 | (1100.0, 1000.0, 0.09, 0.30, 0.0 / 365.0, 100.0, 0.00), 304 | (900.0, 1000.0, 0.09, 0.30, 0.0 / 365.0, 0.0, 100.00), 305 | (1000.0, 1000.0, 0.09, 0.30, 0.0 / 365.0, 0.0, 0.00), 306 | ) 307 | 308 | for teste in testes: 309 | c = Call(*(teste[0:5])) 310 | p = Put(*(teste[0:5])) 311 | assert(abs(c - teste[5]) < 0.005) 312 | assert(abs(p - teste[6]) < 0.005) 313 | 314 | def patch_for_fast(): 315 | global Call, Put, N, d1, d2, dN 316 | import bsfast 317 | teste = testes[0][0:5] 318 | assert(abs(Call(*teste) - bsfast.Call(*teste)) < 0.000000001) 319 | assert(abs(Put(*teste) - bsfast.Put(*teste)) < 0.000000001) 320 | Call = bsfast.Call 321 | Put = bsfast.Put 322 | N = bsfast.N 323 | d1 = bsfast.d1 324 | d2 = bsfast.d2 325 | dN = bsfast.dN 326 | -------------------------------------------------------------------------------- /estudovenda_common.js: -------------------------------------------------------------------------------- 1 | var arvore = {}; 2 | var mapa = {}; 3 | var semaforo_calculo = 0; 4 | var semaforo_throbber = 2; 5 | var livro = null; 6 | var infolivro = null; 7 | var storage = null; 8 | var nomes_opcoes = []; 9 | var calc = null; 10 | var infos = null; 11 | var RATIO = 5; 12 | 13 | function suspende_calculo() 14 | { 15 | ++semaforo_calculo; 16 | } 17 | 18 | suspende_calculo(); 19 | 20 | function libera_calculo() 21 | { 22 | if (semaforo_calculo > 0) { 23 | --semaforo_calculo; 24 | } 25 | } 26 | 27 | function calculo_liberado() 28 | { 29 | return semaforo_calculo <= 0; 30 | } 31 | 32 | function throbber(show) 33 | { 34 | var semaforo_old = semaforo_throbber > 0; 35 | if (show) { 36 | ++semaforo_throbber; 37 | if (! semaforo_old) { 38 | $("#throbber").fadeIn(); 39 | } 40 | } else if (semaforo_throbber > 0) { 41 | --semaforo_throbber; 42 | if (semaforo_old) { 43 | $("#throbber").fadeOut(); 44 | } 45 | } 46 | } 47 | 48 | function muda_strike(sstrike) 49 | { 50 | calc(); 51 | } 52 | 53 | function muda_qtde(sqtde) 54 | { 55 | calc(); 56 | } 57 | 58 | function muda_serie(sserie) 59 | { 60 | var serie = arvore[$(livro[0]).val()]; 61 | if (! serie) { 62 | return; 63 | } 64 | var strikes = serie[$(sserie).val()]; 65 | if (! strikes || ! strikes.data) { 66 | return; 67 | } 68 | 69 | suspende_calculo(); 70 | 71 | var o = $("#"+$(sserie).attr('id')+"k").get(0); 72 | var old = $(o).val(); 73 | if (! old) { 74 | old = strikes.default_strike; 75 | } 76 | 77 | $(o).children().remove().end(); 78 | 79 | var listrikes = []; 80 | for(var val in strikes.data) { 81 | if (typeof val != "function") { 82 | listrikes.push("" + val); 83 | } 84 | } 85 | listrikes.sort(); 86 | 87 | var i = 0; 88 | for (var j = 0; j < listrikes.length; ++j) { 89 | strike = listrikes[j]; 90 | if (typeof strike != "function") { 91 | o.options[i++] = new Option(strike, strike); 92 | if (strike === old) { 93 | $(o.options[i-1]).attr('selected', 1); 94 | } 95 | } 96 | } 97 | muda_strike(o); 98 | 99 | libera_calculo(); 100 | calc(); 101 | } 102 | 103 | function muda_acao() 104 | { 105 | var acao = $(livro[0]).val(); 106 | var serie = arvore[acao]; 107 | if (! serie) { 108 | return; 109 | } 110 | 111 | suspende_calculo(); 112 | 113 | $(".strike").each(function() { 114 | $(this).children().remove().end(); 115 | }); 116 | 117 | $(".serie").each(function() { 118 | var o = this; 119 | var old = $(o).val(); 120 | var i = 0; 121 | $(o).children().remove().end(); 122 | liserie = []; 123 | for (var val in serie) { 124 | if (typeof val != "function") { 125 | liserie.push(val); 126 | } 127 | } 128 | liserie.sort(); 129 | for (var j = 0; j < liserie.length; ++j) { 130 | val = liserie[j]; 131 | o.options[i++] = new Option(val, val); 132 | if (val === old) { 133 | $(o.options[i-1]).attr('selected', 1); 134 | } 135 | } 136 | muda_serie(o); 137 | }); 138 | 139 | libera_calculo(); 140 | calc(); 141 | } 142 | 143 | calc = function() 144 | { 145 | if (! calculo_liberado()) { 146 | return; 147 | } 148 | 149 | compactar(); 150 | 151 | var params = {}; 152 | params.qtdes = []; 153 | params.papeis = []; 154 | for (var i = 0; i < infolivro.length; ++i) { 155 | if (! nomes_opcoes[i]) { 156 | continue; 157 | } 158 | var qtde = $("#s" + (i+1) + "kqtde"); 159 | if (! qtde) { 160 | continue; 161 | } 162 | qtde = parseInt($(qtde).val(), 10); 163 | if (! qtde) { 164 | continue; 165 | } 166 | params.papeis.push(nomes_opcoes[i]); 167 | params.qtdes.push(qtde); 168 | } 169 | 170 | dados = mastigar(params); 171 | plota_graficos(dados); 172 | infos(); 173 | return true; 174 | }; 175 | 176 | function init() 177 | { 178 | livro = [$('#acao').get(0), 179 | $('#s1').get(0), $('#s1k').get(0), $('#s1kqtde').get(0), 180 | $('#s2').get(0), $('#s2k').get(0), $('#s2kqtde').get(0), 181 | $('#s3').get(0), $('#s3k').get(0), $('#s3kqtde').get(0), 182 | $('#s4').get(0), $('#s4k').get(0), $('#s4kqtde').get(0)]; 183 | infolivro = [$('#s1kinfo').get(0), $('#s2kinfo').get(0), 184 | $('#s3kinfo').get(0), $('#s4kinfo').get(0)]; 185 | 186 | var n = 0; 187 | var i = 0; 188 | 189 | $('.qtde').each(function() { 190 | for(i = -RATIO; i <= RATIO; ++i) { 191 | var o = new Option(""+i, ""+i); 192 | if (i === 0) { 193 | $(o).attr('selected', 'true'); 194 | } 195 | this.options[i+5] = o; 196 | } 197 | }); 198 | 199 | i = 0; 200 | liacoes = []; 201 | for (var acao in arvore) { 202 | if (typeof acao != "function") { 203 | liacoes.push(acao); 204 | var Oacao = arvore[acao]; 205 | for (var serie in Oacao) { 206 | if (typeof serie != "function") { 207 | var Oserie = Oacao[serie].data; 208 | for (var strike in Oserie) { 209 | if (typeof strike != "function") { 210 | mapa[acao + serie + strike] = Oserie[strike]; 211 | } 212 | } 213 | } 214 | } 215 | } 216 | } 217 | liacoes.sort(); 218 | for (var j = 0; j < liacoes.length; ++j) { 219 | nome = liacoes[j]; 220 | livro[0].options[i++] = new Option(nome, nome); 221 | } 222 | 223 | muda_acao(); 224 | } 225 | 226 | function init3() 227 | { 228 | libera_calculo(); 229 | libera_calculo(); 230 | 231 | jQuery.extend(jQuery.jStore.defaults, 232 | {project: 'estudoopcoes', 233 | flash: 'jStore.Flash.html'}); 234 | jQuery.jStore.load(); 235 | } 236 | 237 | infos = function() 238 | { 239 | for (var i = 0; i < infolivro.length; ++i) { 240 | $(infolivro[i]).html(""); 241 | } 242 | 243 | for (i = 0; i < infolivro.length; ++i) { 244 | var codigo = nomes_opcoes[i]; 245 | if (! codigo) { 246 | continue; 247 | } 248 | var info = mapa[codigo]; 249 | if (! info) { 250 | continue; 251 | } 252 | $(infolivro[i]).html("$" + info.premio.toFixed(2) + "   " + 253 | "K=" + info.K.toFixed(2) + "   σ=" + 254 | (info.s * 100.0).toFixed(1) + "%   " + 255 | info.t_dias.toFixed(0) + "d"); 256 | } 257 | }; 258 | 259 | function calcula_nomes_opcoes(zeros) 260 | { 261 | var acao = $(livro[0]).val(); 262 | 263 | // guardar nomes para referencia qdo voltar os infos da opcao 264 | nomes_opcoes = []; 265 | 266 | var params = ""; 267 | for (var i = 0; i < infolivro.length; ++i) { 268 | nomes_opcoes[i] = ""; 269 | if (! acao || acao.length != 4) { 270 | continue; 271 | } 272 | var serie = $("#s" + (i+1)).val(); 273 | if (! serie || serie.length != 1) { 274 | continue; 275 | } 276 | var strike = $("#s" + (i+1) + "k").val(); 277 | if (! strike || strike.length != 2) { 278 | continue; 279 | } 280 | if (! zeros) { 281 | var qtde = parseInt($("#s" + (i+1) + "kqtde").val(), 10); 282 | if (! qtde) { 283 | continue; 284 | } 285 | } 286 | var nome = acao + serie + strike; 287 | nomes_opcoes[i] = nome; 288 | } 289 | } 290 | 291 | // FIXME: compactar valores que não são relativamente primos 292 | 293 | function compactar2() 294 | { 295 | calcula_nomes_opcoes(true); 296 | 297 | for (var i = infolivro.length - 1; i >= 0; --i) { 298 | var alto = nomes_opcoes[i]; 299 | for (var j = i - 1; j >= 0; --j) { 300 | var baixo = nomes_opcoes[j]; 301 | 302 | if (baixo === alto) { 303 | // coincidentes; compactar 304 | var qalto = $("#s" + (i+1) + "kqtde"); 305 | var qbaixo = $("#s" + (j+1) + "kqtde"); 306 | var qtdenova = parseInt(qalto.val(), 10) + 307 | parseInt(qbaixo.val(), 10); 308 | if (qtdenova >= -RATIO && qtdenova <= RATIO) { 309 | qbaixo.val("" + qtdenova); 310 | } 311 | qalto.val("0"); 312 | nomes_opcoes[i] = "VOID!"; 313 | alto = "VOID!"; 314 | break; 315 | } 316 | } 317 | } 318 | 319 | calcula_nomes_opcoes(false); 320 | } 321 | 322 | function compactar() 323 | { 324 | compactar2(); 325 | } 326 | 327 | $(document).ready(function() { 328 | redimensionado(); 329 | window.onresize = redimensionado; 330 | var url = "estudovenda3.php"; 331 | $.getJSON(url, function (dados) { 332 | if (dados.err) { 333 | alert(dados.err); 334 | } else { 335 | arvore = dados; 336 | init(); 337 | init2(); 338 | init3(); 339 | } 340 | throbber(false); 341 | }); 342 | }); 343 | -------------------------------------------------------------------------------- /estudo.php: -------------------------------------------------------------------------------- 1 | 2 | '); ?> 3 | 4 | 10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |

AVISO: este aplicativo é apenas um brinquedo, utiliza dados de fontes públicas e 26 | gratuitas (Yahoo, CBLC e Bovespa), e executa grande parte da matemática no seu 27 | navegador. Portanto, não nos responsabilizamos pela exatidão das informações, 28 | nem pelo uso dos dados e gráficos em operações financeiras. 29 | 30 |

31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
--
41 |
42 | throbber 43 |
44 |
--
--
--
63 |
64 |
65 |
66 | 67 |

Modo de usar

68 | 69 | O estudo gráfico foi uma ferramenta desenvolvida para o livro "Ganhando 70 | dinheiro com opções" que escrevi em 2010. Uma explanação bastante completa 71 | está no tópico 2.32 do livro. Vou copiá-la parcialmente aqui. A operação abaixo, 72 | uma trava de alta, "fotografada" no final do dia 3/Jan/2013, será nossa cobaia: 73 | 74 |

75 | Imagem de ajuda 76 | 77 |

78 | A trava de alta em estudo é PETRA20/PETRA22. Note como elas foram escolhidas nas 79 | caixas de seleção (ação, série, strike). Como na trava de alta compramos 80 | a opção baixa e vendemos a alta, escolhemos as proporções +1 e -1 respectivamente. 81 | Numa trava de baixa PETRA20/22 apenas as proporções seriam invertidas, pois 82 | venderíamos a baixa. 83 | 84 |

85 | Também é possível estudar operações a seco, operações assimétricas, e mesmo 86 | operações cobertas. A "série Z" na caixa de seleção é a ação subjacente. 87 | Uma venda coberta ATM seria composta por PETRZ (na proporção +1) e PETRA20 88 | (na proporção -1). 89 | 90 |

91 | Ao lado de cada opção selecionada, são exibidos, nesta ordem: prêmio da opção 92 | (o mais atual obtido pelo sistema), strike (K), volatilidade implícita (letra 93 | grega sigma) e o prazo até o vencimento, em dias corridos. 94 | 95 |

96 | O aspecto mais importante do gráfico é que ele mostra o valor da carteira. 97 | A trava de alta custou 0,43 por opção para montar (0,51 da compra, menos 0,08 da venda). 98 | Ganhamos dinheiro quando a operação ganha valor, de modo que possamos 99 | desmontá-la com lucro. 100 | 101 |

102 | O eixo horizontal (X) é o valor da ação subjacente (PETR4 no caso). Quando o gráfico 103 | foi fotografado ela valia em torno de 19,80. 104 | 105 |

106 | O eixo vertical (Y) é o valor da carteira estudada (trava de alta). A curva azul-escura 107 | mostra o valor da carteira no dia de hoje em função de PETR4. 108 | 109 |

110 | Exatamente no meio do gráfico, há uma linha vertical preta; é o valor de PETR4 no 111 | momento da fotografia. O cruzamento desta linha com a curva azul-escura representa o 112 | valor da carteira no mesmo momento: 0,43. 113 | 114 |

115 | As demais curvas coloridas mostram o valor da carteira em momentos futuros, até chegar 116 | ao vencimento (curva vermelha). A legenda na direita informa o número de dias correspondente 117 | a cada cor (19 dias para azul-escuro, 4 dias para verde, e assim por diante). No vencimento 118 | o valor da carteira é meramente a soma dos valores subjacentes das opções. 119 | 120 |

Como pode ser visto, se PETR4 ficar abaixo de 20,00 a trava de alta não valerá nada 121 | (e portanto os 0,43 gastos na montagem serão integralmente perdidos). PETR4 tem de 122 | subir até perto de 20,50 para a trava apenas empatar no vencimento. 123 | 124 |

125 | Por outro lado, se o objetivo do operador é desfazer a operação quando seu valor 126 | atingir 0,65 (lucro de 50%), não é preciso esperar até o vencimento. Se PETR4 127 | atingir 20,50 a 9 dias do vencimento, a curva azul-clara mostra que a operação 128 | atingiria um valor aproximado de 0,65. Neste ponto o operador deveria desfazer, 129 | porque se ele esperar até o vencimento, e PETR4 estagnar, o valor vai caindo 130 | para abaixo de 0,60 (linha verde) até chegar em 0,50 (linha vermelha). 131 | 132 |

133 | O gráfico não prevê o futuro, naturalmente. A ação subjacente (PETR4) vai oscilar 134 | ao sabor do mercado, percorrendo um "caminho" dentro do gráfico, que vai se cruzando 135 | em diferentes pontos com as diversas curvas de valor. Um "caminho" hipotético 136 | está ilustrado na figura abaixo: 137 | 138 |

139 | Imagem de ajuda 140 | 141 |

142 | Neste "caminho" fantasioso, PETR4 oscilou muito pouco em 19 dias, subindo, descendo e 143 | finalmente subindo a 20,00 no dia do vencimento. Infelizmente para o operador, 144 | este caminho foi cruzando com valores cada vez menores, até chegar a zero. 145 | 146 |

147 | As linhas violeta cruzadas são uma "mira" que segue o ponteiro do mouse. São úteis 148 | para verificar um valor numérico exato. Conforme se move o ponteiro, os valores das 149 | legendas no canto direito superior são atualizados. Na verdade, apenas a posição 150 | horizontal é que importa. 151 | 152 |

No exemplo acima, a "mira" está na posição horizontal correspondente à PETR4 valendo 153 | 19,15. Quando a ação subjacente apresenta este valor, o valor da operação será de: 154 | 0,23 a dezenove dias do vencimento; 0,10 a nove dias; 0,04 a 4 dias; 0,01 a dois dias 155 | do vencimento, e vira pó no vencimento. 156 | 157 |

158 | A curva cinza-clara que cruza o gráfico do canto esquerdo superior até o canto direito 159 | inferior expressa a probabilidade da ação subjacente ficar acima de determinado valor. 160 | Sua legenda é o eixo Y, lado direito, e vai de 0% a 100%. 161 | 162 |

163 | Por exemplo, com a "mira" violeta em PETR4=19,15, a legenda da probabilidade mostra 164 | um valor p=67,68%. Isto significa que a chance de PETR4 ficar acima de 19,15 até 165 | o vencimento é de 67,68%. E portanto, a chance dela ficar abaixo de 19,15 166 | até o vencimento é de 32,32%. (A soma das duas é, naturalmente, de 100%.) 167 | 168 |

169 | Outro exemplo: vemos que a curva de probabilidade fica pouco acima de 10% para um valor 170 | de 21,50 no eixo X. Isto significa que a chance de PETR4 fechar acima de 21,50 no 171 | vencimento é de pouco mais de 10%. É a chance que a nossa trava de alta tem de 172 | apresentar lucro realmente grande... 173 | 174 |

175 | O principal aspecto deste gráfico, que nunca deve ser perdido de vista, é que ele 176 | mostra valor, não lucratividade. A lucratividade aparece quando compramos 177 | uma operação por um valor baixo e vendemos por um valor alto. Não necessariamente 178 | nesta ordem. 179 | 180 |

181 | Operações "vendidas" como trava de baixa apresentarão valores negativos. Isto é 182 | normal. O valor negativo significa que recebemos dinheiro ao montar, mas pagamos 183 | para sair. O melhor cenário de uma trava de baixa é a operação acabar com valor 184 | zero, ou seja, as opções viram pó. 185 | 186 |

187 | As curvas também permitem algumas inferências a respeito das "gregas". Numa 188 | operação com theta negativo, como a trava de alta das ilustrações, as curvas 189 | mais próximas ao vencimento ficam por baixo (ou seja, com valores progressivamente 190 | menores). Curvas inclinadas para cima significam delta positivo. Curvas com 191 | concavidade para cima (como uma bacia) significam gama positivo. 192 | 193 | 194 | --------------------------------------------------------------------------------