en-us/A_Simple_Stockticker.walkthru.help.txt

<#
 
 
PowerShell Pipeworks can be very great for creating software services out of information on the internet.
 
In this sample, we'll create a simple stock ticker that parses Yahoo Finance.
 
 
To start off, we need to create a folder to hold the module.
 
 
#>
 
New-Item -Path "$home\Documents\WindowsPowerShell\Modules\StockTicker" -ItemType Directory -ErrorAction SilentlyContinue -Force |
   Out-Null
 
<#
 
Next we'll create the PSM1 file, which tells PowerShell how to initialize the module.
 
In this example, we'll include one function defined in the file Get-StockQuote
 
#>
 
{
. $psScriptRoot\Get-StockQuote.ps1
} |
    Set-Content "$home\Documents\WindowsPowerShell\Modules\StockTicker\StockTicker.psm1"
 
 
<#
 
Now we'll add a PowerShell module manifest.
 
 
In this manifest, we'll specify the version of the module, the .PSM1 file we will include, and a format file.
 
 
The format file will make our StockTicker a lot more functional and fun, because it will let us customize how we display each result.
#>
{
@{
    ModuleVersion = 0.1
    ModuleToProcess = 'StockTicker.psm1'
    FormatsToProcess = 'StockTicker.Format.ps1xml'
}
} |
    Set-Content "$home\Documents\WindowsPowerShell\Modules\StockTicker\StockTicker.psd1"
 
 
<#
 
We also need to have a Pipeworks manifest. In this manifest, we'll register one web command: Find-BikeStation, with a friendly name.
 
#>
 
{
    @{
        UseBootstrap = $true
        DomainSchematics = @{
            "StockTicker.PowerShellPipeworks.com" = "Default"
        }
        WebCommand = @{
            "Get-StockQuote" = @{
                FriendlyName = "Get a Stock Quote"
            }
        }
    }
} |
    Set-Content "$home\Documents\WindowsPowerShell\Modules\StockTicker\StockTicker.Pipeworks.psd1"
 
 
<#
The Get-StockQuote function is straightforward and simple.
 
It's parsing the web page for a given stock. It uses Get-Web once to return HTML, and then calls Get-Web -Tag with that HTML to pull out specific CSS styles that I know contain information about the stock.
 
It's very important to note that the output object is given it's own type name, which lets us format the object however we'd like. The code that does this looks like so:
 
 
    $stockInfo.pstypenames.clear()
    $stockInfo.pstypenames.add('Stock.Info')
    $stockInfo
 
 
 
 
 
#>
 
{
function Get-StockQuote
{
    <#
    .Synopsis
        Gets stock quotes
    .Description
        Gets stock quotes from Yahoo finance
    .Example
        Get-StockQuote MSFT
    .Example
        'AAPL', 'MSFT', 'GOOG' | Get-StockQuote
 
    #>
    param(
    # The Ticker Symbol of the Stock
    [Parameter(Mandatory=$true,
        Position=0,
        ValueFromPipeline=$true,
        ValueFromPipelineByPropertyName=$true)]
    [string[]]$TickerSymbol
    )
     
    process {
        foreach ($ts in $TickerSymbol) {
        $html = Get-Web -Url "http://finance.yahoo.com/q?s=$ts"
         
        $spans = Get-Web -Html $html -tag 'span'
         
        $currentValue = $spans |
            Where-Object {
                $_.Tag -like "*class=*time_rtq_ticker*"
            } |
            ForEach-Object {
                ($_.Tag -ireplace "<(.|\n)*?>", "") -as [double]
            }
 
        $timeRetreived = $spans |
            Where-Object {
                $_.Tag -like "*class=*time_rtq*" -and
                ($_.Tag -notlike "*class=*time_rtq_ticker*") -and
                ($_.Tag -notlike "*up*") -and
                ($_.Tag -notlike "*down*")
            } |
            Select-Object -First 1 |
            ForEach-Object {
                ($_.Tag -ireplace "<(.|\n)*?>", "")
            }
 
 
        $priceSpans = $spans |
            Where-Object {$_.Tag -like "*class*=*time_rtq_content**" } |
            Select-Object -First 1
 
        $direction =
            if ($priceSpans.Tag -like "*up*") {
                1
            } else {
                -1
            }
 
 
        $tableData = Get-Web -Html $html -Tag td |
            Where-Object {
                $_.Tag -like "*yfnc_tabledata1*"
            } | ForEach-Object {
                ($_.Tag -ireplace "<(.|\n)*?>", "")
            }
 
        $previousClose,
            $openedAt,
            $averageBuyBid,
            $averageAskBid,
            $oneYearEstimate,
            $beta,
            $daysRange,
            $52WeekRange,
            $volumeOfShares,
            $averageVolume,
            $marketCapitalization,
            $priceToEarningsRatio,
            $EarningsPerShare,
            $DividendAndYield,
            $forwardPe,
            $pOvers,
            $exDividendDate,
            $restOfStuff = $tableData
 
 
        $priceChanges = $priceSpans.Tag -ireplace "<(.|\n)*?>", " "
 
 
         
        $priceChanges = @($priceChanges -split ' ' -ne '')
 
 
        $stockInfo =
            New-Object PSObject -Property @{
                Symbol = $ts
                Price = $currentValue
                TimeRetreived = $timeRetreived
                AbsolutePriceChange = (($priceChanges[0] -as [Double])* $direction)
                RelativePriceChange = (($priceChanges[1].Trim('()%') -as [double]) * $direction)
                PreviousClose = $previousClose -as [double]
                OpenedAt = $openedAt -as [double]
                AverageBuyBid = $averageBuyBid
                AverageAskBid = $averageAskBid
                OneYearEstimate = $oneYearEstimate
                Beta = $beta
                TodaysRange = $daysRange
                FiftyTwoWeekRange = $52WeekRange
                VolumeOfShares = $volumeOfShares
                AverageVolume = $averageVolume
                MarketCapitalization = $marketCapitalization
                PriceToEarningsRatio = $priceToEarningsRatio
                EarningsPerShare = $EarningsPerShare
                DividendAndYield = $DividendAndYield
                ForwardPe = $forwardPe
                PriceToSales = $pOvers
                ExDividedDate = $exDividendDate
            }
 
        $stockInfo.pstypenames.clear()
        $stockInfo.pstypenames.add('Stock.Info')
        $stockInfo
 
        }
    }
 
 
     
}
  
 
} |
    Set-Content "$home\Documents\WindowsPowerShell\Modules\StockTicker\Get-StockQuote.ps1"
 
