Documento: Especificação de Indicadores do tipo script
Disponibilidade: programa Gol 5.0
publicado em 15/08/01 por omar reis <omar@enfoque.com.br>

Este documento descreve a API para criação de indicadores tipo script no Gol 5.0. Esse recurso permite a implementação de indicadores não disponíveis no Gol e sistemas de negociação customizados.

Os scripts podem ser criados usando as linguagens JavaScript e VBScript, linguagens simples, orientadas a objetos e de largo uso na Internet, com ampla disponibilidade de programadores treinados.

Para simplificar a criação dos scripts, Gol disponibiliza alguns objetos pré-definidos para acesso aos dados da barra de preços atual (Max, Min, Abe, Fech etc) e também a outros indicadores presentes no mesmo gráfico (ex: IFR, DMI etc). Esses objetos são Barra, Indicador e Grafico, como veremos a seguir.

Indicadores tipo script são semelhantes aos outros indicadores disponíveis no Gol. Cada script pode plotar de 1 a 3 linhas no gráfico. A janela para plotagem deve ser definida na criação do script e pode ser:

  • Na janela de preços, junto do gráfico principal.
  • Na janelas de indicadores (para indicadores com valores de 0 a 100)
  • Junto com o gráfico de volume
  • Em uma janela com escala arbitrária

Todas as linhas de um script serão desenhadas nessa mesma janela. Cada linha tem estilo (linha fina, grossa ou pontilhada) e cor próprios.

Criação de um indicador do tipo script

Para criar um indicador do tipo script, entre no editor de indicadores de um grafico, selecione Script na janela de indicadores disponíveis e use um duplo click (ou o botão [+>] ) para criar o script.

A seguir, defina o nome do script, a escala a ser usada e a linguagem (JScript ou VBScript). O tipo de escala determina em qual janela as linhas do script vão aparecer.

Selecione também as cores e estilos das linhas (ou linha) do indicador. Lembre-se que seu indicador poderá ter de 1 a 3 linhas, o que será definido no fonte do script.

Finalmente, aperte o botão [Edita script..] para escrever o fonte do script.

Funcionamento

A cada redesenho do gráfico, o script é ressetado, executando a parte de inicialização (o chamado Main() implicito, no final do script). Depois, a cada nova barra adicionada ao gráfico, o evento NovaBarra() é chamado. Veja no exemplo abaixo a estrutura de um script de indicador em JavaScript (um calculador de média movel exponencial):

// Este script de exemplo calcula uma media movel exponencial
//O numero de periodos da média é a variável NPer (=9 neste caso)

// primeiro cria variáveis globais (i.e. declaração de variáveis usadas)
var med;     // valor atual da média
var NPer;    // número de periodos da media
var k;       // constante de média exponencial. Normalmente usado k=2/(NPer-1)

//Esse evento é chamado para cada nova barra plotada no gráfico
function NovaBarra() {
  if (med == 0) med = Barra.Fech; //inicializa media na 1a barra
  med = (Barra.Fech - med)*k+med; //calcula media exponencial
  Indicador.Linhas(1)= med;       //plota media como linha 1 ( --> até 3 linhas )
}

//inicialização do script (chamado antes de redesenhar tudo) 
  med = 0;          //resseta media (0=inválido) 
  NPer =  9;        //define numero de periodos da media
  k = 2/(NPer+1);   //Calcula const da media movel exponencial

// (c)copr 2002 Enfoque

 

No evento NovaBarra(), o objeto Barra pode ser acessado para se obter os preços do ativo (série principal) na barra atual. O objeto Barra tem as seguintes propriedades:

  Objeto Barra - Tipo IBarra
    função Barra.Data: Double                             //read only
    função Barra.Fech: Double                             //read only
    função Barra.Abe:  Double                             //read only
    função Barra.Max:  Double                             //read only
    função Barra.Min:  Double                             //read only
    função Barra.Volume: Double                           //read only
    função Barra.DataStr: String                          //read only

Ainda no evento NovaBarra(), o script pode plotar de 1 a 3 linhas, através do objeto Indicador. Inicialmente as linhas tem a propriedade LinhaOk() falsa, indicando que a linha não está definida. Ao setar a propriedade Linhas(), a linha começa a ser traçada. O objeto Indicador tem as seguintes propriedades e funções:

  Objeto Indicador - tipo IIndicador
    Propriedade Indicador.NumLinhas: Integer                      //read only
    Propriedade Indicador.Linhas(index: Integer): Double          //read/write
    Propriedade Indicador.LinhaOk(index: Integer): boolean        //read/write
    função      Indicador.AdicionaTexto(texto: String)
    Propriedade IIndicador.NomeDaLinha(index: Integer):String     //read/write

A função Indicador.AdicionaTexto() escreve um texto junto ao ponto do gráfico, e serve para sinalizar condições especiais, como um ponto de compra ou venda.

