Page 1 of 1

Stock History Example

Posted: Wed Jun 25, 2003 4:14 am
by Mark1Up
Here is a Stock History example based on pulling free data from Yahoo Finance (based on stock ticker symbol), parsing CSV data into arrays and displaying results in a ListIconGadget. Not really an advanced example, but might be helpful for anyone looking to write their own investment program.

Mark

Code: Select all

; StockHistory
; Mark1Up - 6/24/03
; HTTP Network code thanks to Ricardo!
; www.purebasic.com



; Open Window

#MyWindow = 0 
#MyGadget = 1 
Global Ticker$
If OpenWindow(#MyWindow,100,100,420,600,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Stock History") And CreateGadgetList(WindowID(0))

  StringGadget(2, 5, 5, 70, 20, "IBM")
  ButtonGadget(3, 80, 5, 70, 20, "Get History")
  If CreateGadgetList(WindowID()) 
     ListIconGadget(#MyGadget,5,30,410,590,"Date",70,#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection) 
     AddGadgetColumn(#MyGadget,1,"Open",60)
     AddGadgetColumn(#MyGadget,2,"High",60) 
     AddGadgetColumn(#MyGadget,3,"Low",60)
     AddGadgetColumn(#MyGadget,4,"Close",60)
     AddGadgetColumn(#MyGadget,5,"Volume",90)
  EndIf
   
EndIf

Procedure GetStockHistory()

InitNetwork() 

; Get stock data

ConnectionID = OpenNetworkConnection("table.finance.yahoo.com", 80) 

If ConnectionID 
  com$="GET http://table.finance.yahoo.com/table.csv?s="+Ticker$+"&g=d HTTP/1.1"+Chr(13)+Chr(10) 
  com$=com$+"Accept: */*"+Chr(13)+Chr(10) 
  com$=com$+"Accept: text/html"+Chr(13)+Chr(10) 
  com$=com$+"Host: "+host$+Chr(13)+Chr(10) 
  com$=com$+"User-Agent: Yahoo CVS Parser"+Chr(13)+Chr(10) 
  com$=com$+Chr(13)+Chr(10) 
  Res = SendNetworkData(ConnectionID,@com$,Len(com$)) 

    Repeat 
    Delay(10) 
    Result = NetworkClientEvent(ConnectionID) 
  
    Select Result 
  
    Case 2 
      Content$ = Space(14500) 
      ReceiveNetworkData(ConnectionID,@Content$,14500) 
      Ok = 1 
      CloseNetworkConnection(ConnectionID) 
    EndSelect 
    
    Until Ok = 1 
EndIf 
; Parse data

  ; Get past header data
  ptr=1
  For i = 1 To 4
    eptr = FindString(Content$, Chr(10),ptr+1)
    ptr = eptr+1  
  Next


Dim Stock$(65)
Dim StockDate$(65)
Dim StockOpen.f(65)
Dim StockHigh.f(65)
Dim StockLow.f(65)
Dim StockClose.f(65)
Dim StockVolume.l(65)

For i = 1 To 65
  eptr = FindString(Content$, Chr(10),ptr+1)

  Stock$(i)=Mid(Content$,ptr,eptr-ptr)
  StkPtr=1  
  ; Parse Date
  StkEptr = FindString(stock$(i),",",StkPtr)
  StockDate$(i)=Mid(Stock$(i),StkPtr,StkEptr-StkPtr)
  StkPtr=StkEptr+1
  ; Parse Open
  StkEptr = FindString(stock$(i),",",StkPtr)
  StockOpen(i)=ValF(Mid(Stock$(i),StkPtr,StkEptr-StkPtr))
  StkPtr=StkEptr+1
  ; Parse High
  StkEptr = FindString(stock$(i),",",StkPtr)
  StockHigh(i)=ValF(Mid(Stock$(i),StkPtr,StkEptr-StkPtr))
  StkPtr=StkEptr+1
  ; Parse Low  
  StkEptr = FindString(stock$(i),",",StkPtr)
  StockLow(i)=ValF(Mid(Stock$(i),StkPtr,StkEptr-StkPtr))
  StkPtr=StkEptr+1
  ; Parse Close
  StkEptr = FindString(stock$(i),",",StkPtr)
  StockClose(i)=ValF(Mid(Stock$(i),StkPtr,StkEptr-StkPtr))
  StkPtr=StkEptr+1
  ; Parse Volume
  StkEptr = Len(stock$(i))+1
  StockVolume(i)=Val(Mid(Stock$(i),StkPtr,StkEptr-StkPtr))
  StkPtr=StkEptr+1

  ptr = eptr+1 
Next i

; Show parsed results in List Gadget

     ClearGadgetItemList(#MyGadget) 

     For i=1 To 64
        AddGadgetItem(#MyGadget,-1,StockDate$(i)+Chr(10)+StrF(StockOpen(i),2)+Chr(10)+StrF(StockHigh(i),2)+Chr(10)+StrF(StockLow(i),2)+Chr(10)+StrF(StockClose(i),2)+Chr(10)+StrU(StockVolume(i),#Long)) 
     Next i 
     
  
EndProcedure 

; Main Loop

  Repeat
    EventID = WindowEvent()
    
    If EventID = #PB_EventGadget

      Select EventGadgetID()
      
        Case 3 ; Assign ticker and get history
          Ticker$ = GetGadgetText(2)          
          GetStockHistory()
      EndSelect

    EndIf

  Until EventID = #PB_EventCloseWindow
End


Posted: Wed Jun 25, 2003 12:52 pm
by Sensphere
I tried this code with PB 3.71 Beta and it will crash at this line:

Code: Select all

Dim Stock$(65)
BTW: I'm under Windows NT4 SP6

-sensphere

Posted: Wed Jun 25, 2003 2:16 pm
by Rings
confirm, same old DIM bug unter NT4 Fred.

Posted: Wed Jun 25, 2003 8:20 pm
by ebs
Mark1Up,

Very nice!

You can simplify the parsing by using the "StringField()" function, like this:

Code: Select all

...
; Parse data

Dim Stock$(65)
Dim StockDate$(65)
Dim StockOpen.f(65)
Dim StockHigh.f(65)
Dim StockLow.f(65)
Dim StockClose.f(65)
Dim StockVolume.l(65)

For i = 1 To 65
  stock$(i) = StringField(Content$,i+4,Chr(10))
  ; Parse Date
  StockDate$(i) = StringField(stock$(i), 1, ",")
  ; Parse Open
  StockOpen(i) = ValF(StringField(stock$(i), 2, ","))
  ; Parse High
  StockHigh(i) = ValF(StringField(stock$(i), 3, ","))
  ; Parse Low 
  StockLow(i) = ValF(StringField(stock$(i), 4, ","))
  ; Parse Close
  StockClose(i) = ValF(StringField(stock$(i), 5, ","))
  ; Parse Volume
  StockVolume(i) = Val(StringField(stock$(i), 6, ","))
Next i
...
Regards,
Eric

Posted: Wed Jun 25, 2003 8:55 pm
by Mark1Up
Eric,

Thats a good idea :idea:

Thanks for the feedback.

I'm always for simplifing my code and making better use of the language.

Mark

Posted: Wed Jun 25, 2003 9:12 pm
by TerryHough
@ebs
Nice tip. I have never used StringField before, but this made it clear.

@Mark1Up
Thanks for posting this nice code and idea.

Try adding these snippets of code for a better (IMHO) appearance.

Following Global Ticker$

Code: Select all

; ------------------------ Added by TerryHough --------------------------
lvc.LV_COLUMN  ; set up structure for global use
lvc\mask = #LVCF_FMT
lvc\fmt = #LVCFMT_RIGHT
; ------------------------ End code addition -------------------------------
Change this line

Code: Select all

ListIconGadget(#MyGadget,5,30,410,590,"Date",70,#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
to

Code: Select all

LI = ListIconGadget(#MyGadget,5,30,410,590,"Date",70,#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection) 



then followng
AddGadgetColumn(#MyGadget,5,"Volume",90)

Code: Select all

; ------------------------ Added by TerryHough --------------------------
     SendMessage_(LI, #LVM_SETCOLUMN, 1, @lvc)
     SendMessage_(LI, #LVM_SETCOLUMN, 2, @lvc)
     SendMessage_(LI, #LVM_SETCOLUMN, 3, @lvc)
     SendMessage_(LI, #LVM_SETCOLUMN, 4, @lvc)
     SendMessage_(LI, #LVM_SETCOLUMN, 5, @lvc)
; ------------------------ End code addition ----------------------------
This will right justify the columns.

Terry Hough

Posted: Wed Jun 25, 2003 10:07 pm
by ebs
Terry,

Don't forget to save the ListIconGadget handle as "LI":

Code: Select all

LI.l = ListIconGadget(#MyGadget,5,30,410,590,"Date",70,#PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection)
or it won't work.

Eric

Posted: Wed Jun 25, 2003 10:20 pm
by TerryHough
ebs wrote:Don't forget to save the ListIconGadget handle as "LI":
Oops, I did it but just forgot to copy it to the code snips. I will edit my post above.
Thanks,
Terry