<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Calculating FIFO profit using Hash of Hashes in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413844#M101327</link>
    <description>&lt;P&gt;Thank you so much for this solution! It works beautifully and is extremely efficient.&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 15 Nov 2017 23:41:39 GMT</pubDate>
    <dc:creator>jsmith94</dc:creator>
    <dc:date>2017-11-15T23:41:39Z</dc:date>
    <item>
      <title>Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413097#M101075</link>
      <description>&lt;P&gt;I have a large dataset with trading data from which I am trying to calculate profit with a FIFO (first-in first-out) methodology in Base SAS 9.4. In other words, I want the first CUSIPs bought to be matched to the first CUSIPs sold, regardless of the date. In my final dataset, I want all of the variables from the "Buy" observation of the input dataset to show up alongside all of the variables from the "Sell" observation of the input dataset. If more is bought than sold or sold than bought in a given CUSIP, then the excess should be excluded from the final dataset. Furthermore, if more is sold than has been bought at that time, then the excess sell quantity should be disregarded. A few rows of my input dataset are here:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;TABLE&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;CUSIP&lt;/TD&gt;&lt;TD&gt;Date&lt;/TD&gt;&lt;TD&gt;Time&lt;/TD&gt;&lt;TD&gt;Price&lt;/TD&gt;&lt;TD&gt;Quantity&lt;/TD&gt;&lt;TD&gt;Buy / Sell&lt;/TD&gt;&lt;TD&gt;Account&lt;/TD&gt;&lt;TD&gt;Source&lt;/TD&gt;&lt;TD&gt;Trade ID&lt;/TD&gt;&lt;TD&gt;In14 (Dummy)&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;11:46:58 AM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 100&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;135&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;12:23:10 PM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 250&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;352&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;320&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;3:09:02 PM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 150&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;616&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;TD&gt;6/7/2013&lt;/TD&gt;&lt;TD&gt;2:48:28 PM&lt;/TD&gt;&lt;TD&gt;99.854&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 500&lt;/TD&gt;&lt;TD&gt;S&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;065&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;11:47:53 AM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 150&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;287&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;12:23:50 PM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 250&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;352&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;326&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;3:09:58 PM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 100&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;626&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;TD&gt;5/14/2013&lt;/TD&gt;&lt;TD&gt;11:58:52 AM&lt;/TD&gt;&lt;TD&gt;100.028&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 715&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;161&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;251&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;TD&gt;5/20/2013&lt;/TD&gt;&lt;TD&gt;12:18:25 PM&lt;/TD&gt;&lt;TD&gt;100.738&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1,215&lt;/TD&gt;&lt;TD&gt;S&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;628&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;11:48:44 AM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 150&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;290&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;12:24:29 PM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 250&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;352&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;345&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;3:10:38 PM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 100&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;643&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;TD&gt;5/20/2013&lt;/TD&gt;&lt;TD&gt;12:54:53 PM&lt;/TD&gt;&lt;TD&gt;100.699&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 500&lt;/TD&gt;&lt;TD&gt;S&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;165&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A96&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;11:49:21 AM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 135&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;291&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A96&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;12:25:01 PM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 140&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;352&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;348&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;A96&lt;/TD&gt;&lt;TD&gt;6/18/2013&lt;/TD&gt;&lt;TD&gt;4:04:55 PM&lt;/TD&gt;&lt;TD&gt;98.257&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 275&lt;/TD&gt;&lt;TD&gt;S&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;466&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B20&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;11:51:16 AM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 150&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;292&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B20&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;3:51:57 PM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 80&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;268&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B20&lt;/TD&gt;&lt;TD&gt;6/27/2013&lt;/TD&gt;&lt;TD&gt;9:48:19 AM&lt;/TD&gt;&lt;TD&gt;93.6&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 230&lt;/TD&gt;&lt;TD&gt;S&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;181&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B38&lt;/TD&gt;&lt;TD&gt;5/3/2013&lt;/TD&gt;&lt;TD&gt;3:50:05 PM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 100&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;549&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;921&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B38&lt;/TD&gt;&lt;TD&gt;5/6/2013&lt;/TD&gt;&lt;TD&gt;11:52:02 AM&lt;/TD&gt;&lt;TD&gt;100.1&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 110&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;899&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;B38&lt;/TD&gt;&lt;TD&gt;5/20/2013&lt;/TD&gt;&lt;TD&gt;4:55:36 PM&lt;/TD&gt;&lt;TD&gt;100.375&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 210&lt;/TD&gt;&lt;TD&gt;S&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;868&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;L55&lt;/TD&gt;&lt;TD&gt;3/7/2014&lt;/TD&gt;&lt;TD&gt;11:24:32 AM&lt;/TD&gt;&lt;TD&gt;100.05&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 500&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;398&lt;/TD&gt;&lt;TD&gt;2&lt;/TD&gt;&lt;TD&gt;424&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;L55&lt;/TD&gt;&lt;TD&gt;3/7/2014&lt;/TD&gt;&lt;TD&gt;1:00:45 PM&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 500&lt;/TD&gt;&lt;TD&gt;B&lt;/TD&gt;&lt;TD&gt;793&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;953&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;L55&lt;/TD&gt;&lt;TD&gt;3/11/2014&lt;/TD&gt;&lt;TD&gt;12:07:02 PM&lt;/TD&gt;&lt;TD&gt;100.239&lt;/TD&gt;&lt;TD&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 75&lt;/TD&gt;&lt;TD&gt;S&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;716&lt;/TD&gt;&lt;TD&gt;0&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;In order to create the final table I described above, I have written the following code that creates a Hash of Hashes for each CUSIP that uses two other Hash Tables, one for buys, and one for sells. The code is here:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;data&lt;/STRONG&gt;&amp;nbsp;want;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set have;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if _n_=&lt;STRONG&gt;1&lt;/STRONG&gt; then do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; declare hash hoh ();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hoh.definekey('cusip');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hoh.definedata('cusip','buys','sells','buy','sell');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; hoh.definedone();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; declare hash buys;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; declare hash sells;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; declare hiter buy;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; declare hiter sell;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if hoh.find() ne &lt;STRONG&gt;0&lt;/STRONG&gt;&amp;nbsp;then do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; length tid &lt;STRONG&gt;8&lt;/STRONG&gt; b_id bdate btime bprice bquantity quantity s_id sdate stime sprice squantity &lt;STRONG&gt;8&lt;/STRONG&gt;;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buys=_new_ hash(ordered:'a');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buys.defineKey('tid');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buys.defineData('bdate','btime','bprice','bquantity','b_id', 'b_account', 'b_source', 'b_cusip', 'in14');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buys.defineDone();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sells=_new_ hash(ordered:'a');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sells.defineKey('tid');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sells.defineData('sdate','stime','sprice','squantity','s_id','s_account', 's_cusip');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sells.defineDone();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buy=_new_ hiter('buys');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sell=_new_ hiter('sells');&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventory=&lt;STRONG&gt;0&lt;/STRONG&gt;;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tid+&lt;STRONG&gt;1&lt;/STRONG&gt;;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if buy_sell="B" then do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bdate=trade_date;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; btime=execution_time;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bprice=execution_price;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bquantity=quantity;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b_id=trade_id;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b_account=account_number2;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b_source=source;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; b_cusip=cusip;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; in14=in14;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventory+quantity;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; buys.add();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if inventory=&lt;STRONG&gt;0&lt;/STRONG&gt; then delete;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if quantity&amp;gt;inventory then quantity=inventory;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sdate=trade_date;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stime=execution_time;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sprice=execution_price;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; squantity=quantity;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s_id=trade_id;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s_account=account_number2;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; s_cusip=cusip;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; inventory+(-&lt;STRONG&gt;1&lt;/STRONG&gt;*quantity);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sells.add();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; keep bdate b_account b_source b_cusip b_id bdate btime bprice quantity sdate stime sprice s_id s_account s_cusip in14;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; format bdate sdate date9. bprice sprice dollar8.4 btime stime time12.;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; brc=buy.first();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; src=sell.first();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; do while(brc=&lt;STRONG&gt;0&lt;/STRONG&gt; and src=&lt;STRONG&gt;0&lt;/STRONG&gt;);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; select;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when (bquantity &amp;lt; squantity) do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; temp=squantity-bquantity;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; quantity=bquantity;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; squantity=temp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; brc=buy.next();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when (bquantity=squantity) do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; quantity=bquantity;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; brc=buy.next();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; src=sell.next();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; when (bquantity &amp;gt; squantity) do;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; temp=bquantity-squantity;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; quantity=squantity;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; output;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bquantity=temp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; src=sell.next();&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; otherwise;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; end;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; rc=hoh.replace();&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;run&lt;/STRONG&gt;;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The problem is that I get tons of duplicate entries...my final dataset has almost 30 times the number of observations as it does once I remove duplicates. Any idea how I can stop the hash table from creating these duplicates? Once I remove the duplicates it appears to actually have correctly matched buys and sells within each CUSIP and discarded excess buy and sell quantity, but I would feel more confident about this if I wasn't getting these duplicates. Thanks so much for reading through!&lt;/P&gt;</description>
      <pubDate>Mon, 13 Nov 2017 22:18:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413097#M101075</guid>
      <dc:creator>jsmith94</dc:creator>
      <dc:date>2017-11-13T22:18:07Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413215#M101115</link>
      <description>&lt;P&gt;Please provide a sample SAS DATA statement&amp;nbsp; (not just a table of values)&amp;nbsp;of the input and equally important, the wanted output dataset.&amp;nbsp; I don't understand the description of your objective.&lt;/P&gt;</description>
      <pubDate>Tue, 14 Nov 2017 06:51:34 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413215#M101115</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2017-11-14T06:51:34Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413302#M101137</link>
      <description>&lt;P&gt;Yeah. Post the output.&lt;/P&gt;
