experience with stockwatch anyone?

Thinksamuel's icon

Hello

I tought it would be better to post this in the java forum
I am wondering if anyone already used the stockwatch patch that is in the java libraies of maxmsp. I would like to use that patch to get numbers from the stock exchange but I dont know how to program in java.

Mattijs's icon

moved this topic to the Java forum, please reply to the Java list.

Thinksamuel's icon

Ok, so i managed to do the first part (getting more info from the SE) myself (however, still have to compile it) but another problem is, I want to get the numbers hat i get in number boxes to use those numbers as a source for my composition. Apparently you have to create an outlet for that, but what should i write
    declareOutlets(new int[]{DataTypes.ALL});
this is alrteady there, but i now i only get in a message box. What do I have to write to get a separate outlet for numbers?
Thanks in advance
amuel

btw, here is the full code as it appears in the java folder of max

import com.cycling74.max.*;
import java.net.*;
import java.io.*;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;

//finance.yahoo.com/d/quotes.csv?f=sl1d1t1c1ohgv&e=.csv&s=INTC+SUNW

public class StockWatch extends MaxObject implements Runnable, Executable
{
//Attributes
double interval = 30 * 1000; //30 seconds

static final int SYM = 0;
static final int LAST_TRADE = 1;
static final int DAY = 2;
static final int TIME = 3;
static final int CHANGE = 4;

private String _base_url = "http://finance.yahoo.com/d/quotes.csv?f=sl1d1t1c1ohgv&e=.csv";
private String _sym_string = "&s=";
private Hashtable _syms;
private boolean _first_sym = true;
private Thread _t;
private MaxClock _cl;

public StockWatch(Atom[] args)
{
    declareInlets(new int[]{DataTypes.ALL});
    declareOutlets(new int[]{DataTypes.ALL});
    declareAttribute("interval","_get_interval","_set_interval");
    //virtual attribute
    declareAttribute("quotes","_get_quotes","_set_quotes");

    _syms = new Hashtable();
    _cl = new MaxClock(this);
}

private void _set_interval(int i)
{
    interval = i * 1000;
}

private Atom[] _get_interval()
{
    return new Atom[]{Atom.newAtom((float)interval / 1000)};
}

private void _set_quotes(Atom[] args)
{
    _syms.clear();
    for(int i = 0; i < args.length; i++)
     {
        if(args[i].isString())
         _add_quote(args[i].toString());
        else
         System.out.println("Invalid Symbol: "+args[i].toString());
     }
}

private Atom[] _get_quotes()
{
    Enumeration e = _syms.keys();
    Vector tmp = new Vector();
    Atom[] ret = null;
    while(e.hasMoreElements())
        tmp.addElement(Atom.newAtom((String)e.nextElement()));

    ret = new Atom[tmp.size()];
    for(int i = 0; i < tmp.size();i++)
     ret[i] = (Atom)tmp.elementAt(i);

    return ret;
}

public void bang()
{
    _cl.delay(0);
}

public void stop()
{
    _cl.unset();
}

public void clear()
{
    _syms.clear();
}

public void addQuote(String quote)
{
    _add_quote(quote);
}

public void removeQuote(String quote)
{
    quote = quote.toUpperCase();
    if(_syms.containsKey(quote))
     _syms.remove(quote);
}

public void execute()
{

    _t = new Thread(this);
    try{
     _t.start();
    }catch(Exception e)
     {
        e.printStackTrace();
     }

    _cl.delay(interval);
}

public void run()
{
    _do_lookup();
    Enumeration e = _syms.keys();
    outlet(0,"BEGIN");
    while(e.hasMoreElements())
     {
        String[] nfo = (String[])_syms.get(e.nextElement());
        Atom[] list = new Atom[]{Atom.newAtom(nfo[0]),Atom.newAtom(nfo[1]),
                     Atom.newAtom(nfo[2]),Atom.newAtom(nfo[3]),
                     Atom.newAtom(nfo[4])};
        outlet(0,list);
     }
    outlet(0,"END");

}

private void _add_quote(String sym)
{
    sym = sym.toUpperCase();
    if(!_syms.containsKey(sym))
     {
        _syms.put(sym, new String[5]);
     }
}

private void _do_lookup()
{
    try{
     String url = genURL();
     int c;
     URL u = new URL(url);
     BufferedInputStream in = new BufferedInputStream(u.openStream());
     StringBuffer sb = new StringBuffer();
     while((c = in.read()) != -1)
        {
         if(c == (int)'n')
            {
             _stuff_into_hash(sb.toString());
             sb.setLength(0);
             continue;
            }
         sb.append((char)c);
        }

     in.close();
    }catch(Exception e)
     {
        e.printStackTrace();
     }
}

private String genURL()
{
    Enumeration e = _syms.keys();
    int cnt = 0;
    StringBuffer ret = new StringBuffer(_base_url);
    while(e.hasMoreElements())
     {
        if(cnt == 0)
         ret.append(_sym_string+(String)e.nextElement());
        else
         ret.append("+"+(String)e.nextElement());
        cnt++;
     }
    return ret.toString();
}

//indexOf(StringB str, intB fromIndex);
private void _stuff_into_hash(String line)
{
    byte[] b = line.getBytes();
    StringBuffer word = new StringBuffer();
    int idx = 0;
    String key = null;

    for(int i = 0; i < b.length;i++)
     {
        if(idx >= 5)
         break;
        if(b[i] == (byte)'"')
         continue; //skip quotes
        else if(b[i] == (byte)',' && idx == 0) //first word
         {
            key = word.toString();
            ((String[])(_syms.get(key)))[idx] = word.toString();
            idx++;
            word.setLength(0);
            continue;
         }
        else if(b[i] == (byte)',')
         {
            ((String[])(_syms.get(key)))[idx] = word.toString();
            idx++;
            word.setLength(0);        
            continue;
         }
        word.append((char)b[i]);
     }
}

protected void notifyDeleted() {
    _cl.release();
}

}

