Related Topics
George (3)
It's often desirable to get live financial data and everyone knows. XML is the thing to use but actually writing programs that work takes a bit of trouble. Plus, once you've got the data you need to display it.
When buying or selling options it is helpful to be able to see the information graphically rather than just looking at the tabular option chain tables. (I sell puts instead of placing buy limit orders; and I sell covered calls when I want to sell a position that may continue to appreciate.)
The feature below allows you to see how all the puts and calls are priced for a particular stock; in a glance it is often possible to see if the strategy you have in mind would be worth the trouble.
The data is from Yahoo Finance and the process of repetitively querying their XML streams takes a while, so be patient.
To see the messy, ugly code, click here
<?php // Find and display options prices from Yahoo Finance // Thanks to https://developer.yahoo.com/yql/console // for access to the XML streams // // And to https://www.pchart.net/ // for their lovely charting package if (empty($_POST)) { // -----------------STEP ONE-------------------- // if nothing has been POSTed, send out the form // --------------------------------------------- ?> <!DOCTYPE HTML> <html xmlns="https://www.w3.org/1999/xhtml"> <head> <meta charset="windows-1252" /> <title>Option Lookup: Entry</title> <script type="text/javascript"> function validateForm() { var x=document.forms["option_lookup"]["symbol"].value; if (x==null || x=="") { alert("Please enter a stock symbol"); return false; } } </script> </head> <body> <form name="option_lookup" action="Display_Options.php" method="post" onsubmit="return validateForm()" > Enter Stock Symbol: <input type="text" name="symbol" /> <input type="submit" value="Look Up Options" /><br /> <input type="radio" name="table_or_picture" value="table" checked>table<br /> <input type="radio" name="table_or_picture" value="picture" onclick='javascript:document.getElementById("picture_options").style.visibility = "visible";'>picture <div id="picture_options" style='visibility:hidden;'> <hr /> <input type="radio" name="last_bid_ask" value="bid" checked>bid (if you're a seller of an option)<br /> <input type="radio" name="last_bid_ask" value="last">last<br /> <input type="radio" name="last_bid_ask" value="ask">ask<br /> </div> </form> </body> </html> <?php } else { // -------------------------STEP TWO---------------------------- // pull the symbol from the form and get the options data for it // // for all available expirations ... two choices: // 1. display all the data in tables // 2. display bid, last or ask in a table and line graph // ------------------------------------------------------------- // ------ pull the data from the form ------ ob_implicit_flush(true); ob_end_flush(); $symbol = strtoupper($_POST['symbol']); $output = $_POST['table_or_picture']; switch ($_POST['last_bid_ask']) { case "last": $price_value = "lastPrice"; break; case "bid": $price_value = "bid"; break; case "ask": $price_value = "ask"; break; default: echo "bad last_bid_ask radio input"; exit; } // ------ Get the last price data for this symbol ------ // note: the nice, clean instructions given at // https://developer.yahoo.com/yql/guide/yql-code-examples.html#yql_php // don't work (in particular urlencode doesn't give what Yahoo wants) $url_part1 = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20%28%22"; $url_part2 = "%22%29&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"; $URL = $url_part1 . $symbol . $url_part2; $xml = simplexml_load_file($URL); $last_price = (double)$xml->results->quote->LastTradePriceOnly; $last_trade_date = (string)$xml->results->quote->LastTradeDate; $last_trade_time = (string)$xml->results->quote->LastTradeTime; $symbol_name = (string)$xml->results->quote->Name; $last_trade_date_formatted = date("l F j, Y",strtotime($last_trade_date)); // ------ Send out the HTML header with current price data ------ echo "<!DOCTYPE HTML> <html xmlns='https://www.w3.org/1999/xhtml'> <head> <meta charset='windows-1252' /> <title>Option Lookup: Output</title> </head> <body> <h1>Options data for $symbol ($symbol_name)</h1> <h3><a href='https://www.philadelphia-reflections.com/utilities/Display_Options.php'>Start Over</a></h3> <table title='current stock information'> <tr><td>Symbol: $symbol</td></tr> <tr><td>Last Trade: $last_trade_date_formatted $last_trade_time</td></tr> <tr><td>Last Price: $last_price</td></tr> </table> "; // ------ Find all the available expiration dates ------ $url_part1 = "https://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20yahoo.finance.option_contracts%20WHERE%20symbol%3D%27"; $url_part2 = "%27&diagnostics=false&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"; $URL = $url_part1 . $symbol . $url_part2; $xml = simplexml_load_file($URL); foreach ($xml->results->option as $contract) { foreach ($contract as $value) { $contract_dates[] = (string)$value; } } // ------ Pull all the contract information for each expiration date ------ $url_part1 = "https://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20yahoo.finance.options%20WHERE%20symbol%3D'$symbol'%20%20and%20expiration%3D'"; $url_part2 = "'&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"; foreach ($contract_dates as $contract_date) { $URL = $url_part1 . $contract_date . $url_part2; $xml = simplexml_load_file($URL); $expiration_date = (string)$xml->results->optionsChain->attributes()->expiration; foreach ($xml->results->optionsChain->option as $option) { $type = (string)$option->attributes()->type; $option_symbol = (string)$option->attributes()->symbol; foreach ($option as $characteristic => $value) { if ((string)$value == "NaN") continue; $option_chain[$expiration_date][$type][$option_symbol][$characteristic] = (string)$value; } } } // -------------------------STEP TWO choice 1---------------------------- // display all the data in tables // ---------------------------------------------------------------------- if ($output == "table") { foreach ($option_chain as $expiration_date => $chain) { foreach ($chain as $type => $contracts) { foreach ($contracts as $contract) { $one_contract_date[$contract['strikePrice']][$type] = $contract; } } if (!array_key_exists((string)$last_price, $one_contract_date)) { $one_contract_date[(string)$last_price]['C']['bid'] = ''; # put in the current at-the-money price } ksort($one_contract_date); $table_data[$expiration_date] = $one_contract_date; unset($one_contract_date); } foreach ($table_data as $expiration_date => $strike_data) { $expiration_date_formatted = date("M j 'y",strtotime($expiration_date)); echo " <table title='symbol: $symbol; expiration: $expiration_date' style='border:1px solid black; border-collapse:collapse;'>\n"; echo " <tr><td colspan='8'>$symbol $symbol_name</td></tr>\n"; echo " <tr><td colspan='8'>Contract expiration: $expiration_date_formatted</td></tr>\n"; echo " <tr><th> </th><th colspan='3' style='border-bottom:1px double black;'>Call</th><th> </th><th colspan='3' style='border-bottom:1px double black;'>Put</th></tr>\n"; echo " <tr><th>Strike</th><th>bid</th><th>last</th><th>ask</th><th> </th><th>bid</th><th>last</th><th>ask</th></tr>\n"; foreach ($strike_data as $strike => $data) { $call_bid = " "; $call_last = " "; $call_ask = " "; $put_bid = " "; $put_last = " "; $put_ask = " "; if (array_key_exists('C', $data)) { $call_bid = $data['C']['bid']; $call_last = $data['C']['lastPrice']; $call_ask = $data['C']['ask']; } if (array_key_exists('P', $data)) { $put_bid = $data['P']['bid']; $put_last = $data['P']['lastPrice']; $put_ask = $data['P']['ask']; } $strike_style = "style='text-align:center;'"; if ((double)$strike == (double)$last_price) $strike_style = "style='text-align:center;color:red;'"; echo " <tr><td $strike_style>$strike</td><td style='text-align:center;'>$call_bid</td><td style='text-align:center;padding:0 10px 0 10px;'>$call_last</td><td style='text-align:center;'>$call_ask</td><td style='padding:0 10px 0 10px;'> </td><td style='text-align:center;'>$put_bid</td><td style='text-align:center;padding:0 10px 0 10px;'>$put_last</td><td style='text-align:center;'>$put_ask</td></tr>\n"; } echo " </table>\n\n"; } } // -------------------------STEP TWO choice 2---------------------------- // display bid, last or ask in a table and line graph // ---------------------------------------------------------------------- // note: creating and displaying images using dynamic data is something I struggled with. // There undoubtedly is a better way but what I ended up with was to put the name // of the PHP script that creates and displays the image in an iframe. // The calling program (this one) writes the dynamic data to a file and the image // program reads that file. // I hate this but it is all I could get to work. elseif ($output == "picture") { foreach ($option_chain as $expiration_date => $contracts) { foreach ($contracts as $type => $option) { foreach ($option as $option_symbol => $data) { $strikes[$data['strikePrice']][$type] = $data[$price_value]; } } if (!array_key_exists((string)$last_price, $strikes)) { $strikes[(string)$last_price]['C'] = ''; # put in the current at-the-money price } ksort($strikes); foreach ($strikes as $strike => $data) { $strike_list[] = $strike; if ((!array_key_exists('C', $data)) || ($data['C'] == '')) $call_list[] = null; else $call_list[] = (double)$data['C']; (array_key_exists('P', $data)) ? $put_list[] = (double)$data['P'] : $put_list[] = null; } unset($strikes); // create the string to be output to the file $OutputString = "<?php\n"; $expiration_date_formatted = date("M j 'y",strtotime($expiration_date)); $OutputString .= '$desc = ' . "\"$symbol $expiration_date_formatted $price_value\";\n"; $OutputString .= '$last_price = ' . "$last_price;\n"; $OutputString .= '$strikes = array('; foreach ($strike_list as $strike) ($strike == '') ? $OutputString .= "null," : $OutputString .= "$strike,"; $OutputString = substr($OutputString, 0, -1) . ");\n"; $OutputString .= '$calls = array('; foreach ($call_list as $call) ($call == '') ? $OutputString .= "null," : $OutputString .= "$call,"; $OutputString = substr($OutputString, 0, -1) . ");\n"; $OutputString .= '$puts = array('; foreach ($put_list as $put) ($put == '') ? $OutputString .= "null," : $OutputString .= "$put,"; $OutputString = substr($OutputString, 0, -1) . ");\n"; $OutputString .= "?>"; // write the file $fh = fopen($myFile, 'w'); fwrite($fh, $OutputString); fclose($fh); // write the data in a table above the image echo " <table title='symbol: $symbol; expiration: $expiration_date_formatted' style='border:1px solid black; border-collapse:collapse;'>\n"; echo " <tr><td colspan='3'>$symbol $symbol_name $price_value</td></tr>\n"; echo " <tr><td colspan='3'>Contract expiration: $expiration_date_formatted</td></tr>\n"; echo " <tr><th>Strike</th><th>Call</th><th>Put</th></tr>\n"; for ($i = 0; $i < count($strike_list); $i++) { $strike_style = "style='text-align:center;'"; if ((double)$strike_list[$i] == (double)$last_price) $strike_style = "style='text-align:center;color:red;'"; echo " <tr><td $strike_style>$strike_list[$i]</td><td style='text-align:center;'>$call_list[$i]</td><td style='text-align:center;'>$put_list[$i]</td></tr>\n"; } echo " </table>\n\n"; unset($OutputString, $strike_list, $call_list, $put_list); // call the lovely pChart program echo "<iframe src='https://www.philadelphia-reflections.com/utilities/pChart2.1.3/mygraphs/OptionsGraph.php' width='800' height='500'></iframe>"; @ob_flush(); sleep(1); } } else { echo "bad table_or_picture input"; } echo "\n\n </body>\n</html>"; } ?>
Originally published: Monday, December 24, 2012; most-recently modified: Tuesday, May 21, 2019