&lt;P&gt;and the logic to calculate.&lt;/P&gt;</description>
      <pubDate>Tue, 14 Nov 2017 12:42:17 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413302#M101137</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2017-11-14T12:42:17Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413349#M101147</link>
      <description>&lt;P&gt;Sorry for the lack of information. Here is a data&amp;nbsp;statement:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Data have;&lt;BR /&gt;Input Cusip $ Trade_Date mmddyy10. Execution_Time time9. Execution_Price Quantity Buy_Sell $ Account_Number2 Source Trade_ID In14;&lt;BR /&gt;datalines;&lt;BR /&gt;A62 05/06/2013 11:46:58 100.1 100 B 602 1 135 1&lt;BR /&gt;A62 05/06/2013 12:23:10 100.1 250 B 352 3 320 1&lt;BR /&gt;A62 05/06/2013 15:09:02 100.1 150 B 602 1 616 1&lt;BR /&gt;A62 06/07/2013 14:48:28 99.854 500 S 176 3 065 0&lt;BR /&gt;A70 05/06/2013 11:47:53 100.1 150 B 602 1 287 1&lt;BR /&gt;A70 05/06/2013 12:23:50 100.1 250 B 352 3 326 1&lt;BR /&gt;A70 05/06/2013 15:09:58 100.1 100 B 602 1 626 1&lt;BR /&gt;A70 05/14/2013 11:58:52 100.028 715 B 161 3 251 1&lt;BR /&gt;A70 05/20/2013 12:18:25 100.738 1215 S 176 3 628 0&lt;BR /&gt;A88 05/06/2013 11:48:44 100.1 150 B 602 1 290 1&lt;BR /&gt;A88 05/06/2013 12:24:29 100.1 250 B 352 3 345 1&lt;BR /&gt;A88 05/06/2013 15:10:38 100.1 100 B 602 1 643 1&lt;BR /&gt;A88 05/20/2013 12:54:53 100.699 500 S 176 3 165 0&lt;BR /&gt;A96 05/06/2013 11:49:21 100.1 135 B 602 1 291 1&lt;BR /&gt;A96 05/06/2013 12:25:01 100.1 140 B 352 3 348 1&lt;BR /&gt;A96 06/18/2013 16:04:55 98.257 275 S 176 3 466 0&lt;BR /&gt;B20 05/06/2013 11:51:16 100.1 150 B 602 1 292 1&lt;BR /&gt;B20 05/06/2013 15:51:57 100.1 80 B 602 1 268 1&lt;BR /&gt;B20 06/27/2013 09:48:19 93.6 230 S 176 3 181 0&lt;BR /&gt;B38 05/03/2013 15:50:05 100.1 100 B 549 3 921 1&lt;BR /&gt;B38 05/06/2013 11:52:02 100.1 110 B 602 1 899 1&lt;BR /&gt;B38 05/20/2013 16:55:36 100.375 210 S 176 3 868 0&lt;BR /&gt;L55 03/07/2014 11:24:32 100.05 500 B 398 2 424 1&lt;BR /&gt;L55 03/07/2014 13:00:45 100 500 B 793 3 953 1&lt;BR /&gt;L55 03/11/2014 12:07:02 100.239 75 S 176 3 716 0&lt;BR /&gt;;&lt;BR /&gt;run;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The objective&amp;nbsp;is&amp;nbsp;to match the first quantity bought with the first quantity sold in each CUSIP, disregarding any excess quantity on the buy or sell side that can't be matched. Then, the output dataset should have all of the data from the buy observations and all of the data from the sell observation matched alongside, like this:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;SAS Output&lt;/P&gt;&lt;DIV class="branch"&gt;&lt;DIV&gt;&lt;DIV align="center"&gt;b_id bdate btime bprice quantity s_id sdate stime sprice In14 b_account b_source b_cusip s_account s_cusip &lt;TABLE cellspacing="0" cellpadding="5"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;135&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;11:46:58&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;65&lt;/TD&gt;&lt;TD&gt;07JUN2013&lt;/TD&gt;&lt;TD&gt;14:48:28&lt;/TD&gt;&lt;TD&gt;$99.8540&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;320&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;12:23:10&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;250&lt;/TD&gt;&lt;TD&gt;65&lt;/TD&gt;&lt;TD&gt;07JUN2013&lt;/TD&gt;&lt;TD&gt;14:48:28&lt;/TD&gt;&lt;TD&gt;$99.8540&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;352&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;616&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;15:09:02&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;150&lt;/TD&gt;&lt;TD&gt;65&lt;/TD&gt;&lt;TD&gt;07JUN2013&lt;/TD&gt;&lt;TD&gt;14:48:28&lt;/TD&gt;&lt;TD&gt;$99.8540&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A62&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;287&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;11:47:53&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;150&lt;/TD&gt;&lt;TD&gt;628&lt;/TD&gt;&lt;TD&gt;20MAY2013&lt;/TD&gt;&lt;TD&gt;12:18:25&lt;/TD&gt;&lt;TD&gt;100.7380&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;326&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;12:23:50&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;250&lt;/TD&gt;&lt;TD&gt;628&lt;/TD&gt;&lt;TD&gt;20MAY2013&lt;/TD&gt;&lt;TD&gt;12:18:25&lt;/TD&gt;&lt;TD&gt;100.7380&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;352&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;626&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;15:09:58&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;628&lt;/TD&gt;&lt;TD&gt;20MAY2013&lt;/TD&gt;&lt;TD&gt;12:18:25&lt;/TD&gt;&lt;TD&gt;100.7380&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;251&lt;/TD&gt;&lt;TD&gt;14MAY2013&lt;/TD&gt;&lt;TD&gt;11:58:52&lt;/TD&gt;&lt;TD&gt;100.0280&lt;/TD&gt;&lt;TD&gt;715&lt;/TD&gt;&lt;TD&gt;628&lt;/TD&gt;&lt;TD&gt;20MAY2013&lt;/TD&gt;&lt;TD&gt;12:18:25&lt;/TD&gt;&lt;TD&gt;100.7380&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;161&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A70&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;290&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;11:48:44&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;150&lt;/TD&gt;&lt;TD&gt;165&lt;/TD&gt;&lt;TD&gt;20MAY2013&lt;/TD&gt;&lt;TD&gt;12:54:53&lt;/TD&gt;&lt;TD&gt;100.6990&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;345&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;12:24:29&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;250&lt;/TD&gt;&lt;TD&gt;165&lt;/TD&gt;&lt;TD&gt;20MAY2013&lt;/TD&gt;&lt;TD&gt;12:54:53&lt;/TD&gt;&lt;TD&gt;100.6990&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;352&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;643&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;15:10:38&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;165&lt;/TD&gt;&lt;TD&gt;20MAY2013&lt;/TD&gt;&lt;TD&gt;12:54:53&lt;/TD&gt;&lt;TD&gt;100.6990&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A88&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;291&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;11:49:21&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;135&lt;/TD&gt;&lt;TD&gt;466&lt;/TD&gt;&lt;TD&gt;18JUN2013&lt;/TD&gt;&lt;TD&gt;16:04:55&lt;/TD&gt;&lt;TD&gt;$98.2570&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;A96&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A96&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;348&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;12:25:01&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;140&lt;/TD&gt;&lt;TD&gt;466&lt;/TD&gt;&lt;TD&gt;18JUN2013&lt;/TD&gt;&lt;TD&gt;16:04:55&lt;/TD&gt;&lt;TD&gt;$98.2570&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;352&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;A96&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;A96&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;292&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;11:51:16&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;150&lt;/TD&gt;&lt;TD&gt;181&lt;/TD&gt;&lt;TD&gt;27JUN2013&lt;/TD&gt;&lt;TD&gt;9:48:19&lt;/TD&gt;&lt;TD&gt;$93.6000&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;B20&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;B20&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;268&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;15:51:57&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;80&lt;/TD&gt;&lt;TD&gt;181&lt;/TD&gt;&lt;TD&gt;27JUN2013&lt;/TD&gt;&lt;TD&gt;9:48:19&lt;/TD&gt;&lt;TD&gt;$93.6000&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;B20&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;B20&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;921&lt;/TD&gt;&lt;TD&gt;03MAY2013&lt;/TD&gt;&lt;TD&gt;15:50:05&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;100&lt;/TD&gt;&lt;TD&gt;868&lt;/TD&gt;&lt;TD&gt;20MAY2013&lt;/TD&gt;&lt;TD&gt;16:55:36&lt;/TD&gt;&lt;TD&gt;100.3750&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;549&lt;/TD&gt;&lt;TD&gt;3&lt;/TD&gt;&lt;TD&gt;B38&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;B38&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;899&lt;/TD&gt;&lt;TD&gt;06MAY2013&lt;/TD&gt;&lt;TD&gt;11:52:02&lt;/TD&gt;&lt;TD&gt;100.1000&lt;/TD&gt;&lt;TD&gt;110&lt;/TD&gt;&lt;TD&gt;868&lt;/TD&gt;&lt;TD&gt;20MAY2013&lt;/TD&gt;&lt;TD&gt;16:55:36&lt;/TD&gt;&lt;TD&gt;100.3750&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;602&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;B38&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;B38&lt;/TD&gt;&lt;/TR&gt;&lt;TR&gt;&lt;TD&gt;424&lt;/TD&gt;&lt;TD&gt;07MAR2014&lt;/TD&gt;&lt;TD&gt;11:24:32&lt;/TD&gt;&lt;TD&gt;100.0500&lt;/TD&gt;&lt;TD&gt;75&lt;/TD&gt;&lt;TD&gt;716&lt;/TD&gt;&lt;TD&gt;11MAR2014&lt;/TD&gt;&lt;TD&gt;12:07:02&lt;/TD&gt;&lt;TD&gt;100.2390&lt;/TD&gt;&lt;TD&gt;1&lt;/TD&gt;&lt;TD&gt;398&lt;/TD&gt;&lt;TD&gt;2&lt;/TD&gt;&lt;TD&gt;L55&lt;/TD&gt;&lt;TD&gt;176&lt;/TD&gt;&lt;TD&gt;L55&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Let me know if there is any other information that would be useful to know. The basic logic is to create a Hash of Hashes that changes for each CUSIP, and contains references to a Buys hash table, a Sells hash table, a Buy iterator, and a Sell iterator. The hash tables take all of the buy and sell observations, and output them together based on the order that they were brought into the hash table and the quantities that they have. Once the hash tables run out of buy or sell observations in a CUSIP, the additional observations are discarded and the the program moves on to the next CUSIP. This is largely working - just with a massive number of duplicates.&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 14 Nov 2017 15:00:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413349#M101147</guid>
      <dc:creator>jsmith94</dc:creator>
      <dc:date>2017-11-14T15:00:46Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413656#M101276</link>
      <description>&lt;P&gt;How about this one ?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;