topher lafata's icon

declareOutlets(new int[]{DataTypes.ALL,DataTypes.INT});

t

On Oct 21, 2007, at 05:38 AM, Samuel Van Ransbeeck wrote:

>
> Ok, so i managed to do the first part (getting more info from the
> SE) myself (however, still have to compile it) but another problem
> is, I want to get the numbers hat i get in number boxes to use
> those numbers as a source for my composition. Apparently you have
> to create an outlet for that, but what should i write
>     declareOutlets(new int[]{DataTypes.ALL});
> this is alrteady there, but i now i only get in a message
> box. What do I have to write to get a separate outlet for numbers?
> Thanks in advance
> amuel
>
> btw, here is the full code as it appears in the java folder of max
>
> import com.cycling74.max.*;
> import java.net.*;
> import java.io.*;
> import java.util.Hashtable;
> import java.util.Vector;
> import java.util.Enumeration;
>
> //finance.yahoo.com/d/quotes.csv?f=sl1d1t1c1ohgv&e=.csv&s=INTC+SUNW
>
> public class StockWatch extends MaxObject implements Runnable,
> Executable
> {
> //Attributes
> double interval = 30 * 1000; //30 seconds
>
> static final int SYM = 0;
> static final int LAST_TRADE = 1;
> static final int DAY = 2;
> static final int TIME = 3;
> static final int CHANGE = 4;
>
> private String _base_url = "http://finance.yahoo.com/d/
> quotes.csv?f=sl1d1t1c1ohgv&e=.csv";
> private String _sym_string = "&s=";
> private Hashtable _syms;
> private boolean _first_sym = true;
> private Thread _t;
> private MaxClock _cl;
>
>
> public StockWatch(Atom[] args)
> {
>     declareInlets(new int[]{DataTypes.ALL});
>     declareOutlets(new int[]{DataTypes.ALL});
>     declareAttribute("interval","_get_interval","_set_interval");
>     //virtual attribute
>     declareAttribute("quotes","_get_quotes","_set_quotes");
>
>     _syms = new Hashtable();
>     _cl = new MaxClock(this);
> }
>
> private void _set_interval(int i)
> {
>     interval = i * 1000;
> }
>
> private Atom[] _get_interval()
> {
>     return new Atom[]{Atom.newAtom((float)interval / 1000)};
> }
>
> private void _set_quotes(Atom[] args)
> {
>     _syms.clear();
>     for(int i = 0; i < args.length; i++)
>      {
>         if(args[i].isString())
>          _add_quote(args[i].toString());
>         else
>          System.out.println("Invalid Symbol: "+args[i].toString());
>      }
> }
>
> private Atom[] _get_quotes()
> {
>     Enumeration e = _syms.keys();
>     Vector tmp = new Vector();
>     Atom[] ret = null;
>     while(e.hasMoreElements())
>         tmp.addElement(Atom.newAtom((String)e.nextElement()));
>
>     ret = new Atom[tmp.size()];
>     for(int i = 0; i < tmp.size();i++)
>      ret[i] = (Atom)tmp.elementAt(i);
>
>     return ret;
> }
>
>
> public void bang()
> {
>     _cl.delay(0);
> }
>
> public void stop()
> {
>     _cl.unset();
> }
>
> public void clear()
> {
>     _syms.clear();
> }
>
>
> public void addQuote(String quote)
> {
>     _add_quote(quote);
> }
>
> public void removeQuote(String quote)
> {
>     quote = quote.toUpperCase();
>     if(_syms.containsKey(quote))
>      _syms.remove(quote);
> }
>
>
> public void execute()
> {
>
>     _t = new Thread(this);
>     try{
>      _t.start();
>     }catch(Exception e)
>      {
>         e.printStackTrace();
>      }
>
>     _cl.delay(interval);
> }
>
> public void run()
> {
>     _do_lookup();
>     Enumeration e = _syms.keys();
>     outlet(0,"BEGIN");
>     while(e.hasMoreElements())
>      {
>         String[] nfo = (String[])_syms.get(e.nextElement());
>         Atom[] list = new Atom[]{Atom.newAtom(nfo[0]),Atom.newAtom(nfo[1]),
>                      Atom.newAtom(nfo[2]),Atom.newAtom(nfo[3]),
>                      Atom.newAtom(nfo[4])};
>         outlet(0,list);
>      }
>     outlet(0,"END");
>
> }
>
> private void _add_quote(String sym)
> {
>     sym = sym.toUpperCase();
>     if(!_syms.containsKey(sym))
>      {
>         _syms.put(sym, new String[5]);
>      }
> }
>
> private void _do_lookup()
> {
>     try{
>      String url = genURL();
>      int c;
>      URL u = new URL(url);
>      BufferedInputStream in = new BufferedInputStream(u.openStream());
>      StringBuffer sb = new StringBuffer();
>      while((c = in.read()) != -1)
>         {
>          if(c == (int)'
> ')
>             {
>              _stuff_into_hash(sb.toString());
>              sb.setLength(0);
>              continue;
>             }
>          sb.append((char)c);
>         }
>
>      in.close();
>     }catch(Exception e)
>      {
>         e.printStackTrace();
>      }
> }
>
> private String genURL()
> {
>     Enumeration e = _syms.keys();
>     int cnt = 0;
>     StringBuffer ret = new StringBuffer(_base_url);
>     while(e.hasMoreElements())
>      {
>         if(cnt == 0)
>          ret.append(_sym_string+(String)e.nextElement());
>         else
>          ret.append("+"+(String)e.nextElement());
>         cnt++;
>      }
>     return ret.toString();
> }
>
> //indexOf(StringB str, intB fromIndex);
> private void _stuff_into_hash(String line)
> {
>     byte[] b = line.getBytes();
>     StringBuffer word = new StringBuffer();
>     int idx = 0;
>     String key = null;
>
>     for(int i = 0; i < b.length;i++)
>      {
>         if(idx >= 5)
>          break;
>         if(b[i] == (byte)'"')
>          continue; //skip quotes
>         else if(b[i] == (byte)',' && idx == 0) //first word
>          {
>             key = word.toString();
>             ((String[])(_syms.get(key)))[idx] = word.toString();
>             idx++;
>             word.setLength(0);
>             continue;
>          }
>         else if(b[i] == (byte)',')
>          {
>             ((String[])(_syms.get(key)))[idx] = word.toString();
>             idx++;
>             word.setLength(0);        
>             continue;
>          }
>         word.append((char)b[i]);
>      }
> }
>
> protected void notifyDeleted() {
>     _cl.release();
> }
>
>
> }
>

Jonny's icon

Hi - sorry to come in a bit late on this thread, but i've been doing a lot of this for a new project recently and have written an mxj object that does all this quite nicely, if you know regular expressions (totally didn't spot the StockWatch example - could have saved myself lots of grief!).