O script pode ainda acessar outros indicadores no mesmo gráfico. Isto permite comparar um indicador com outro, ou calcular a média movel de um outro indicador, por exemplo. O objeto Grafico tem as seguintes propriedades:

  Objeto Grafico - tipo IGrafico
    Propriedade  Grafico.Count: Integer                           //read only
    Propriedade  Grafico.Indicadores(index: Integer): IIndicador  //read only
    Propriedade  Grafico.Indicador(Nome: String): IIndicador      //read only

As funções Grafico.Indicadores() e Grafico.Indicador() retornam objetos do tipo IIndicador, já definido acima. Neste caso, os valores dos indicadores são read-only, isto é, um script não pode alterar o valor de outro indicador.

No exemplo abaixo, o script usa o valor de outro indicador, o IFR, para traçar duas linhas:

//Nome: Indicador IFR 30/70
//Plotar no gráfico de indicadores (escala 0-100)
// Algoritmo:
// Linha 1:
//    Se IFR acima de 70, linha = 70
//    Se IFR abaixo de 30, linha = 30
//    Se IFR entre 30 e 70, linha acompanha o IFR
// Linha 2:
//    media movel exponencial do IFR de 9 periodos

// Variaveis globais:
var ifr;             //objeto ifr
var vifr;            //valor do ifr    
var mme_ifr,k;       //vars da mÉdia

// Evento de barra
function NovaBarra() {
  if ((ifr) && ( ifr.LinhaOk(1)== true )) {  //verifica se IFR incializado
    //calc linha 1
    vifr = ifr.Linhas(1);                    //pega valor do IFR nesta barra
    if (vifr > 70) Indicador.Linhas(1)= 70;
      else if (vifr < 30) Indicador.Linhas(1)= 30;
      else Indicador.Linhas(1) =  vifr;     //no meio acompanha
    //calc linha 2, a MME do IFR 
    if (mme_ifr == 0) mme_ifr =  vifr;
    mme_ifr = (vifr - mme_ifr)*k + mme_ifr; //calc media exponencial
    Indicador.Linhas(2) =  mme_ifr;         
  }
}

//inicialização do script
  ifr = Grafico.Indicador('ifr'); //pega o objeto IFR, um outro indicador
// neste mesmo gráfico. O IFR deve preceder este script // na lista de indicadores
mme_ifr = 0; //inicializa media com 0 (=inválido) NPer = 9; //numero de periodos k = 2/(NPer+1); //Calcula contante da MME // (c)copr 2002 Enfoque

Notar que um script deste tipo, que usa o valor de outro indicador, deve vir após o indicador na ordem de cálculo, ou o valor do indicador referenciado será o da barra anterior. Na janela de edição de indicadores é possível alterar a ordem de cálculo dos indicadores. Como regra geral, os scripts devem estar sempre no final da lista de indicadores (em baixo).

Neste outro script abaixo, uma média móvel exponencial de 9 períodos é calculada e duas linhas são plotadas: uma 10% abaixo e uma 10% acima da média calculada.

// Nome do indicador: Média móvel exponencial exponencial +/- 10%
// Plotar na janela de preços, junto com a série principal
// Este script de exemplo calcula uma media movel exponencial de 9 períodos
// e plota 10% acima e 10% abaixo da media calculada

//aqui define variáveis usadas no estudo
var med;  //media movel exponencial
var k;    //Constante de mme
var NPer; //Numero de períodos

//Esse evento é chamado a cada nova barra. 
//O objeto Barra contem os preços da série principal 
function NovaBarra() {
  if (med == 0) med = Barra.Fech;   //inicializa media na 1a vez
  med = (Barra.Fech - med)*k+med;   //calc media exponencial
  Indicador.Linhas(1) = med*0.9;    //pode ter até 3 linhas (1,2 e 3)
  Indicador.Linhas(2) = med*1.1;
}

//inicialização do script
  med = 0;
  NPer = 9;        //Seta numero de periodos
  k = 2/(NPer+1);  //Calcula contante de MME

// (c)copr 2002 Enfoque

 

Este script simples plota os níveis de 30 e 70 na janela de indicadores (0 a 100):

// Nome: Plota níveis 30 e 70 na janela de indicadores
// Plotar na janela de indicadores (0 a 100)

function NovaBarra() {
  Indicador.Linhas(1) = 30;  
  Indicador.Linhas(2) = 70; 
}

// (c)copr 2002 Enfoque

O script abaixo mostra como fazer um oscilador usando duas médias aritméticas de 10 e 20 períodos. Além disso, ilustra como plotar os sinais do oscilador, usando um critério numérico e a função AdicionaTexto.

// Nome do indicador: Oscilador usando 2 Médias móveis aritméticas
// O oscilador cruza o nivel zero quando as duas médias se cruzam 
// Plotar na janela de preços arbitrários 