Data have;
Input Cusip $ Trade_Date mmddyy10. Execution_Time time9. Execution_Price Quantity Buy_Sell $ Account_Number2 Source Trade_ID In14;
format Trade_Date mmddyy10. Execution_Time time9.;
datalines;
A62 05/06/2013 11:46:58 100.1 100 B 602 1 135 1
A62 05/06/2013 12:23:10 100.1 250 B 352 3 320 1
A62 05/06/2013 15:09:02 100.1 150 B 602 1 616 1
A62 06/07/2013 14:48:28 99.854 500 S 176 3 065 0
A70 05/06/2013 11:47:53 100.1 150 B 602 1 287 1
A70 05/06/2013 12:23:50 100.1 250 B 352 3 326 1
A70 05/06/2013 15:09:58 100.1 100 B 602 1 626 1
A70 05/14/2013 11:58:52 100.028 715 B 161 3 251 1
A70 05/20/2013 12:18:25 100.738 1215 S 176 3 628 0
A88 05/06/2013 11:48:44 100.1 150 B 602 1 290 1
A88 05/06/2013 12:24:29 100.1 250 B 352 3 345 1
A88 05/06/2013 15:10:38 100.1 100 B 602 1 643 1
A88 05/20/2013 12:54:53 100.699 500 S 176 3 165 0
A96 05/06/2013 11:49:21 100.1 135 B 602 1 291 1
A96 05/06/2013 12:25:01 100.1 140 B 352 3 348 1
A96 06/18/2013 16:04:55 98.257 275 S 176 3 466 0
B20 05/06/2013 11:51:16 100.1 150 B 602 1 292 1
B20 05/06/2013 15:51:57 100.1 80 B 602 1 268 1
B20 06/27/2013 09:48:19 93.6 230 S 176 3 181 0
B38 05/03/2013 15:50:05 100.1 100 B 549 3 921 1
B38 05/06/2013 11:52:02 100.1 110 B 602 1 899 1
B38 05/20/2013 16:55:36 100.375 210 S 176 3 868 0
L55 03/07/2014 11:24:32 100.05 500 B 398 2 424 1
L55 03/07/2014 13:00:45 100 500 B 793 3 953 1
L55 03/11/2014 12:07:02 100.239 75 S 176 3 716 0
;
run;
data buy;
 set have(keep=cusip quantity buy_sell trade_id where=(buy_sell='B'));
 token=1;
 do i=1 to quantity;
  output;
 end;
 drop i quantity;