Actually it's a general "screen scraper" object that will go and get a list of strings and/or numbers from any web page at regular intervals, so it'll do weather monitoring, random words - you name it).

I intend to release it in some sort of Open way at some point, but i need to get a lot of other stuff working before i get time to tidy up the code and look into licenses, documentation etc.

In the mean time if it'll help i can mail you an example (but it looks like this thing is doing what you want anyway)

Just thought i'd mention it,

jonny B

Thinksamuel's icon

Another question (i am really sorrry but java is quite difficult to learn in shorttime). Is there a way to split all the numbers in different number boxes, I mean, one numberbox for the last trade, one for the change in value of the stock and so on? And this should happen for all stockzs separately. I want to get all the information for each stock and then make a markov patch using the numbers. THe polyphony increases as you add stock to be sonified.
Again, sorry for asking so much but I just got to know java so it's still difficult.
Thanks a lot
Samuel

Thinksamuel's icon

It doesn't work :(
I added the int and a float outlet and i don't get any numbers out of there, even not in the max window. I really don't know what to do more. In the meantime i discovered the Javatutorials of max, i didn't know there were and the compilation is really simple but still, I don't book any results. What should I do. I am already happy if I can get just 1 stock giing information, if necessary I just make this a subpatch and let for every stock this subpatch be used, with each stock a specific name.