<#
 
In order to make the output of the function look good in a web site, we want to create a formatter for the results.
 
 
The next chunk of code is an [EzFormat file](http://ezout.start-automating.com/Writing%20An%20EzFormat%20File/). It assumes you've loaded the module [EZOut](http://ezout.start-automating.com), which makes writing PowerShell formatters a lot friendlier.
 
 
This particular ezFormat file is pretty simple. If Request and Response are found, it displays a table with the three most pertinent pieces of information, and
 
 
 
 
#>
 
$ezFormat=
{
$moduleName = 'StockTicker'
$ModuleRoot = "$home\Documents\WindowsPowerShell\Modules\$moduleName"
             
$formatting = @()
$formatting += Write-FormatView -TypeName "Stock.Info" -Action {
    $data = $_
 
    $extraData = New-Object PSOBject
    $extraData.pstypenames.clear()
    $extraData.pstypenames.add('Stock.Data')
    foreach ($prop in $data.psobject.properties | Sort-Object Name){
        if ('Symbol', 'Price', 'AbsolutePriceChange', 'RelativePriceChange' -notcontains $prop.Name) {
            $null = $extraData.psobject.Properties.add($prop)
        }
    }
    if ($request -and $response) {
        $output = "<div class='span3' style='font-size:2.33em'>$($data.Symbol)</div><div class='span2' style='font-size:2em'>$($data.Price)</div><div class='span4' style='font-size:1.66em'>Today's Change ($($data.AbsolutePriceChange) / $($data.RelativePriceChange)%)</div><hr style='clear:both' />"
 
         
        foreach ($ed in $extraData.psobject.properties) {
            $output += "<div class='span4 $($ed.Name)_Heading'>$($ed.Name)</div>
            <div class='span4 $($ed.Name)_Data'>$($ed.Value)</div>
            <hr style='line-height:150%' />"
        }
         
        $output
    } else {
        $output = "$($data.Symbol) : $($data.Price) [Today's Change ($($data.AbsolutePriceChange) / $($data.RelativePriceChange))]"
         
 
         
               
        $output += $extraData|
            Out-String -Width 10kb
        $output
    }
}
             
             
$formatting |
    Out-FormatData |
    Set-Content "$moduleRoot\$ModuleName.Format.ps1xml"
}
 
& $ezFormat
 
$ezFormat |
    Set-Content "$home\Documents\WindowsPowerShell\Modules\$moduleName\$moduleName.Ezformat.ps1"
 
<#
 
Now we can import the module, and can check on that state of Microsoft's stock.
 
#>
 
 
Import-Module StockTicker -Force -PassThru | ConvertTo-ModuleService -Force -Do "http://localhost/StockTicker/Get-StockQuote/MSFT/"