run;

data sell;
 set have(keep=cusip quantity buy_sell trade_id where=(buy_sell='S'));
 token=1;
 do i=1 to quantity;
  output;
 end;
 drop i quantity;
run;

data temp;
ina=0;inb=0;
 merge buy(keep=cusip trade_id rename=(trade_id=trade_id_buy) in=ina)
       sell(keep=cusip trade_id rename=(trade_id=trade_id_sell) in=inb);
 by cusip;
 if ina and inb;
run;
proc summary data=temp nway;
class cusip trade_id_buy trade_id_sell;
output out=want(drop=_type_ rename=(_freq_=quantity));
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 15 Nov 2017 14:10:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413656#M101276</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2017-11-15T14:10:12Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413692#M101282</link>
      <description>&lt;P&gt;Thanks for your reply Ksharp!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;It's clever, but it only works if the dataset is relatively small. The total quantity in my dataset is in the billions,&amp;nbsp;which using your algorithm would&amp;nbsp;create billions of observations in two datasets and then merge them back together. This would take a long time and might not work at all because of the amount of space and memory required. My hash table is able to process and match my data together in seconds - I'm really just trying to find the bug in that piece of code that's creating duplicates for me in the output. Thanks though!&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 15:36:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413692#M101282</guid>
      <dc:creator>jsmith94</dc:creator>
      <dc:date>2017-11-15T15:36:05Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413790#M101311</link>
      <description>&lt;P&gt;I now &lt;STRIKE&gt;eve&lt;/STRIKE&gt; see&amp;nbsp;what you want is a dataset with (usually) one observation per purchased lot of shares.&amp;nbsp; The obs will have the CUSIP, then all the buy transaction variables (B_data=trade_data,&amp;nbsp; B_time=execution_time, etc).&amp;nbsp;&amp;nbsp; If that lot is sold it will also have an analogous set of sell transaction variables&amp;nbsp; (s_date, s_price, s_quantity ...).&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If all the shares from a lot is sold, it will have a &lt;EM&gt;&lt;STRONG&gt;quantity_available=0&lt;/STRONG&gt;&lt;/EM&gt;.&amp;nbsp;&amp;nbsp; If no shares from a lot is sold, then all the &lt;EM&gt;&lt;STRONG&gt;S_&lt;/STRONG&gt;&lt;/EM&gt; vars will be missing, and that lot will have &lt;EM&gt;&lt;STRONG&gt;quantify_available=b_quantity&lt;/STRONG&gt;&lt;/EM&gt;.&amp;nbsp; If a lot is partially sold, than it will have two records.&amp;nbsp; The first will record the sold portion (and will have quantity_available=0), and the second will have the same &lt;EM&gt;&lt;STRONG&gt;B_&lt;/STRONG&gt;&lt;/EM&gt; variables, and all missing &lt;EM&gt;&lt;STRONG&gt;S_&lt;/STRONG&gt;&lt;/EM&gt; variables, and &lt;EM&gt;&lt;STRONG&gt;quantity_available=the unsold portion&lt;/STRONG&gt;&lt;/EM&gt; of the lot.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Even through I've written papers using hash-of-hashes for FIFO queues, I think you might be better off maintaining a single hash with both "b_" and "s_" vars for each stock lot, and a second hash with one data item per stock, with the current status (i.e. like total shares currently held, number of buys&amp;nbsp;and&amp;nbsp;sales to date).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;In that case, each "buy" establishes a new stock LOT (i.e. a new data item in hash object LOTS).&amp;nbsp; I.e. 3 buys of stock AAA generates three lots, identified by stock/date/price/quantity/source/&amp;nbsp; (the "b_" vars - b_date, b_price, b_quantity, b_source,...).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But when a subsequent "sell" for the same stock is encountered you want to match it with the oldest LOT not yet sold off - that's the FIFO part.&amp;nbsp; So in addition to the buy-related vars noted above, the lot should&amp;nbsp;also have the same set of variables (date/price/...) from the sell transactions (the "s_" vars).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As a rule:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;When a "buy" is encountered add a new lot, with populated "b_" vars, and missing "s_" vars.&lt;/LI&gt;