topher lafata's icon

if you post your code perhaps someone could help with what is going
wrong.
t

On Oct 29, 2007, at 11:19 AM, Samuel Van Ransbeeck wrote:

>
> It doesn't work :(
> I added the int and a float outlet and i don't get any numbers out
> of there, even not in the max window. I really don't know what to
> do more. In the meantime i discovered the Javatutorials of max, i
> didn't know there were and the compilation is really simple but
> still, I don't book any results. What should I do. I am already
> happy if I can get just 1 stock giing information, if necessary I
> just make this a subpatch and let for every stock this subpatch be
> used, with each stock a specific name.
>

Thinksamuel's icon

here you go

topher lafata's icon

I dont really understand totally what you are trying to do but to
send something out the
FLOAT outlet you created you need to use:

outlet(1,floatdata)

t

On Oct 29, 2007, at 11:19 AM, Samuel Van Ransbeeck wrote:

>
> It doesn't work :(
> I added the int and a float outlet and i don't get any numbers out
> of there, even not in the max window. I really don't know what to
> do more. In the meantime i discovered the Javatutorials of max, i
> didn't know there were and the compilation is really simple but
> still, I don't book any results. What should I do. I am already
> happy if I can get just 1 stock giing information, if necessary I
> just make this a subpatch and let for every stock this subpatch be
> used, with each stock a specific name.
>

Thinksamuel's icon

Ok, I will check how to implement that.
This is what I want to do.
The java object is collecting stock excgange data. This data I want to use as a source for pitch information and velocity (and then manipulate them further in Max). For this I need to get the numbers out some way.

Thinksamuel's icon

I tried to integrate floatdata utlet, but apparently that doesn't exist. I don't see what I can do more? I know there must be an easy solution but what? Yes, I know I ask alot but I don't want to give up this project.

Thinksamuel's icon

I got the thing working :))))))
I used (wel my teacher used) the ZL NTH object to get an element from the list and from there I can move on.
Just one question left, I added in the javacode AVG_VOL and VOLUME (coming from yahoo Finance)as static finals, because I want those values as well. However, after I compile the thing, it doesn't appear in the scrolling window, nor in the max inspector. Do I have to add an element more and if yes, where?