MAXPRECOS=20;    //tamanho da maior média 
var Precos;      //array de precos p/ calc da media
var headPrecos;  //head do buffer circular de precos 
var OscAnt;      //valor do oscilador na barra anterior

//CalcMediaAritmetica - calcula media arit. de N periodos
function CalculaMediaAritmetica(N) {
  tail = headPrecos-N;           //posiciona tail do buffer circular
  if (tail<0) {tail=tail+MAXPRECOS }
  aMed = 0;
  for (k=0; k<N; k++)  {
    aPreco=Precos[tail];
    if (aPreco == 0) { return 0 } //erro: ainda tem preco invalido (zerado)
    aMed = aMed + aPreco;
    tail++;
    if (tail>=MAXPRECOS) {tail=0;}
  }
  return (aMed / N);
}

//evento de nova barra 
function NovaBarra() {
  //salva fechamento da barra atual
  Precos[headPrecos] = Barra.Fech;
  headPrecos++;        //avança head
  if (headPrecos>=MAXPRECOS) {headPrecos=0};
  //calcula as medias
  M1 = CalculaMediaAritmetica(10);
  M2 = CalculaMediaAritmetica(20);
  //calcula e plota oscilador 
  if ((M2 != 0) && (M1 != 0)) { 
    Osc = M1-M2;                //calcula oscilador 
    Indicador.Linhas(1)= Osc;   //plota oscilador como linha 1 
    if (OscAnt != 0) {  //dá indicaçoes quando cruza +100 e -100 pontos para fora  
      if ((OscAnt<100) && (Osc>100)) Indicador.AdicionaTexto('x');
      else if ((OscAnt>-100) && (Osc<-100)) Indicador.AdicionaTexto('o');
    }
    OscAnt = Osc;               //salva anterior
    Indicador.Linhas(2)= 0;     //plota o nível zero como linha 2 
  }
}

//inicialização do script
  Precos = new Array(MAXPRECOS);         //aloca array de preços          
  for (i=0; i<MAXPRECOS; i++) { Precos[i]=0 }   //zera preços
  headPrecos=0;
  OscAnt=0;
// (c)copr 2002 Enfoque

O script acima (adicionando independentemente as duas medias de 10 e 20 períodos) produz o gráfico abaixo.
O oscilador está plotado na janela abaixo do gráfico. Observe os sinais 'x' e 'o' quando os níveis +100 e -100 são rompidos.

Atualização do Indicador em tempo real. Evento MudaPreco

Além do evento NovaBarra, é possível receber o MudaPreco, que é chamado toda vez que há uma alteração no preço do ativo. Esse evento permite antecipar qual seria o valor do indicador se a barra fechasse neste momento. O uso de MudaPreco é similar a NovaBarra: o objeto Barra contém os preços sendo que Barra.Fech contém o último preço.

A sequencia de chamada dos eventos um script é:

  1. Inicialização do script. Chamada uma vez, quando inicia o redesenho do gráfico.
  2. O evento NovaBarra é chamado multiplas vezes, para cada barra da série. Após essa reconstrução do passado, inicia-se a fase de atualização em tempo real (online).
  3. O evento MudaPreco é chamado multiplas vezes, a cada mudança de preço do ativo (novos negócios)
  4. O evento NovaBarra é chamado uma vez ao completar o período da barra.
  5. Os items 3 e 4 se repetem durante o pregão.

O exemplo abaixo mostra como calcular uma MME, mantendo o valor do indicador online:

// Este script calcula uma Media Movel Exponencial (MME),
// com o valor da media mantido em tempo real

// declaração das variáveis globais -------------
var med;
var medAnt;
var k;
var NPer;

//Esse evento é chamado para cada nova barra ---------------
function NovaBarra() {
  if (med == 0) med=Barra.Fech;   //inicializa media na 1a vez
  med = (Barra.Fech - med)*k+med; //calc media exponencial
  Indicador.Linhas(1) = med;      //pode ter até 3 linhas
}

//Esse evento é chamado quando muda o preco (barra online)------
function MudaPreco() {
  //aqui calcula com a media anterior sem alterar o valor de med 
  Indicador.Linhas(1)= (Barra.Fech - med)*k+med; //recalc media exponencial
}

//inicialização --------------------------- 
  med = 0;         //med mantem valor da média
  NPer = 9;        //numero de periodos da média   
  k = 2/(NPer+1);  //Calcula constante de média exponencial 

// (c)copr 2005 Enfoque

O evento MudaPreco está disponmível na versao 5.0.82+.

xxx

OR - v1.0 - 15/08/01
OR - jun/05 - Adicionado evento MudaPreco

 

(c)copr 1988-2005 Enfoque Gráfico Sistemas Ltda - todos os direitos reservados