&lt;LI&gt;When a sell is encountered, find the oldest lot with available_shares&amp;gt;0.
&lt;OL&gt;
&lt;LI&gt;If the sell is for exactly the number in available shares, simply update the lot with the "b_" vars and set available shares to 0.&lt;/LI&gt;
&lt;LI&gt;If the sell if for more than available shares, do the same as the above, but then proceed to subsequent lots to sell of the unsatisfied portion of the original sell transaction.&amp;nbsp; Update that second lot&lt;/LI&gt;
&lt;LI&gt;But &lt;EM&gt;&lt;STRONG&gt;If the sell is for &lt;STRIKE&gt;leave&lt;/STRIKE&gt; less&amp;nbsp;than available shares&lt;/STRONG&gt;&lt;/EM&gt; then you have to create a new second "sub-lot" with the unsold portion of the lot, while updating the sold portion setting available shares to 0.&lt;/LI&gt;
&lt;/OL&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;You might have chosen hash-of-hashes so that you can easily find the oldest lot for a given stock.&amp;nbsp; Since each stock has its own hash and corresponding hash iterator, then just using the &lt;EM&gt;&lt;STRONG&gt;first&lt;/STRONG&gt;&lt;/EM&gt; method of the iterator gets you to the oldest lot for that stock.&amp;nbsp; If you have a single hash &lt;EM&gt;&lt;STRONG&gt;lots&lt;/STRONG&gt;&lt;/EM&gt; sorted by cusip/b_num&amp;nbsp; (b_num is the sequence of the buy transaction), then instead of &lt;EM&gt;&lt;STRONG&gt;first&lt;/STRONG&gt;&lt;/EM&gt; method, you can use the &lt;EM&gt;&lt;STRONG&gt;setcur&lt;/STRONG&gt;&lt;/EM&gt; method, with arguments cusip=cusip, anb b_num=1.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is a working program:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&amp;nbsp;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;proc datasets library=work noprint;
  delete _: ;
quit;

Data have;
  Input Cusip $ Trade_Date mmddyy10. Execution_Time time9. Execution_Price Quantity Buy_Sell $1. Account_Number2 Source Trade_ID In14;
  format trade_date yymmddn8.  execution_time time8.0;
datalines;
A62 05/06/2013 11:46:58 100.1    100 B 602 1 135 1
A62 05/06/2013 12:23:10 100.1    250 B 352 3 320 1
A62 05/06/2013 15:09:02 100.1    150 B 602 1 616 1
A62 06/07/2013 14:48:28  99.854  500 S 176 3 065 0
A70 05/06/2013 11:47:53 100.1    150 B 602 1 287 1
A70 05/06/2013 12:23:50 100.1    250 B 352 3 326 1
A70 05/06/2013 15:09:58 100.1    100 B 602 1 626 1
A70 05/14/2013 11:58:52 100.028  715 B 161 3 251 1
A70 05/20/2013 12:18:25 100.738 1215 S 176 3 628 0
A88 05/06/2013 11:48:44 100.1    150 B 602 1 290 1
A88 05/06/2013 12:24:29 100.1    250 B 352 3 345 1
A88 05/06/2013 15:10:38 100.1    100 B 602 1 643 1
A88 05/20/2013 12:54:53 100.699  500 S 176 3 165 0
A96 05/06/2013 11:49:21 100.1    135 B 602 1 291 1
A96 05/06/2013 12:25:01 100.1    140 B 352 3 348 1
A96 06/18/2013 16:04:55  98.257  275 S 176 3 466 0
B20 05/06/2013 11:51:16 100.1    150 B 602 1 292 1
B20 05/06/2013 15:51:57 100.1     80 B 602 1 268 1
B20 06/27/2013 09:48:19  93.6    230 S 176 3 181 0
B38 05/03/2013 15:50:05 100.1    100 B 549 3 921 1
B38 05/06/2013 11:52:02 100.1    110 B 602 1 899 1
B38 05/20/2013 16:55:36 100.375  210 S 176 3 868 0
L55 03/07/2014 11:24:32 100.05   500 B 398 2 424 1
L55 03/07/2014 13:00:45 100      500 B 793 3 953 1
L55 03/11/2014 12:07:02 100.239   75 S 176 3 716 0
run;

data _null_;

  set have  end=end_of_have;

  length lot_cusip $8                        /* The CUSIP var for use in the LOTS hash object */
         shrs_held N_buys N_sells            /* Vars for the stock_profile hash            */
         lot_sold                            /* Actual lot sales for this Sales transaction   */
         lot_avail                           /* Current share available in a LOT after sale   */
         8;

  array trdata {*} trade_date  execution_time  quantity   execution_price  account_number2  source   trade_id  in14;
  array b_data {*} b_date      b_time          b_quantity b_price          b_acct           b_source b_tid     b_in14;
  array s_data {*} s_date      s_time          s_quantity s_price          s_acct           s_source s_tid     s_in14;
  format b_date: s_date: yymmddn8.   b_time s_time time8.0;

  if _n_=1 then do;
    declare hash stock_profile();
      stock_profile.definekey('cusip');
      stock_profile.definedata('cusip','shrs_held','N_buys','N_sells');   /*Number of Buys, Sells*/
      stock_profile.definedone();

    declare hash lots(ordered:'A');
      lots.definekey('lot_cusip','b_num'); 
      lots.definedata('lot_cusip','b_num','s_num');
      lots.definedata('b_date','b_time','b_quantity','b_price','b_acct','b_source','b_tid','b_in14');
      lots.definedata('s_date','s_time','s_quantity','s_price','s_acct','s_source','s_tid','s_in14');
      lots.definedata('lot_sold','lot_avail');       
      lots.definedone();
    declare hiter ilots('lots');
  end;

  rc=stock_profile.find();   /*Get current status of the incoming CUSIP */

  if (rc^=0 or shrs_held in (.,0)) and buy_sell='S' then do;
     if end_of_have=0 then delete;  /*Avoid premature sales*/
     else goto eoh;
  end;
  else if buy_sell='B' then do;
    N_buys=sum(N_buys,1);
    shrs_held=sum(shrs_held,quantity);
    rc=stock_profile.replace();

    lot_cusip=cusip;
    b_num=n_buys;
    lot_sold=0;
    lot_avail=quantity;
    do v=1 to dim(trdata);   b_data{v}=trdata{v};   end;
    rc=lots.add();
  end;

  else if buy_sell='S' then do;
    N_sells=sum(N_sells,1);
    total_shrs_to_sell=min(quantity,shrs_held);

    /* Now step through the lots looking for shares availble to sell */
    do rc=ilots.setcur(key:cusip,key:1) by 0 until(total_shrs_to_sell=0 or lot_cusip^=cusip or rc^=0);
      if lot_avail&amp;gt;0 then do;
        orig_lot_avail=lot_avail;

       	s_num=n_sells;
        do v=1 to dim(trdata);   s_data{v}=trdata{v};   end;
        lot_sold=min(lot_avail,total_shrs_to_sell);
        lot_avail=0;
        rc=lots.replace();

        total_shrs_to_sell=total_shrs_to_sell-lot_sold;  /*Update the sales "order" */
        shrs_held=shrs_held-lot_sold;                    /*Update current holdings  */
	
        if lot_sold&amp;lt;orig_lot_avail then do;  /*If the LOT was not emptied by this sale ...*/
           b_num=b_num+.01;                  /*Create a "sublot" (=lot+.01) with remaining avaiable shrs*/
           lot_avail=orig_lot_avail-lot_sold; 
           lot_sold=0;
           call missing(of s_:);
           rc=lots.add();
        end; 

      end;

      rc=ilots.next();
    end;
    rc=stock_profile.replace();   /*Store updated holdings*/
  end;

  if end_of_have ;
eoh:
  rc=stock_profile.output(dataset:'stock_profile');
  rc=lots.output(dataset:'want');
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;notes:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Your data has to be sorted by TRADE_DATE, but it doesn't have to be grouped by CUSIP&lt;/LI&gt;
&lt;LI&gt;Note that premature sales (i.e. first transaction is an "S", or the shares_held is already at zero), that record is entirely ignored.&lt;/LI&gt;
&lt;LI&gt;If, say, lot 2 for cusip AAA starts with 200 shares, of which only 50 shares are sold, then there will be two records:
&lt;OL&gt;
&lt;LI&gt;Record with B_NUM=2.0 and&amp;nbsp;lot_available=0, and lot_sold=50&lt;/LI&gt;
&lt;LI&gt;Record with B_NUM=2.01 and lot_available=150 and lot_sold=0&lt;/LI&gt;
&lt;/OL&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;I suspect this will be just as flexible as the hash-of-hashes approach, and probably takes somewhat less memory.&amp;nbsp; Plus it allows you to easily do a bulk output of all the records for all the cusips.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Nov 2018 19:09:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413790#M101311</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2018-11-29T19:09:05Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413844#M101327</link>
      <description>&lt;P&gt;Thank you so much for this solution! It works beautifully and is extremely efficient.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 15 Nov 2017 23:41:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413844#M101327</guid>
      <dc:creator>jsmith94</dc:creator>
      <dc:date>2017-11-15T23:41:39Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413971#M101386</link>
      <description>&lt;P&gt;Make a macro and each time process one CUSIP.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I think could handle big data.&lt;/P&gt;</description>
      <pubDate>Thu, 16 Nov 2017 12:32:32 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/413971#M101386</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2017-11-16T12:32:32Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/449549#M113139</link>
      <description>&lt;P&gt;Shouldn't this line:&lt;/P&gt;&lt;P&gt;if lot_sold&amp;lt;orig_lot_avail then do;&amp;nbsp; /*If the LOT was not emptied by this sale ...*/&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;be&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;if lot_sold&amp;lt;orig_lot_avail&amp;nbsp;&amp;nbsp;and total_shrs_to_sell &amp;gt; 0 then do;&amp;nbsp; /*If the LOT was not emptied by this sale ...*/&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Interesting and useful piece of code, I like the use of the hash tables.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Mar 2018 01:27:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/449549#M113139</guid>
      <dc:creator>J_R_Furman</dc:creator>
      <dc:date>2018-03-29T01:27:56Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/449576#M113156</link>
      <description>&lt;P&gt;No, because the transaction that results in TOTAL_SHARES_TO_SELL reaching zero, also has to be used to update the individual lot.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As an example, consider a sell order of 100, which can be satisfied from a single lot with 200 shares. Adding the condition you propose would leave that lot at 200 shares, instead of updating it to 100.&lt;/P&gt;</description>
      <pubDate>Thu, 29 Mar 2018 05:25:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/449576#M113156</guid>
      <dc:creator>mkeintz</dc:creator>
      <dc:date>2018-03-29T05:25:39Z</dc:date>
    </item>
    <item>
      <title>Re: Calculating FIFO profit using Hash of Hashes</title>
      <link>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/449635#M113179</link>
      <description>&lt;P&gt;Just realized that my data had negative quantities for sales, thus I was getting unwanted sub-lots.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Originally I thought it was due to buys and sells on the same day which wasn't represented in the test data, which adding that conditioned fixed.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Once I retested your code with those scenarios, then I knew I had mangled your code or had other issues.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks for responding so quickly, again nice piece of code.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 29 Mar 2018 12:55:46 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/Calculating-FIFO-profit-using-Hash-of-Hashes/m-p/449635#M113179</guid>
      <dc:creator>J_R_Furman</dc:creator>
      <dc:date>2018-03-29T12:55:46Z</dc:date>
    </item>
  </channel>
</rss>

