packages feed

ib-api (empty) → 0.1.0.0

raw patch · 10 files changed

+3776/−0 lines, 10 filesdep +attoparsecdep +basedep +bytestringsetup-changed

Dependencies added: attoparsec, base, bytestring, network

Files

+ LICENSE view
@@ -0,0 +1,674 @@+              GNU GENERAL PUBLIC LICENSE+                Version 3, 29 June 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++                     Preamble++  The GNU General Public License is a free, copyleft license for+software and other kinds of works.++  The licenses for most software and other practical works are designed+to take away your freedom to share and change the works.  By contrast,+the GNU General Public License is intended to guarantee your freedom to+share and change all versions of a program--to make sure it remains free+software for all its users.  We, the Free Software Foundation, use the+GNU General Public License for most of our software; it applies also to+any other work released this way by its authors.  You can apply it to+your programs, too.++  When we speak of free software, we are referring to freedom, not+price.  Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+them if you wish), that you receive source code or can get it if you+want it, that you can change the software or use pieces of it in new+free programs, and that you know you can do these things.++  To protect your rights, we need to prevent others from denying you+these rights or asking you to surrender the rights.  Therefore, you have+certain responsibilities if you distribute copies of the software, or if+you modify it: responsibilities to respect the freedom of others.++  For example, if you distribute copies of such a program, whether+gratis or for a fee, you must pass on to the recipients the same+freedoms that you received.  You must make sure that they, too, receive+or can get the source code.  And you must show them these terms so they+know their rights.++  Developers that use the GNU GPL protect your rights with two steps:+(1) assert copyright on the software, and (2) offer you this License+giving you legal permission to copy, distribute and/or modify it.++  For the developers' and authors' protection, the GPL clearly explains+that there is no warranty for this free software.  For both users' and+authors' sake, the GPL requires that modified versions be marked as+changed, so that their problems will not be attributed erroneously to+authors of previous versions.++  Some devices are designed to deny users access to install or run+modified versions of the software inside them, although the manufacturer+can do so.  This is fundamentally incompatible with the aim of+protecting users' freedom to change the software.  The systematic+pattern of such abuse occurs in the area of products for individuals to+use, which is precisely where it is most unacceptable.  Therefore, we+have designed this version of the GPL to prohibit the practice for those+products.  If such problems arise substantially in other domains, we+stand ready to extend this provision to those domains in future versions+of the GPL, as needed to protect the freedom of users.++  Finally, every program is threatened constantly by software patents.+States should not allow patents to restrict development and use of+software on general-purpose computers, but in those that do, we wish to+avoid the special danger that patents applied to a free program could+make it effectively proprietary.  To prevent this, the GPL assures that+patents cannot be used to render the program non-free.++  The precise terms and conditions for copying, distribution and+modification follow.++                TERMS AND CONDITIONS++  0. Definitions.++  "This License" refers to version 3 of the GNU General Public License.++  "Copyright" also means copyright-like laws that apply to other kinds of+works, such as semiconductor masks.++  "The Program" refers to any copyrightable work licensed under this+License.  Each licensee is addressed as "you".  "Licensees" and+"recipients" may be individuals or organizations.++  To "modify" a work means to copy from or adapt all or part of the work+in a fashion requiring copyright permission, other than the making of an+exact copy.  The resulting work is called a "modified version" of the+earlier work or a work "based on" the earlier work.++  A "covered work" means either the unmodified Program or a work based+on the Program.++  To "propagate" a work means to do anything with it that, without+permission, would make you directly or secondarily liable for+infringement under applicable copyright law, except executing it on a+computer or modifying a private copy.  Propagation includes copying,+distribution (with or without modification), making available to the+public, and in some countries other activities as well.++  To "convey" a work means any kind of propagation that enables other+parties to make or receive copies.  Mere interaction with a user through+a computer network, with no transfer of a copy, is not conveying.++  An interactive user interface displays "Appropriate Legal Notices"+to the extent that it includes a convenient and prominently visible+feature that (1) displays an appropriate copyright notice, and (2)+tells the user that there is no warranty for the work (except to the+extent that warranties are provided), that licensees may convey the+work under this License, and how to view a copy of this License.  If+the interface presents a list of user commands or options, such as a+menu, a prominent item in the list meets this criterion.++  1. Source Code.++  The "source code" for a work means the preferred form of the work+for making modifications to it.  "Object code" means any non-source+form of a work.++  A "Standard Interface" means an interface that either is an official+standard defined by a recognized standards body, or, in the case of+interfaces specified for a particular programming language, one that+is widely used among developers working in that language.++  The "System Libraries" of an executable work include anything, other+than the work as a whole, that (a) is included in the normal form of+packaging a Major Component, but which is not part of that Major+Component, and (b) serves only to enable use of the work with that+Major Component, or to implement a Standard Interface for which an+implementation is available to the public in source code form.  A+"Major Component", in this context, means a major essential component+(kernel, window system, and so on) of the specific operating system+(if any) on which the executable work runs, or a compiler used to+produce the work, or an object code interpreter used to run it.++  The "Corresponding Source" for a work in object code form means all+the source code needed to generate, install, and (for an executable+work) run the object code and to modify the work, including scripts to+control those activities.  However, it does not include the work's+System Libraries, or general-purpose tools or generally available free+programs which are used unmodified in performing those activities but+which are not part of the work.  For example, Corresponding Source+includes interface definition files associated with source files for+the work, and the source code for shared libraries and dynamically+linked subprograms that the work is specifically designed to require,+such as by intimate data communication or control flow between those+subprograms and other parts of the work.++  The Corresponding Source need not include anything that users+can regenerate automatically from other parts of the Corresponding+Source.++  The Corresponding Source for a work in source code form is that+same work.++  2. Basic Permissions.++  All rights granted under this License are granted for the term of+copyright on the Program, and are irrevocable provided the stated+conditions are met.  This License explicitly affirms your unlimited+permission to run the unmodified Program.  The output from running a+covered work is covered by this License only if the output, given its+content, constitutes a covered work.  This License acknowledges your+rights of fair use or other equivalent, as provided by copyright law.++  You may make, run and propagate covered works that you do not+convey, without conditions so long as your license otherwise remains+in force.  You may convey covered works to others for the sole purpose+of having them make modifications exclusively for you, or provide you+with facilities for running those works, provided that you comply with+the terms of this License in conveying all material for which you do+not control copyright.  Those thus making or running the covered works+for you must do so exclusively on your behalf, under your direction+and control, on terms that prohibit them from making any copies of+your copyrighted material outside their relationship with you.++  Conveying under any other circumstances is permitted solely under+the conditions stated below.  Sublicensing is not allowed; section 10+makes it unnecessary.++  3. Protecting Users' Legal Rights From Anti-Circumvention Law.++  No covered work shall be deemed part of an effective technological+measure under any applicable law fulfilling obligations under article+11 of the WIPO copyright treaty adopted on 20 December 1996, or+similar laws prohibiting or restricting circumvention of such+measures.++  When you convey a covered work, you waive any legal power to forbid+circumvention of technological measures to the extent such circumvention+is effected by exercising rights under this License with respect to+the covered work, and you disclaim any intention to limit operation or+modification of the work as a means of enforcing, against the work's+users, your or third parties' legal rights to forbid circumvention of+technological measures.++  4. Conveying Verbatim Copies.++  You may convey verbatim copies of the Program's source code as you+receive it, in any medium, provided that you conspicuously and+appropriately publish on each copy an appropriate copyright notice;+keep intact all notices stating that this License and any+non-permissive terms added in accord with section 7 apply to the code;+keep intact all notices of the absence of any warranty; and give all+recipients a copy of this License along with the Program.++  You may charge any price or no price for each copy that you convey,+and you may offer support or warranty protection for a fee.++  5. Conveying Modified Source Versions.++  You may convey a work based on the Program, or the modifications to+produce it from the Program, in the form of source code under the+terms of section 4, provided that you also meet all of these conditions:++    a) The work must carry prominent notices stating that you modified+    it, and giving a relevant date.++    b) The work must carry prominent notices stating that it is+    released under this License and any conditions added under section+    7.  This requirement modifies the requirement in section 4 to+    "keep intact all notices".++    c) You must license the entire work, as a whole, under this+    License to anyone who comes into possession of a copy.  This+    License will therefore apply, along with any applicable section 7+    additional terms, to the whole of the work, and all its parts,+    regardless of how they are packaged.  This License gives no+    permission to license the work in any other way, but it does not+    invalidate such permission if you have separately received it.++    d) If the work has interactive user interfaces, each must display+    Appropriate Legal Notices; however, if the Program has interactive+    interfaces that do not display Appropriate Legal Notices, your+    work need not make them do so.++  A compilation of a covered work with other separate and independent+works, which are not by their nature extensions of the covered work,+and which are not combined with it such as to form a larger program,+in or on a volume of a storage or distribution medium, is called an+"aggregate" if the compilation and its resulting copyright are not+used to limit the access or legal rights of the compilation's users+beyond what the individual works permit.  Inclusion of a covered work+in an aggregate does not cause this License to apply to the other+parts of the aggregate.++  6. Conveying Non-Source Forms.++  You may convey a covered work in object code form under the terms+of sections 4 and 5, provided that you also convey the+machine-readable Corresponding Source under the terms of this License,+in one of these ways:++    a) Convey the object code in, or embodied in, a physical product+    (including a physical distribution medium), accompanied by the+    Corresponding Source fixed on a durable physical medium+    customarily used for software interchange.++    b) Convey the object code in, or embodied in, a physical product+    (including a physical distribution medium), accompanied by a+    written offer, valid for at least three years and valid for as+    long as you offer spare parts or customer support for that product+    model, to give anyone who possesses the object code either (1) a+    copy of the Corresponding Source for all the software in the+    product that is covered by this License, on a durable physical+    medium customarily used for software interchange, for a price no+    more than your reasonable cost of physically performing this+    conveying of source, or (2) access to copy the+    Corresponding Source from a network server at no charge.++    c) Convey individual copies of the object code with a copy of the+    written offer to provide the Corresponding Source.  This+    alternative is allowed only occasionally and noncommercially, and+    only if you received the object code with such an offer, in accord+    with subsection 6b.++    d) Convey the object code by offering access from a designated+    place (gratis or for a charge), and offer equivalent access to the+    Corresponding Source in the same way through the same place at no+    further charge.  You need not require recipients to copy the+    Corresponding Source along with the object code.  If the place to+    copy the object code is a network server, the Corresponding Source+    may be on a different server (operated by you or a third party)+    that supports equivalent copying facilities, provided you maintain+    clear directions next to the object code saying where to find the+    Corresponding Source.  Regardless of what server hosts the+    Corresponding Source, you remain obligated to ensure that it is+    available for as long as needed to satisfy these requirements.++    e) Convey the object code using peer-to-peer transmission, provided+    you inform other peers where the object code and Corresponding+    Source of the work are being offered to the general public at no+    charge under subsection 6d.++  A separable portion of the object code, whose source code is excluded+from the Corresponding Source as a System Library, need not be+included in conveying the object code work.++  A "User Product" is either (1) a "consumer product", which means any+tangible personal property which is normally used for personal, family,+or household purposes, or (2) anything designed or sold for incorporation+into a dwelling.  In determining whether a product is a consumer product,+doubtful cases shall be resolved in favor of coverage.  For a particular+product received by a particular user, "normally used" refers to a+typical or common use of that class of product, regardless of the status+of the particular user or of the way in which the particular user+actually uses, or expects or is expected to use, the product.  A product+is a consumer product regardless of whether the product has substantial+commercial, industrial or non-consumer uses, unless such uses represent+the only significant mode of use of the product.++  "Installation Information" for a User Product means any methods,+procedures, authorization keys, or other information required to install+and execute modified versions of a covered work in that User Product from+a modified version of its Corresponding Source.  The information must+suffice to ensure that the continued functioning of the modified object+code is in no case prevented or interfered with solely because+modification has been made.++  If you convey an object code work under this section in, or with, or+specifically for use in, a User Product, and the conveying occurs as+part of a transaction in which the right of possession and use of the+User Product is transferred to the recipient in perpetuity or for a+fixed term (regardless of how the transaction is characterized), the+Corresponding Source conveyed under this section must be accompanied+by the Installation Information.  But this requirement does not apply+if neither you nor any third party retains the ability to install+modified object code on the User Product (for example, the work has+been installed in ROM).++  The requirement to provide Installation Information does not include a+requirement to continue to provide support service, warranty, or updates+for a work that has been modified or installed by the recipient, or for+the User Product in which it has been modified or installed.  Access to a+network may be denied when the modification itself materially and+adversely affects the operation of the network or violates the rules and+protocols for communication across the network.++  Corresponding Source conveyed, and Installation Information provided,+in accord with this section must be in a format that is publicly+documented (and with an implementation available to the public in+source code form), and must require no special password or key for+unpacking, reading or copying.++  7. Additional Terms.++  "Additional permissions" are terms that supplement the terms of this+License by making exceptions from one or more of its conditions.+Additional permissions that are applicable to the entire Program shall+be treated as though they were included in this License, to the extent+that they are valid under applicable law.  If additional permissions+apply only to part of the Program, that part may be used separately+under those permissions, but the entire Program remains governed by+this License without regard to the additional permissions.++  When you convey a copy of a covered work, you may at your option+remove any additional permissions from that copy, or from any part of+it.  (Additional permissions may be written to require their own+removal in certain cases when you modify the work.)  You may place+additional permissions on material, added by you to a covered work,+for which you have or can give appropriate copyright permission.++  Notwithstanding any other provision of this License, for material you+add to a covered work, you may (if authorized by the copyright holders of+that material) supplement the terms of this License with terms:++    a) Disclaiming warranty or limiting liability differently from the+    terms of sections 15 and 16 of this License; or++    b) Requiring preservation of specified reasonable legal notices or+    author attributions in that material or in the Appropriate Legal+    Notices displayed by works containing it; or++    c) Prohibiting misrepresentation of the origin of that material, or+    requiring that modified versions of such material be marked in+    reasonable ways as different from the original version; or++    d) Limiting the use for publicity purposes of names of licensors or+    authors of the material; or++    e) Declining to grant rights under trademark law for use of some+    trade names, trademarks, or service marks; or++    f) Requiring indemnification of licensors and authors of that+    material by anyone who conveys the material (or modified versions of+    it) with contractual assumptions of liability to the recipient, for+    any liability that these contractual assumptions directly impose on+    those licensors and authors.++  All other non-permissive additional terms are considered "further+restrictions" within the meaning of section 10.  If the Program as you+received it, or any part of it, contains a notice stating that it is+governed by this License along with a term that is a further+restriction, you may remove that term.  If a license document contains+a further restriction but permits relicensing or conveying under this+License, you may add to a covered work material governed by the terms+of that license document, provided that the further restriction does+not survive such relicensing or conveying.++  If you add terms to a covered work in accord with this section, you+must place, in the relevant source files, a statement of the+additional terms that apply to those files, or a notice indicating+where to find the applicable terms.++  Additional terms, permissive or non-permissive, may be stated in the+form of a separately written license, or stated as exceptions;+the above requirements apply either way.++  8. Termination.++  You may not propagate or modify a covered work except as expressly+provided under this License.  Any attempt otherwise to propagate or+modify it is void, and will automatically terminate your rights under+this License (including any patent licenses granted under the third+paragraph of section 11).++  However, if you cease all violation of this License, then your+license from a particular copyright holder is reinstated (a)+provisionally, unless and until the copyright holder explicitly and+finally terminates your license, and (b) permanently, if the copyright+holder fails to notify you of the violation by some reasonable means+prior to 60 days after the cessation.++  Moreover, your license from a particular copyright holder is+reinstated permanently if the copyright holder notifies you of the+violation by some reasonable means, this is the first time you have+received notice of violation of this License (for any work) from that+copyright holder, and you cure the violation prior to 30 days after+your receipt of the notice.++  Termination of your rights under this section does not terminate the+licenses of parties who have received copies or rights from you under+this License.  If your rights have been terminated and not permanently+reinstated, you do not qualify to receive new licenses for the same+material under section 10.++  9. Acceptance Not Required for Having Copies.++  You are not required to accept this License in order to receive or+run a copy of the Program.  Ancillary propagation of a covered work+occurring solely as a consequence of using peer-to-peer transmission+to receive a copy likewise does not require acceptance.  However,+nothing other than this License grants you permission to propagate or+modify any covered work.  These actions infringe copyright if you do+not accept this License.  Therefore, by modifying or propagating a+covered work, you indicate your acceptance of this License to do so.++  10. Automatic Licensing of Downstream Recipients.++  Each time you convey a covered work, the recipient automatically+receives a license from the original licensors, to run, modify and+propagate that work, subject to this License.  You are not responsible+for enforcing compliance by third parties with this License.++  An "entity transaction" is a transaction transferring control of an+organization, or substantially all assets of one, or subdividing an+organization, or merging organizations.  If propagation of a covered+work results from an entity transaction, each party to that+transaction who receives a copy of the work also receives whatever+licenses to the work the party's predecessor in interest had or could+give under the previous paragraph, plus a right to possession of the+Corresponding Source of the work from the predecessor in interest, if+the predecessor has it or can get it with reasonable efforts.++  You may not impose any further restrictions on the exercise of the+rights granted or affirmed under this License.  For example, you may+not impose a license fee, royalty, or other charge for exercise of+rights granted under this License, and you may not initiate litigation+(including a cross-claim or counterclaim in a lawsuit) alleging that+any patent claim is infringed by making, using, selling, offering for+sale, or importing the Program or any portion of it.++  11. Patents.++  A "contributor" is a copyright holder who authorizes use under this+License of the Program or a work on which the Program is based.  The+work thus licensed is called the contributor's "contributor version".++  A contributor's "essential patent claims" are all patent claims+owned or controlled by the contributor, whether already acquired or+hereafter acquired, that would be infringed by some manner, permitted+by this License, of making, using, or selling its contributor version,+but do not include claims that would be infringed only as a+consequence of further modification of the contributor version.  For+purposes of this definition, "control" includes the right to grant+patent sublicenses in a manner consistent with the requirements of+this License.++  Each contributor grants you a non-exclusive, worldwide, royalty-free+patent license under the contributor's essential patent claims, to+make, use, sell, offer for sale, import and otherwise run, modify and+propagate the contents of its contributor version.++  In the following three paragraphs, a "patent license" is any express+agreement or commitment, however denominated, not to enforce a patent+(such as an express permission to practice a patent or covenant not to+sue for patent infringement).  To "grant" such a patent license to a+party means to make such an agreement or commitment not to enforce a+patent against the party.++  If you convey a covered work, knowingly relying on a patent license,+and the Corresponding Source of the work is not available for anyone+to copy, free of charge and under the terms of this License, through a+publicly available network server or other readily accessible means,+then you must either (1) cause the Corresponding Source to be so+available, or (2) arrange to deprive yourself of the benefit of the+patent license for this particular work, or (3) arrange, in a manner+consistent with the requirements of this License, to extend the patent+license to downstream recipients.  "Knowingly relying" means you have+actual knowledge that, but for the patent license, your conveying the+covered work in a country, or your recipient's use of the covered work+in a country, would infringe one or more identifiable patents in that+country that you have reason to believe are valid.++  If, pursuant to or in connection with a single transaction or+arrangement, you convey, or propagate by procuring conveyance of, a+covered work, and grant a patent license to some of the parties+receiving the covered work authorizing them to use, propagate, modify+or convey a specific copy of the covered work, then the patent license+you grant is automatically extended to all recipients of the covered+work and works based on it.++  A patent license is "discriminatory" if it does not include within+the scope of its coverage, prohibits the exercise of, or is+conditioned on the non-exercise of one or more of the rights that are+specifically granted under this License.  You may not convey a covered+work if you are a party to an arrangement with a third party that is+in the business of distributing software, under which you make payment+to the third party based on the extent of your activity of conveying+the work, and under which the third party grants, to any of the+parties who would receive the covered work from you, a discriminatory+patent license (a) in connection with copies of the covered work+conveyed by you (or copies made from those copies), or (b) primarily+for and in connection with specific products or compilations that+contain the covered work, unless you entered into that arrangement,+or that patent license was granted, prior to 28 March 2007.++  Nothing in this License shall be construed as excluding or limiting+any implied license or other defenses to infringement that may+otherwise be available to you under applicable patent law.++  12. No Surrender of Others' Freedom.++  If conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License.  If you cannot convey a+covered work so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you may+not convey it at all.  For example, if you agree to terms that obligate you+to collect a royalty for further conveying from those to whom you convey+the Program, the only way you could satisfy both those terms and this+License would be to refrain entirely from conveying the Program.++  13. Use with the GNU Affero General Public License.++  Notwithstanding any other provision of this License, you have+permission to link or combine any covered work with a work licensed+under version 3 of the GNU Affero General Public License into a single+combined work, and to convey the resulting work.  The terms of this+License will continue to apply to the part which is the covered work,+but the special requirements of the GNU Affero General Public License,+section 13, concerning interaction through a network will apply to the+combination as such.++  14. Revised Versions of this License.++  The Free Software Foundation may publish revised and/or new versions of+the GNU General Public License from time to time.  Such new versions will+be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++  Each version is given a distinguishing version number.  If the+Program specifies that a certain numbered version of the GNU General+Public License "or any later version" applies to it, you have the+option of following the terms and conditions either of that numbered+version or of any later version published by the Free Software+Foundation.  If the Program does not specify a version number of the+GNU General Public License, you may choose any version ever published+by the Free Software Foundation.++  If the Program specifies that a proxy can decide which future+versions of the GNU General Public License can be used, that proxy's+public statement of acceptance of a version permanently authorizes you+to choose that version for the Program.++  Later license versions may give you additional or different+permissions.  However, no additional obligations are imposed on any+author or copyright holder as a result of your choosing to follow a+later version.++  15. Disclaimer of Warranty.++  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.++  16. Limitation of Liability.++  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF+SUCH DAMAGES.++  17. Interpretation of Sections 15 and 16.++  If the disclaimer of warranty and limitation of liability provided+above cannot be given local legal effect according to their terms,+reviewing courts shall apply local law that most closely approximates+an absolute waiver of all civil liability in connection with the+Program, unless a warranty or assumption of liability accompanies a+copy of the Program in return for a fee.++              END OF TERMS AND CONDITIONS++     How to Apply These Terms to Your New Programs++  If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++  To do so, attach the following notices to the program.  It is safest+to attach them to the start of each source file to most effectively+state the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++    <one line to give the program's name and a brief idea of what it does.>+    Copyright (C) <year>  <name of author>++    This program is free software: you can redistribute it and/or modify+    it under the terms of the GNU General Public License as published by+    the Free Software Foundation, either version 3 of the License, or+    (at your option) any later version.++    This program is distributed in the hope that it will be useful,+    but WITHOUT ANY WARRANTY; without even the implied warranty of+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+    GNU General Public License for more details.++    You should have received a copy of the GNU General Public License+    along with this program.  If not, see <http://www.gnu.org/licenses/>.++Also add information on how to contact you by electronic and paper mail.++  If the program does terminal interaction, make it output a short+notice like this when it starts in an interactive mode:++    <program>  Copyright (C) <year>  <name of author>+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.+    This is free software, and you are welcome to redistribute it+    under certain conditions; type `show c' for details.++The hypothetical commands `show w' and `show c' should show the appropriate+parts of the General Public License.  Of course, your program's commands+might be different; for a GUI interface, you would use an "about box".++  You should also get your employer (if you work as a programmer) or school,+if any, to sign a "copyright disclaimer" for the program, if necessary.+For more information on this, and how to apply and follow the GNU GPL, see+<http://www.gnu.org/licenses/>.++  The GNU General Public License does not permit incorporating your program+into proprietary programs.  If your program is a subroutine library, you+may consider it more useful to permit linking proprietary applications with+the library.  If this is what you want to do, use the GNU Lesser General+Public License instead of this License.  But first, please read+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ ib-api.cabal view
@@ -0,0 +1,70 @@+-- Initial ib-api.cabal generated by cabal init.  For further +-- documentation, see http://haskell.org/cabal/users-guide/++-- The name of the package.+name:                ib-api++-- The package version.  See the Haskell package versioning policy (PVP) +-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary:      +-+------- breaking API changes+--                   | | +----- non-breaking API additions+--                   | | | +--- code changes with no API change+version:             0.1.0.0++-- A short (one-line) description of the package.+synopsis:            An API for the Interactive Brokers Trading Workstation written in pure Haskell++-- A longer description of the package.+-- description:         ++-- URL for the project homepage or repository.+homepage:            https://github.com/rbermani/ib-api++-- The license under which the package is released.+license:             GPL-3++-- The file containing the license text.+license-file:        LICENSE++-- The package author(s).+author:              Robert Bermani++-- An email address to which users can send suggestions, bug reports, and +-- patches.+maintainer:          bobbermani@gmail.com++-- A copyright notice.+-- copyright:           ++category:            Network++build-type:          Simple++-- Extra files to be distributed with the package, such as examples or a +-- README.+-- extra-source-files:  ++-- Constraint on the version of Cabal needed to build this package.+cabal-version:       >=1.10+++library+  -- Modules exported by the library.+  exposed-modules:     Examples.Example, IB.Client, IB.Client.Parser, IB.Client.Exception, IB.Client.Types, IB.Client.Request, IB.Client.Nums+  +  -- Modules included in this library but not exported.+  -- other-modules:       +  +  -- LANGUAGE extensions used by modules in this package.+  other-extensions:    NamedFieldPuns, DeriveDataTypeable, BangPatterns+  +  -- Other library packages from which modules are imported.+  build-depends:       base >=4.6 && < 6, network >=2.6 && <2.7, bytestring >=0.10 && <0.11, attoparsec >=0.12 && <0.13+  +  -- Directories containing source files.+  hs-source-dirs:      src+  +  -- Base language which the package is written in.+  default-language:    Haskell2010+  
+ src/Examples/Example.hs view
@@ -0,0 +1,34 @@+-- |+-- Module  : IB.Client+-- License : GPL3+-- Author : Robert Bermani <bobbermani@gmail.com>+-- Stability : experimental+-- |++-- Main Loop example++module Examples.Example where++import IB.Client+{--+handleMsg :: MIB -> IBMessage -> IO ()+handleMsg msv ibMsg =++nothreadEx = do let cconf = defaultConf { cc_handler = Just handleMsg } +                result <- connect cconf False False+                case result of +                 Left err ->+                 Right msv -> do s <- readMVar msv+                                 unless (not s_connected s) +                                    do checkMsg False ++threadEx = do let cconf = defaultConf { cc_handler = Just handleMsg } +                  result <- connect cconf True False+                  case result of +                   Left err ->+                   Right msv -> do s <- readMVar msv++                  unless (not s_connected s) checkMsg False ++main = +--}
+ src/IB/Client.hs view
@@ -0,0 +1,172 @@+-- |+-- Module  : IB.Client+-- License : GPL3+-- Author : Robert Bermani <bobbermani@gmail.com>+-- Stability : experimental+-- |++-- IB Client++module IB.Client where++import Control.Concurrent (forkIO)+import Control.Concurrent.MVar+import Control.Exception+import Control.Monad+import Data.Attoparsec.ByteString.Char8 hiding (try)+import Data.Bits+import qualified Network.Socket as S hiding (send, recv, sendTo, recvFrom) +import Network.Socket.ByteString +import Network.BSD+import Data.List+import System.Timeout+import System.IO+import qualified Data.ByteString.Char8 as B+import Data.Maybe++import IB.Client.Types+import IB.Client.Nums+import IB.Client.Request+import IB.Client.Exception+import IB.Client.Parser++data ClientConfig = ClientConfig+    { cc_addr :: String+    , cc_port :: Int +    , cc_clientId :: Int +    , cc_extraAuth :: Bool+    , cc_handler :: Maybe HandlerFunc+    } ++disconnect :: MIB -> IO ()+disconnect smv = +    do srv <- readMVar smv+       let h = fromJust (s_sock srv)+       hClose h+       putMVar smv srv { s_clientId = -1+                     , s_extraAuth = False+                     , s_version = 0+                     , s_connected = False+                     }++greetServer :: IBServer -> IO IBServer+greetServer server = +    do write server $ show' client_version+       wFlush server++       let h = fromJust (s_sock server )+           extraAuth = s_extraAuth server++       msg <- B.hGet h 128+       let prea = parse pServerVersion msg++       case eitherResult prea of+         Left errMsg -> throwIO $ IBExc no_valid_id ParseError errMsg+         Right val   -> do let serv_ver =  pre_serverVersion val+                               twsTime = pre_twsTime val+                           case () of+                            _ | serv_ver < server_version -> throwIO $ IBExc no_valid_id UpdateTWS ""+                              | serv_ver >= 3 -> if (serv_ver < min_server_ver_linking)+                                                    then do write server $ show' $ s_clientId server+                                                    else return ()+                              | not extraAuth -> request server StartApi+                              | otherwise -> return ()+                           wFlush server+                           return server { s_twsTime = twsTime+                                         , s_version = serv_ver+                                         , s_connected = True+                                         } ++++checkMsg :: MIB -> Bool -> IO ()+checkMsg mvs loop =+    do s <- readMVar mvs+       let h = fromJust $ s_sock s+           handleMsg = s_handler s+           ver = s_version s+       eof <- timeout (s_timeoutInterval s) $ hIsEOF h++       if (eof /= Just False)+            then do+                modifyMVar_ mvs (\serv -> return $ serv {s_sock = Nothing})+                hClose h+            else do+                msg <- B.hGet h 4096+                server <- takeMVar mvs+                debugWrite server $ ">> " ++ (B.unpack msg)+                putMVar mvs server+                pResult <- parseWith (B.hGet h 1024) (pRecvMsg ver) msg ++                case eitherResult pResult of +                    Left errMsg -> throwIO $ IBExc no_valid_id ParseError errMsg+                    Right res -> handleMsg mvs $ rc_msgBody res +                +                if (loop) +                    then checkMsg mvs loop+                    else return ()++-- |Connects to a server+connect :: ClientConfig     -- ^ Configuration+           -> Bool          -- ^ Run in a new thread+           -> Bool          -- ^ Print debug messages+           -> IO (Either IOError MIB) -- ^ IB instance+ +connect cconf threaded debug = try $ do+    (when debug $+        putStrLn $ "Connecting to " ++ cc_addr cconf)++--    if (isConnected $ cc_socket cconf)+--             then throwIO IBExc no_valid_id AlreadyConnected ""+--             else return ()+    --(when ((cc_handler cconf) == Nothing) (throwIO $ IBExc no_valid_id MissingHandler ""))++    let hostStr = cc_addr cconf+        portStr = show $ cc_port cconf+        hostname | null hostStr = Nothing+                 | otherwise = Just hostStr +    addrinfos <-  ( S.getAddrInfo Nothing hostname (Just portStr))++    let serveraddr = head addrinfos+    s <- S.socket (S.addrFamily serveraddr) S.Stream defaultProtocol++    S.connect s (S.addrAddress serveraddr)+    h <- S.socketToHandle s ReadWriteMode +    hSetBuffering h (BlockBuffering Nothing)+   +    let preServer = toServer cconf h debug++    -- initialize connection with server+    server <- greetServer preServer++    res <- newMVar server++    if threaded+        then do msgThreadId <- forkIO (checkMsg res True)+                modifyMVar_ res (\srv -> return $ srv { s_msgThread = Just msgThreadId +                                                      } )+                return res+        else return res+++toServer :: ClientConfig -> Handle -> Bool -> IBServer+toServer cc h debug = IBServer { s_addr = cc_addr cc+                               , s_port = cc_port cc+                               , s_clientId = cc_clientId cc+                               , s_extraAuth = cc_extraAuth cc+                               , s_handler = fromJust $ cc_handler cc+                               , s_debug = debug+                               , s_sock = Just h+                               }++defaultConf :: ClientConfig +defaultConf = ClientConfig { cc_addr = ""+                           , cc_port = 5555+                           , cc_clientId = 1+                           , cc_extraAuth = False+                           , cc_handler = Just defHandler+                           } ++defHandler :: MIB -> IBMessage -> IO ()+defHandler _ _ = putStrLn "No Message Handler is defined" +
+ src/IB/Client/Exception.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE DeriveDataTypeable #-}++module IB.Client.Exception +  (+    -- * Types+    IBExceptionType(..)+  , IBException(..)+  , CodeMsgPair+ +    -- * Functions+  , excToPair++    -- * Accessors+  , code+  , msg+  ) where+  +import Control.Exception+import Data.Typeable++type CodeMsgPair = (Int, String)++data IBExceptionType +    = AlreadyConnected +    | ConnectFail +    | UpdateTWS +    | NotConnected +    | UnknownID +    | ZeroByteRead +    | NullStringRead +    | NoBytesRead +    | SocketException +    | FailCreateSock +    | FailConnectTWS +    | FailSendFARequest +    | FailSendFAReplace +    | FailSendReqScanner +    | FailSendCanScanner +    | FailSendReqScannerParameters +    | FailSendReqHistData +    | FailSendCanHistData +    | FailSendReqRtBars +    | FailSendCanRTBars +    | FailSendReqCurrTime +    | MissingHandler+    | ParseError+    | SystemError+        deriving (Show)++data IBException = IBExc Int IBExceptionType String+    deriving (Show, Typeable)+ +instance Exception IBException+++code :: CodeMsgPair -> Int+code = fst++msg :: CodeMsgPair -> String+msg = snd++excToPair :: IBExceptionType -> CodeMsgPair+excToPair AlreadyConnected = (501,	"Already connected.") +excToPair ConnectFail = (502, "Couldn't connect to TWS.  Confirm that \"Enable ActiveX and Socket Clients\" is enabled on the TWS \"Configure->API\" menu.") +excToPair UpdateTWS = (503, "The TWS is out of date and must be upgraded.")+excToPair NotConnected = (504, "Not connected")+excToPair UnknownID = (505, "Fatal Error: Unknown message id.")+excToPair ZeroByteRead = (506, "Unexplained zero bytes read.")+excToPair NullStringRead = (507, "Null string read when expecting integer")+excToPair NoBytesRead = (508, "Error: no bytes read or no null terminator found")+excToPair SocketException = (509, "Exception caught while reading socket - ")+excToPair FailCreateSock = (520, "Failed to create socket")+excToPair FailConnectTWS = (521, "Couldn't connect to TWS.")+excToPair FailSendFARequest = (522, "FA Information Request Sending Error - ")+excToPair FailSendFAReplace  = (523, "FA Information Replace Sending Error - ")+excToPair FailSendReqScanner = (524, "Request Scanner Subscription Sending Error - ")+excToPair FailSendCanScanner = (525, "Cancel Scanner Subscription Sending Error - ")+excToPair FailSendReqScannerParameters = (526, "Request Scanner Parameter Sending Error - ")+excToPair FailSendReqHistData = (527, "Request Historical Data Sending Error - ")+excToPair FailSendCanHistData= (528, "Cancel Historical Data Sending Error - ")+excToPair FailSendReqRtBars = (529, "Request Real-time Bar Data Sending Error - ")+excToPair FailSendCanRTBars =(530, "Cancel Real-time Bar Data Sending Error - ")+excToPair FailSendReqCurrTime = (531, "Request Current Time Sending Error - ")+
+ src/IB/Client/Nums.hs view
@@ -0,0 +1,42 @@++module IB.Client.Nums where++no_valid_id = -1 :: Int+no_valid_error_code = 0 :: Int++client_version = 63 :: Int+server_version = 38 :: Int++min_server_ver_pta_orders             = 39      :: Int+min_server_ver_fundamental_data       = 40      :: Int+min_server_ver_under_comp             = 40      :: Int+min_server_ver_contract_data_chain    = 40      :: Int+min_server_ver_scale_orders2          = 40      :: Int+min_server_ver_algo_orders            = 41      :: Int+min_server_ver_execution_data_chain   = 42      :: Int+min_server_ver_not_held               = 44      :: Int+min_server_ver_sec_id_type            = 45      :: Int+min_server_ver_place_order_conid      = 46      :: Int+min_server_ver_req_mkt_data_conid     = 47      :: Int+min_server_ver_req_calc_implied_volat = 49      :: Int+min_server_ver_req_calc_option_price     = 50   :: Int+min_server_ver_cancel_calc_implied_volat = 50   :: Int+min_server_ver_cancel_calc_option_price  = 50   :: Int+min_server_ver_sshortx_old               = 51   :: Int+min_server_ver_sshortx                = 52      :: Int+min_server_ver_req_global_cancel      = 53      :: Int+min_server_ver_hedge_orders			  = 54      :: Int+min_server_ver_req_market_data_type	  = 55      :: Int+min_server_ver_opt_out_smart_routing  = 56      :: Int+min_server_ver_smart_combo_routing_params = 57  :: Int+min_server_ver_delta_neutral_conid    = 58      :: Int+min_server_ver_scale_orders3          = 60      :: Int+min_server_ver_order_combo_legs_price = 61      :: Int+min_server_ver_trailing_percent       = 62      :: Int+min_server_ver_delta_neutral_open_close = 66    :: Int+min_server_ver_positions              = 67      :: Int+min_server_ver_account_summary        = 67      :: Int+min_server_ver_trading_class          = 68      :: Int+min_server_ver_scale_table            = 69      :: Int+min_server_ver_linking            = 70          :: Int+
+ src/IB/Client/Parser.hs view
@@ -0,0 +1,1273 @@+{-# LANGUAGE NamedFieldPuns #-}+++module IB.Client.Parser +  (+    -- * Types+    IBMessage(..)+  , RecvMsg(..) ++    -- * Functions+  , pRecvMsg+  , pServerVersion+  ) where++--import Data.ByteString hiding (elem, map, empty)+import qualified Data.ByteString.Char8 as C +import Control.Monad +import Control.Applicative+import Data.Attoparsec.ByteString.Char8++import IB.Client.Types+import IB.Client.Nums++pServerVersion :: Parser Preamble+pServerVersion = +    do pre_serverVersion <- pStrInt+       let pre_twsTime = 0+ +       if (pre_serverVersion >= 20)+        then do pre_twsTime <- pStrInt+                return ()+        else return ()+    +       --if (serv_ver >= 20)+       -- then do twsTime <- pStrInt+       -- else let twsTime = 0 +    +       return Preamble {pre_serverVersion, pre_twsTime }++pRecvMsg :: Int -> Parser RecvMsg+pRecvMsg sver = +    do rc_msgId <- pStrInt+       rc_version <- pStrInt+       rc_msgBody <- pIBMsg rc_msgId sver rc_version+       return RecvMsg {rc_msgId, rc_version, rc_msgBody}++tickOptionDefault :: IBMessage+tickOptionDefault = TickOptionComputation { tickerId = 0+                                          , tickType = 0+                                          , impliedVol = dblMaximum+                                          , delta = dblMaximum +                                          , optPrice = dblMaximum+                                          , pvDividend = dblMaximum+                                          , gamma = dblMaximum+                                          , vega = dblMaximum+                                          , theta = dblMaximum+                                          , undPrice = dblMaximum +                                          }+++pStr :: Parser String+pStr = do bs <- takeWhile1 (\w -> w /= '\0')+          return (C.unpack bs)++pStrMaybe :: Parser (Maybe String)+pStrMaybe = do bs <- takeWhile1 (\w -> w /= '\0')+               let str = C.unpack bs++               return $ case null str of+                            True -> Nothing+                            False -> Just str++pStrIntMax :: Parser Int+pStrIntMax = do res <- pStrMaybe++                return $ case res of+                            Just x -> read x +                            Nothing -> fromIntegral int32max++pStrDoubleMax :: Parser Double+pStrDoubleMax = do res <- pStrMaybe+                   return $ case res of+                                Just x -> read x+                                Nothing -> dblMaximum+ +pStrInt :: Parser Int+pStrInt = read <$> pStr++pStrDouble :: Parser Double+pStrDouble = read <$> pStr++pStrBool :: Parser Bool+pStrBool = do int <- pStrInt+              case () of +               _ | int /= 0 -> return True+                 | otherwise -> return False++pTagValue :: Parser TagValue+pTagValue = TagValue <$>+         pStr+    <*>  pStr+    <?> "Tag Value"++ +pTickPrice :: Int -> Int -> Parser IBMessage+pTickPrice _ _ = TickPrice <$> +        pStrInt +    <*> pStrInt+    <*> pStrDouble +    <*> pStrInt +    <*> pStrInt+    <?> "Tick Price"++pTickSize :: Int -> Int -> Parser IBMessage+pTickSize _ _ = TickSize <$>+        pStrInt+    <*> pStrInt+    <*> pStrDouble+    <*> pStrInt+    <?> "Tick Size"++pTickEFP :: Int -> Int -> Parser IBMessage+pTickEFP _ _ = TickEFP <$>+        pStrInt+    <*> pStrInt+    <*> pStrDouble+    <*> pStr+    <*> pStrDouble+    <*> pStrInt+    <*> pStr+    <*> pStrDouble+    <*> pStrDouble+    <?> "Tick EFP"++pAcctValue :: Int -> Int -> Parser IBMessage+pAcctValue _ _ = AcctValue <$>+        pStr+    <*> pStr+    <*> pStr+    <*> pStr+    <?> "Acct Value"++pPortfolioValue :: Int -> Int -> Parser IBMessage+pPortfolioValue _ ver = +     do ct_conId <- pStrInt+        ct_symbol <- pStr+        ct_secType <- pStr+        ct_expiry <- pStr+        ct_strike <- pStrDouble+        ct_right <- pStr+        let ct_multiplier = ""+            ct_tradingClass = ""++        if (ver >= 7)+            then do ct_multiplier <- pStr+                    return ()+            else return () ++        ct_exchange <- pStr+        ct_currency <- pStr+        ct_localSymbol <- pStr+        +        if (ver >= 8)+            then do ct_tradingClass <- pStr+                    return ()+            else return () ++        let contract = Contract { ct_conId+                                , ct_symbol+                                , ct_secType+                                , ct_expiry+                                , ct_strike+                                , ct_right+                                , ct_multiplier+                                , ct_exchange+                                , ct_currency+                                , ct_localSymbol+                                , ct_tradingClass +                                }+        position <- pStrInt+        marketPrice <- pStrDouble+        marketValue <- pStrDouble+        averageCost <- pStrDouble+        unrealizedPNL <- pStrDouble+        realizedPNL <- pStrDouble+        accountName <- pStr++        return PortfolioValue { contract+                              , position+                              , marketPrice+                              , averageCost+                              , unrealizedPNL+                              , realizedPNL+                              , accountName +                              }++pAcctUpdateTime :: Int -> Int -> Parser IBMessage+pAcctUpdateTime _ _ = AcctUpdateTime <$> pStr <?> "Acct Update Time"++pNextValidId :: Int -> Int -> Parser IBMessage+pNextValidId _ _ = NextValidId <$> pStrInt <?> "Next Valid Id"++pManagedAccts :: Int -> Int -> Parser IBMessage+pManagedAccts _ _ = ManagedAccts <$>+        pStr+    <?> "Managed Accts"++pReceiveFA :: Int -> Int -> Parser IBMessage+pReceiveFA _ _ = ReceiveFA <$>+        pStrInt+    <*> pStr+    <?> "Receive FA"++pHistoricalData :: Int -> Int -> Parser IBMessage+pHistoricalData _ _ = HistoricalData <$>+        pStrInt+    <*> pStr+    <*> pStr+    <*> pBarDataCons+    <?> "Historical Data"++pTickString :: Int -> Int -> Parser IBMessage +pTickString _ _ = TickString <$>+        pStrInt+    <*> pStrInt+    <*> pStr+    <?> "Tick String"++pScannerData :: Int -> Int -> Parser IBMessage+pScannerData _ _ = ScannerData <$>+        pStrInt+    <*> pScanDataList+    <?> "Scanner Data"++pScannerParameters :: Int -> Int -> Parser IBMessage+pScannerParameters _ _ = ScannerParameters <$>+        pStr+    <?> "Scanner Parameters"++pCurrentTime :: Int -> Int -> Parser IBMessage+pCurrentTime  _ _ = CurrentTime <$>+       pStrInt+    <?> "Current Time"++pRealTimeBars :: Int -> Int -> Parser IBMessage+pRealTimeBars _ _ = RealTimeBars <$>+        pStrInt+    <*> pStrInt+    <*> pStrDouble+    <*> pStrDouble+    <*> pStrDouble+    <*> pStrDouble+    <*> pStrInt+    <*> pStrDouble+    <*> pStrInt+    <?> "Real Time Bars"++pFundamentalData :: Int -> Int -> Parser IBMessage+pFundamentalData _ _ = FundamentalData <$>+        pStrInt+    <*> pStr+    <?> "Fundamental Data"++pPositionData :: Int -> Int -> Parser IBMessage+pPositionData _ ver = do account <- pStr+                         contract <- pContract' +                         position <- pStrInt+                         let avgCost = dblMaximum++                         if (ver >= 3)+                            then do avgCost <- pStrDouble+                                    return ()+                            else return () ++                         return PositionData { account+                                             , contract+                                             , position+                                             , avgCost+                                             }+                      where pContract' =  +                             do ct_conId <- pStrInt+                                ct_symbol <- pStr+                                ct_secType <- pStr+                                ct_expiry <- pStr+                                ct_strike <- pStrDouble+                                ct_right <- pStr+                                ct_multiplier <- pStr+                                ct_exchange <- pStr+                                ct_currency <- pStr+                                ct_localSymbol <- pStr+                                let ct_tradingClass = ""++                                if (ver >= 2)+                                    then do ct_tradingClass <- pStr+                                            return ()+                                    else return () ++                                return Contract { ct_conId+                                                , ct_symbol+                                                , ct_secType+                                                , ct_expiry+                                                , ct_strike+                                                , ct_right+                                                , ct_multiplier+                                                , ct_exchange+                                                , ct_currency+                                                , ct_localSymbol+                                                , ct_tradingClass +                                                }+pPositionEnd :: Int -> Int -> Parser IBMessage+pPositionEnd _ _ = return PositionEnd  ++pAccountSummary :: Int -> Int -> Parser IBMessage +pAccountSummary _ _ = AccountSummary <$> +        pStrInt +    <*> pStr+    <*> pStr+    <*> pStr+    <*> pStr+    <?> "Account Summary" ++pAccountSummaryEnd :: Int -> Int -> Parser IBMessage +pAccountSummaryEnd _ _ = AccountSummaryEnd <$> pStrInt <?> "Account Summary End"++pVerifyMessageAPI :: Int -> Int -> Parser IBMessage  +pVerifyMessageAPI _ _ = VerifyMessageAPI <$>+        pStr+    <?> "Verify Message API"    ++pVerifyCompleted :: Int -> Int -> Parser IBMessage   +pVerifyCompleted _ _ = VerifyCompleted <$>+        pStr+    <*> pStr+    <?> "Verify Completed"++pDisplayGroupList :: Int -> Int -> Parser IBMessage    +pDisplayGroupList _ _ = DisplayGroupList <$>+        pStrInt+    <*> pStr+    <?> "Display Group List"++        +pDisplayGroupUpdated :: Int -> Int -> Parser IBMessage     +pDisplayGroupUpdated _ _ = DisplayGroupUpdated <$>+        pStrInt+    <*> pStr+    <?> "Display Group Updated"+ +pCommissionReport :: Int -> Int -> Parser IBMessage+pCommissionReport _ _  = CommissionReport <$>+        pStr+    <*> pStrDouble+    <*> pStr+    <*> pStrDouble+    <*> pStrDouble+    <*> pStrInt+    <?> "Commission Report"++pContractDataEnd :: Int -> Int -> Parser IBMessage+pContractDataEnd _ _ = ContractDataEnd <$> pStrInt <?> "Contract Data End"  ++pOpenOrderEnd :: Int -> Int -> Parser IBMessage+pOpenOrderEnd _ _ = return OpenOrderEnd+ +pAcctDownloadEnd :: Int -> Int -> Parser IBMessage+pAcctDownloadEnd _ _ = AcctDownloadEnd <$> pStr <?> "Acct Download End"++pExecutionDataEnd :: Int -> Int -> Parser IBMessage  +pExecutionDataEnd _ _ = ExecutionDataEnd <$> pStrInt <?> "Execution Data End"++pDeltaNeutralValidation :: Int -> Int -> Parser IBMessage   +pDeltaNeutralValidation _ _ =  DeltaNeutralValidation <$> pStrInt+    <*> pUnderComp' <?> "Delta Neutral Validation"++pTickSnapshotEnd :: Int -> Int -> Parser IBMessage+pTickSnapshotEnd _ _ = TickSnapshotEnd <$> pStrInt <?> "Tick Snapshot End"++pMarketDataType :: Int -> Int -> Parser IBMessage +pMarketDataType _ _ = MarketDataType <$> pStrInt <*> pStrInt <?> "Market Data"++pOrderState :: Parser OrderState+pOrderState = OrderState <$> +        pStr+    <*> pStr+    <*> pStr+    <*> pStr+    <*> pStrDoubleMax+    <*> pStrDoubleMax+    <*> pStrDoubleMax+    <*> pStr+    <*> pStr+    <?> "Order State"++--if (ver >= 6) +--  then do cumQty <- pStrInt+--          avgPrice <- pStrDouble+--  else let cumQty = int32max+--           avgPrice = dblMaximum++--if (ver >= 8)+--  then do orderRef <- pStr+--  else return () ++--if (ver >= 9) +--  then do evRule <- pStr+--          evMultiplier <- pStrDouble+--  else let evRule = ""+--           evMultiplier = dblMaximum++pExecution :: Int -> Int -> Parser Execution+pExecution _ ver = +    do  ex_execId <- pStr+        ex_time <- pStr+        ex_acctNumber <- pStr+        ex_exchange <- pStr+        ex_side <- pStr+        ex_shares <- pStrInt+        ex_price <- pStrDouble+        ex_permId <- pStrInt+        ex_clientId <- pStrInt+        ex_liquidation <- pStrInt+    +        let ex_cumQty = int32max+            ex_avgPrice = dblMaximum+            ex_orderRef = ""+            ex_evRule = ""+            ex_evMultiplier = dblMaximum++        case () of+         _ | ver >= 9 -> do ex_cumQty <- pStrInt+                            ex_avgPrice <- pStrDouble+                            ex_orderRef <- pStr+                            ex_evRule <- pStr+                            ex_evMultiplier <- pStrDouble+                            return ()+           | ver >= 8 -> do ex_cumQty <- pStrInt+                            ex_avgPrice <- pStrDouble+                            ex_orderRef <- pStr+                            return ()+           | ver >= 6 -> do ex_cumQty <- pStrInt+                            ex_avgPrice <- pStrDouble+                            return ()++        return Execution +              { ex_execId  +              , ex_time+              , ex_acctNumber+              , ex_exchange+              , ex_side+              , ex_shares+              , ex_price+              , ex_permId+              , ex_clientId+              , ex_liquidation+              , ex_cumQty+              , ex_avgPrice+              , ex_orderRef+              , ex_evRule+              , ex_evMultiplier +              }++pExecutionData :: Int -> Int -> Parser IBMessage+pExecutionData _ ver = do reqId <- pStrInt +                          orderId <- pStrInt +                          contract <- pContract'+                          exec <- pExecution 0 ver+                          return ExecutionData { reqId+                                               , orderId+                                               , contract+                                               , exec +                                               } +                            where pContract' :: Parser Contract+                                  pContract' = +                                    do ct_conId <- pStrInt+                                       ct_symbol <- pStr+                                       ct_secType <- pStr+                                       ct_expiry <- pStr+                                       ct_strike <- pStrDouble+                                       ct_right <- pStr+                                       +                                       let ct_multiplier = ""+                                           ct_tradingClass = ""++                                       if (ver >= 9)+                                           then do ct_multiplier <- pStr+                                                   return ()+                                           else return () ++                                       ct_exchange <- pStr+                                       ct_currency <- pStr+                                       ct_localSymbol <- pStr+                                       +                                       if (ver >= 10)+                                           then do ct_tradingClass <- pStr+                                                   return ()+                                           else return ()++                                       return Contract { ct_conId+                                                       , ct_symbol+                                                       , ct_secType+                                                       , ct_expiry+                                                       , ct_strike+                                                       , ct_right+                                                       , ct_multiplier+                                                       , ct_exchange+                                                       , ct_currency+                                                       , ct_localSymbol+                                                       , ct_tradingClass +                                                       }++pMarketDepth :: Int -> Int -> Parser IBMessage+pMarketDepth _ _ = MarketDepth <$>+        pStrInt+    <*> pStrInt+    <*> pStrInt+    <*> pStrInt+    <*> pStrDouble+    <*> pStrInt+    <?> "Market Depth"++pMarketDepthL2 :: Int -> Int -> Parser IBMessage+pMarketDepthL2 _ _ = MarketDepthL2 <$>+        pStrInt+    <*> pStrInt+    <*> pStr+    <*> pStrInt+    <*> pStrInt+    <*> pStrDouble+    <*> pStrInt+    <?> "Market Depth L2"+ +pBondContractData :: Int -> Int -> Parser IBMessage+pBondContractData _ ver = +    do  let reqId = -1 +        if (ver >= 3) then do reqId <- pStrInt+                              return ()+                      else return ()+        ct_symbol <- pStr+        ct_secType <- pStr+        ctd_cusip <- pStr+        ctd_coupon <- pStrDouble+        ctd_maturity <- pStr+        ctd_issueDate <- pStr+        ctd_ratings <- pStr+        ctd_bondType <- pStr+        ctd_couponType <- pStr+        ctd_convertible <- pStrBool+        ctd_callable <- pStrBool+        ctd_putable <- pStrBool+        ctd_descAppend <- pStr+        ct_exchange <- pStr+        ct_currency <- pStr+        ctd_marketName <- pStr+        ct_tradingClass <- pStr+        ct_conId <- pStrInt+        ctd_minTick <- pStrDouble+        ctd_orderTypes <- pStr+        ctd_validExchanges <- pStr+        ctd_nextOptionDate <- pStr+        ctd_nextOptionType <- pStr+        ctd_nextOptionPartial <- pStrBool+        ctd_notes <- pStr+        +        let ctd_summary = Contract { ct_symbol+                               , ct_secType+                               , ct_exchange+                               , ct_currency+                               , ct_tradingClass+                               , ct_conId+                               }+            ctd_secIdList = []+            ctd_evRule = ""+            ctd_longName = ""+            ctd_evMultiplier = dblMaximum++        case () of+         _ | ver >= 6 -> do ctd_longName <- pStr+                            ctd_evRule <- pStr+                            ctd_evMultiplier <- pStrDouble+                            ctd_secIdList <- pTagValueCons+                            return ()+           | ver >= 5 -> do ctd_longName <- pStr+                            ctd_secIdList <- pTagValueCons+                            return ()+           | ver >= 4 -> do ctd_longName <- pStr+                            return ()++        let ctd = ContractDetails { ctd_summary+                                  , ctd_marketName+                                  , ctd_minTick+                                  , ctd_orderTypes+                                  , ctd_validExchanges+                                  , ctd_longName+                                  , ctd_evRule+                                  , ctd_evMultiplier+                                  , ctd_secIdList+                                  , ctd_notes+                                  , ctd_nextOptionPartial+                                  , ctd_nextOptionType+                                  , ctd_nextOptionDate+                                  , ctd_descAppend+                                  , ctd_putable+                                  , ctd_callable+                                  , ctd_convertible+                                  , ctd_couponType+                                  , ctd_bondType+                                  , ctd_ratings+                                  , ctd_issueDate+                                  , ctd_maturity+                                  , ctd_coupon+                                  , ctd_cusip+                                  }+        return $ BondContractData ctd++pNewsBulletins :: Int -> Int -> Parser IBMessage  +pNewsBulletins _ _ = NewsBulletins <$>+        pStrInt+    <*> pStrInt+    <*> pStr+    <*> pStr+    <?> "News Bulletins"+ +pContractData :: Int -> Int -> Parser IBMessage+pContractData _ ver = do+    let reqId = -1+    if (ver >= 3) then do reqId <- pStrInt+                          return ()+                  else return ()+    ct_symbol <- pStr+    ct_secType <- pStr+    ct_expiry <- pStr+    ct_strike <- pStrDouble+    ct_right <- pStr+    ct_exchange <- pStr+    ct_currency <- pStr+    ct_localSymbol <- pStr+    ctd_marketName <- pStr+    ctd_minTick <- pStrDouble+    ct_multiplier <- pStr+    ctd_orderTypes <- pStr+    ctd_validExchanges <- pStr+    ctd_priceMagnifier <- pStrInt++    let ctd_underConId = int32max +        ctd_longName = ""+        ct_primaryExchange = ""+        ctd_evRule = ""+        ctd_evMultiplier = dblMaximum+        ctd_secIdList = []+        ctd_contractMonth = ""+        ctd_industry = ""+        ctd_category = ""+        ctd_subcategory = ""+        ctd_timeZoneId = ""+        ctd_tradingHours = ""+        ctd_liquidHours = ""++    if (ver >= 4) then do ctd_underConId <- pStrInt+                          return ()+                  else return () +    if (ver >= 5) then do ctd_longName <- pStr+                          ct_primaryExchange <- pStr +                          return ()+                  else return () +                      +    if (ver >= 6) then do ctd_contractMonth <- pStr+                          ctd_industry <- pStr+                          ctd_category <- pStr+                          ctd_subcategory <- pStr+                          ctd_timeZoneId <- pStr+                          ctd_tradingHours <- pStr+                          ctd_liquidHours <- pStr+                          return ()+                   else return ()+                   +    if (ver >= 8) then do ctd_evRule <- pStr+                          ctd_evMultiplier <- pStrDouble+                          return ()+                  else return ()++    if (ver >= 7) then do ctd_secIdList <- pTagValueCons+                          return ()+                  else return ()+                                       +    let ctd_summary = Contract { ct_symbol+                               , ct_secType+                               , ct_expiry+                               , ct_primaryExchange+                               , ct_strike+                               , ct_right+                               , ct_multiplier+                               , ct_exchange+                               , ct_currency+                               , ct_localSymbol +                               }++        ctd = ContractDetails { ctd_summary+                              , ctd_marketName+                              , ctd_minTick+                              , ctd_orderTypes+                              , ctd_validExchanges+                              , ctd_priceMagnifier+                              , ctd_underConId+                              , ctd_longName+                              , ctd_contractMonth+                              , ctd_industry+                              , ctd_category+                              , ctd_subcategory+                              , ctd_timeZoneId+                              , ctd_tradingHours+                              , ctd_liquidHours+                              , ctd_evRule+                              , ctd_evMultiplier+                              , ctd_secIdList+                              }+    return $ ContractData ctd+pContract :: Int -> Int -> Parser Contract+pContract _ ver =+     do let ct_multiplier = ""+            ct_trading_class = ""+        ct_conId <- pStrInt+        ct_symbol <- pStr+        ct_secType <- pStr+        ct_expiry <- pStr+        ct_strike <- pStrDouble+        ct_right <- pStr++        if (ver >= 32)+            then do ct_multiplier <- pStr+                    return ()+            else return ()++        ct_exchange <- pStr+        ct_currency <- pStr+        ct_localSymbol <- pStr+        +        if (ver >= 32)+            then do ct_tradingClass <- pStr+                    return ()+            else return ()++        return Contract { ct_conId+                        , ct_symbol+                        , ct_secType+                        , ct_expiry+                        , ct_strike+                        , ct_right+                        , ct_multiplier+                        , ct_exchange+                        , ct_currency+                        , ct_localSymbol+                        }++pOrder :: Int -> Int -> Parser Order+pOrder serv_ver ver = +     do ord_action <- pStr+        ord_totalQuantity <- pStrInt+        ord_orderType <- pStr+        let ord_exemptCode = int32max+            ord_deltaNeutralConId = int32max+            ord_deltaNeutralSettlingFirm = ""+            ord_deltaNeutralClearingAccount = ""+            ord_deltaNeutralClearingIntent = ""+            ord_deltaNeutralOpenClose = ""+            ord_deltaNeutralShortSale = False+            ord_deltaNeutralShortSaleSlot = int32max+            ord_deltaNeutralDesignatedLocation = ""+            ord_trailingPercent = dblMaximum++        if (ver < 29)+           then do ord_lmtPrice <- pStrDouble+                   return ()+           else do ord_lmtPrice <- pStrDoubleMax+                   return ()++        if (ver < 30)+           then do ord_auxPrice <- pStrDouble+                   return ()+           else do ord_auxPrice <- pStrDoubleMax+                   return () ++        ord_tif <- pStr+        ord_ocaGroup <- pStr+        ord_account <- pStr+        ord_openClose <- pStr+        ord_origin' <- pStrInt+        ord_orderRef <- pStr+        ord_clientId <- pStrInt+        ord_permId <- pStrInt+        ord_outsideRth <- pStrBool+        ord_hidden <- pStrBool+        ord_discretionaryAmt <- pStrDouble+        ord_goodAfterTime <- pStr+        ord_pStr <- pStr -- deprecated sharesAllocation Field, unused+        ord_faGroup <- pStr+        ord_faMethod <- pStr+        ord_faPercentage <- pStr +        ord_faProfile <- pStr+        ord_goodTillDate <- pStr+        ord_rule80A <- pStr+        ord_percentOffset <- pStrDoubleMax+        ord_settlingFirm <- pStr+        ord_shortSaleSlot <- pStrInt+        ord_designatedLocation <- pStr++        if (serv_ver == min_server_ver_sshortx_old)+           then do pStrInt+                   return () +           else if (ver >= 23) +            then do ord_exemptCode <- pStrInt+                    return ()+           else return ()++        ord_auctionStrategy <- pStrInt+        ord_startingPrice <- pStrDoubleMax+        ord_stockRefPrice <- pStrDoubleMax+        ord_delta <- pStrDoubleMax+        ord_stockRangeLower <- pStrDoubleMax+        ord_stockRangeUpper <- pStrDoubleMax+        ord_displaySize <- pStrInt+        ord_blockOrder <-  pStrBool+        ord_sweepToFill <- pStrBool+        ord_allOrNone <- pStrBool+        ord_minQty <- pStrIntMax+        ord_ocaType <- pStrInt+        ord_eTradeOnly <- pStrBool+        ord_firmQuoteOnly <- pStrBool+        ord_nbboPriceCap <- pStrDoubleMax+        ord_parentId <- pStrInt+        ord_triggerMethod <- pStrInt+        ord_volatility <- pStrDoubleMax+        ord_volatilityType <- pStrInt+        ord_deltaNeutralOrderType <- pStr+        ord_deltaNeutralAuxPrice <- pStrDoubleMax++        if (ver >= 27 && not (null ord_deltaNeutralOrderType))+            then do ord_deltaNeutralConId <- pStrInt +                    ord_deltaNeutralSettlingFirm <- pStr+                    ord_deltaNeutralClearingAccount <- pStr+                    ord_deltaNeutralClearingIntent <- pStr+                    return () +            else if (ver >= 31 && not  (null ord_deltaNeutralOrderType))+                then do ord_deltaNeutralOpenClose <- pStr+                        ord_deltaNetralShortSale <- pStrBool+                        ord_deltaNeutralShortSaleSlot <- pStrInt+                        ord_deltaNeutralDesignatedLocation <- pStr+                        return ()+            else return ()++        ord_continuousUpdate <- pStrBool+        ord_referencePriceType <- pStrInt+        ord_trailStopPrice <- pStrDoubleMax+        +        if (ver >= 30)+            then do ord_trailingPercent <- pStrDoubleMax+                    return ()+            else return () +        +        ord_basisPoints <- pStrDoubleMax+        ord_basisPointsType <- pStrIntMax+        let ord_origin = toEnum ord_origin'++        return Order { ord_action+                     , ord_totalQuantity+                     , ord_orderType+                     , ord_tif+                     , ord_ocaGroup+                     , ord_account+                     , ord_openClose+                     , ord_origin+                     , ord_orderRef+                     , ord_clientId+                     , ord_permId+                     , ord_outsideRth+                     , ord_hidden+                     , ord_discretionaryAmt+                     , ord_goodAfterTime+                     , ord_faGroup+                     , ord_faMethod+                     , ord_faPercentage+                     , ord_faProfile+                     , ord_goodTillDate+                     , ord_rule80A+                     , ord_percentOffset+                     , ord_settlingFirm+                     , ord_shortSaleSlot+                     , ord_designatedLocation+                     , ord_exemptCode+                     , ord_auctionStrategy+                     , ord_startingPrice+                     , ord_stockRefPrice+                     , ord_delta+                     , ord_stockRangeLower+                     , ord_stockRangeUpper+                     , ord_displaySize+                     , ord_blockOrder+                     , ord_sweepToFill+                     , ord_allOrNone+                     , ord_minQty+                     , ord_ocaType+                     , ord_eTradeOnly+                     , ord_firmQuoteOnly+                     , ord_nbboPriceCap+                     , ord_parentId+                     , ord_triggerMethod+                     , ord_volatility+                     , ord_volatilityType+                     , ord_deltaNeutralOrderType+                     , ord_deltaNeutralAuxPrice+                     , ord_deltaNeutralConId+                     , ord_deltaNeutralSettlingFirm+                     , ord_deltaNeutralClearingAccount+                     , ord_deltaNeutralClearingIntent+                     , ord_deltaNeutralOpenClose+                     , ord_deltaNeutralShortSale+                     , ord_deltaNeutralShortSaleSlot+                     , ord_deltaNeutralDesignatedLocation+                     , ord_continuousUpdate+                     , ord_referencePriceType+                     , ord_trailStopPrice+                     , ord_trailingPercent+                     , ord_basisPoints+                     , ord_basisPointsType+                     }++ +pOrderStatus :: Int -> Int -> Parser IBMessage+pOrderStatus _ _  = OrderStatus <$>+            pStrInt+        <*> pStr +        <*> pStrInt+        <*> pStrInt+        <*> pStrDouble+        <*> pStrInt+        <*> pStrInt+        <*> pStrDouble+        <*> pStrInt+        <*> pStr+        <?> "Order Status"++pErr :: Int -> Int -> Parser IBMessage+pErr _ _ = Err <$> pStrInt <*> pStr <?> "Err Msg"++pComboLeg :: Parser ComboLeg+pComboLeg = ComboLeg <$> +        pStrInt+    <*> pStrInt+    <*> pStr+    <*> pStr+    <*> pStrInt+    <*> pStrInt+    <*> pStr+    <*> pStrInt+    <?> "Combo Leg"++pTagValueCons :: Parser [TagValue]+pTagValueCons = +    do listCount <- pStrInt+       if (listCount > 0)+        then do tvl <- replicateM listCount pTagValue+                return tvl+        else do return []++pComboLegCons :: Int -> Int -> Parser [ComboLeg]+pComboLegCons _ ver = +    if (ver >= 29) then do +                        comboLegsCount <- pStrInt +                        if (comboLegsCount > 0)+                            then do tvl <- replicateM comboLegsCount pComboLeg +                                    return tvl+                            else return []+    else return []++pOrderComboLeg :: Parser OrderComboLeg+pOrderComboLeg = +    do ordComboLeg <- pStrDoubleMax+       return ordComboLeg+++pBarData :: Parser BarData+pBarData = BarData <$>+        pStr+    <*> pStrDouble+    <*> pStrDouble+    <*> pStrDouble+    <*> pStrDouble+    <*> pStrInt+    <*> pStrDouble+    <*> pStr+    <*> pStrInt+    <?> "Bar Data"++pScanData :: Parser ScanData+pScanData = ScanData <$>+        pStrInt+    <*> plocContractDetails+    <*> pStr+    <*> pStr+    <*> pStr+    <*> pStr+    <?> "Scan Data"+        where+          plocContractDetails = do ct_conId <- pStrInt+                                   ct_symbol <- pStr+                                   ct_secType <- pStr+                                   ct_expiry <- pStr+                                   ct_strike <- pStrDouble+                                   ct_right <- pStr+                                   ct_exchange <- pStr+                                   ct_currency <- pStr+                                   ct_localSymbol <- pStr+                                   ctd_marketName <- pStr+                                   ct_tradingClass <- pStr++                                   let ctd_summary = Contract { ct_conId+                                                          , ct_symbol+                                                          , ct_secType+                                                          , ct_expiry+                                                          , ct_strike+                                                          , ct_right+                                                          , ct_exchange+                                                          , ct_currency+                                                          , ct_localSymbol+                                                          , ct_tradingClass+                                                          }+                                   return ContractDetails { ctd_summary+                                                          , ctd_marketName}++pScanDataList :: Parser [ScanData]+pScanDataList = do numberOfElements <- pStrInt+                   scl <- replicateM numberOfElements pScanData+                   return scl++pOrderComboLegCons :: Int -> Int -> Parser [OrderComboLeg]+pOrderComboLegCons _ ver +    | ver >= 29 = do orderComboLegsCount <- pStrInt+                     case () of+                      _ | orderComboLegsCount > 0 -> do ocl <- replicateM orderComboLegsCount pOrderComboLeg+                                                        return ocl+                        | otherwise -> return []+    | otherwise = return []++pBarDataCons :: Parser [BarData]+pBarDataCons  = do itemCount <- pStrInt+                   bdl <- replicateM itemCount pBarData+                   return bdl++pUnderComp' :: Parser UnderComp+pUnderComp' = UnderComp <$> pStrInt <*> pStrDouble <*> pStrDouble <?> "UnderComp"++pUnderComp :: Int -> Int -> Parser UnderComp+pUnderComp _ ver = +    do if (ver >= 20) +        then do underCompPresent <- pStrBool+                let uc_conId = int32max+                    uc_delta = dblMaximum+                    uc_price = dblMaximum ++                if (underCompPresent) +                    then do uc_conId <- pStrInt+                            uc_delta <- pStrDouble+                            uc_price <- pStrDouble+                            return ()+                    else return ()++                return UnderComp {uc_conId, uc_delta, uc_price}+        else return UnderComp {}++-- TODO: Convert to pattern guard case structure+pAlgoStrategy :: Int -> Int -> Parser (String,[TagValue])+pAlgoStrategy _ ver = +    do if (ver >= 21) +        then do algoStrategy <- pStr+                if (not (null algoStrategy)) +                 then do algoParamsCount <- pStrInt+                         if (algoParamsCount > 0)+                           then do agl <- replicateM algoParamsCount pTagValue+                                   return (algoStrategy, agl)+                           else return (empty,[])+                         return (empty,[])+                 else return (empty,[] )+        else return (empty,[] )                               +++pOpenOrder :: Int -> Int -> Parser IBMessage+pOpenOrder serv_ver ver = +    do  let ord_smartComboRoutingParams = [] +            ord_scaleSubsLevelSize = int32max+            ord_hedgeType = ""+            ord_hedgeParam = ""+            ord_optOutSmartRouting = False+            ord_notHeld = False+            ord_scalePriceAdjustValue = dblMaximum +            ord_scalePriceAdjustInterval = int32max+            ord_scaleProfitOffset = dblMaximum+            ord_scaleAutoReset = False+            ord_scaleInitPosition = int32max+            ord_scaleInitFillQty = int32max+            ord_scaleRandomPercent = False+            ord_scaleInitLevelSize = int32max++        orderId <- pStrInt+        contract' <- pContract serv_ver ver+        order' <- pOrder serv_ver ver+        ct_comboLegsDescrip <- pStr+        comboLeg <- pComboLegCons serv_ver ver+        orderComboLegs <- pOrderComboLegCons serv_ver ver++        if (ver >= 26) then do ord_smartComboRoutingParams <- pTagValueCons+                               return ()+                       else return ()++        if (ver >= 20)+            then do ord_scaleInitLevelSize <- pStrIntMax+                    ord_scaleSubsLevelSize <- pStrIntMax+                    return ()+            else do pStr+                    ord_scaleInitLevelSize <- pStrIntMax+                    return () ++        ord_scalePriceIncrement <- pStrDoubleMax+        +        if (ver >= 28 && ord_scalePriceIncrement > 0.0 && ord_scalePriceIncrement /= dblMaximum)+            then do ord_scalePriceAdjustValue <- pStrDoubleMax+                    ord_scalePriceAdjustInterval <- pStrIntMax+                    ord_scaleProfitOffset <- pStrDoubleMax+                    ord_scaleAutoReset <- pStrBool+                    ord_scaleInitPosition <- pStrIntMax+                    ord_scaleInitFillQty <- pStrIntMax+                    ord_scaleRandomPercent <- pStrBool+                    return ()+            else return ()++        if (ver >= 24) +            then do ord_hedgeType <- pStr+                    if (not (null ord_hedgeType)) +                        then do ord_hedgeParam <- pStr+                                return ()+                        else return ()+                    return () +            else return ()++        if (ver >= 25) then do ord_optOutSmartRouting <- pStrBool+                               return ()+                       else return ()++        ord_clearingAccount <- pStr+        ord_clearingIntent <- pStr++        if (ver >= 22) then do notHeld <- pStrBool+                               return ()+                       else return ()++        ct_underComp <- pUnderComp serv_ver ver+        (ord_algoStrategy, ord_algoParams) <- pAlgoStrategy serv_ver ver+        ord_whatIf <- pStrBool+        orderState <- pOrderState++        let order = order' { ord_whatIf+                           , ord_notHeld+                           , ord_smartComboRoutingParams+                           , ord_algoStrategy+                           , ord_algoParams+                           , ord_clearingAccount+                           , ord_clearingIntent+                           , ord_optOutSmartRouting+                           , ord_hedgeType+                           , ord_hedgeParam+                           , ord_scaleInitLevelSize+                           , ord_scaleSubsLevelSize+                           , ord_scalePriceIncrement+                           , ord_scalePriceAdjustValue+                           , ord_scalePriceAdjustInterval+                           , ord_scaleProfitOffset+                           , ord_scaleAutoReset+                           , ord_scaleInitPosition+                           , ord_scaleInitFillQty+                           , ord_scaleRandomPercent+                           }++        let contract = contract' { ct_underComp+                                 , ct_comboLegsDescrip  +                                 } ++        return OpenOrder { order+                         , contract+                         , comboLeg+                         , orderComboLegs+                         , orderState+                         }++pTickOptionComputation :: Int -> Int -> Parser IBMessage+pTickOptionComputation _ ver = do +        let gamma = dblMaximum+            vega = dblMaximum+            theta = dblMaximum +            undPrice = dblMaximum +            optPrice = dblMaximum+            pvDividend = dblMaximum +        tickerId <- pStrInt+        tickType <- pStrInt+        impliedVol <- dblCheckNegative <$> pStrDouble+        delta <- pStrDouble++        if (ver >= 6 || tickType == fromEnum MODEL_OPTION)+          then do optPrice <- dblCheckNegative <$> pStrDouble+                  pvDividend <- dblCheckNegative <$> pStrDouble  +                  return ()+          else return ()++        if (ver >= 6)+          then do gamma <- dblDefaultCheck <$> pStrDouble+                  vega <- dblDefaultCheck <$> pStrDouble+                  theta <- dblDefaultCheck <$> pStrDouble+                  undPrice <- dblDefaultCheck <$> pStrDouble+                  return ()+          else return ()++        return $ TickOptionComputation tickerId tickType impliedVol delta optPrice pvDividend gamma vega theta undPrice++pTickGeneric :: Int -> Int -> Parser IBMessage+pTickGeneric _ _ = TickGeneric <$>+            pStrInt+        <*> pStrInt+        <*> pStrDouble+        <?> "Tick Generic"++pIBMsg :: Int -> Int -> Int -> Parser IBMessage+pIBMsg id sver ver = case idToMsg id of+    TickPrice {} -> pTickPrice sver ver+    TickSize {} -> pTickSize sver ver+    TickOptionComputation {}   -> pTickOptionComputation sver ver+    TickGeneric {}  -> pTickGeneric sver ver+    TickString {}  -> pTickString  sver ver+    TickEFP {}  -> pTickEFP sver ver+    OrderStatus {}  -> pOrderStatus sver ver+    Err {}  -> pErr sver ver+    OpenOrder {}   -> pOpenOrder sver ver+    AcctValue {}  -> pAcctValue sver ver+    PortfolioValue {} -> pPortfolioValue sver ver+    AcctUpdateTime {} -> pAcctUpdateTime sver ver+    NextValidId  {}   -> pNextValidId sver ver+    ContractData  {}  -> pContractData sver ver+    BondContractData  {}  -> pBondContractData sver ver+    ExecutionData  {}  -> pExecutionData sver ver+    MarketDepth  {}  -> pMarketDepth sver ver+    MarketDepthL2  {}  -> pMarketDepthL2 sver ver+    NewsBulletins  {}  -> pNewsBulletins sver ver+    ManagedAccts  {}  -> pManagedAccts sver ver+    ReceiveFA  {}  -> pReceiveFA sver ver+    HistoricalData  {}  -> pHistoricalData sver ver+    ScannerData  {}  -> pScannerData sver ver+    ScannerParameters {}   -> pScannerParameters sver ver+    CurrentTime  {}  -> pCurrentTime sver ver+    RealTimeBars  {}  -> pRealTimeBars sver ver+    FundamentalData  {}  -> pFundamentalData sver ver+    ContractDataEnd  {}  -> pContractDataEnd sver ver+    OpenOrderEnd  {}  -> pOpenOrderEnd  sver ver+    AcctDownloadEnd  {}  -> pAcctDownloadEnd sver ver+    ExecutionDataEnd  {}  -> pExecutionDataEnd sver ver+    DeltaNeutralValidation  {}  -> pDeltaNeutralValidation  sver ver+    TickSnapshotEnd  {}  -> pTickSnapshotEnd  sver ver+    MarketDataType {}   -> pMarketDataType sver ver+    CommissionReport  {}  -> pCommissionReport sver ver+    PositionData  {}  -> pPositionData sver ver+    PositionEnd {}   -> pPositionEnd sver ver+    AccountSummary  {}  -> pAccountSummary sver ver+    AccountSummaryEnd {}  -> pAccountSummaryEnd sver ver+    VerifyMessageAPI {}   -> pVerifyMessageAPI sver ver+    VerifyCompleted  {} -> pVerifyCompleted sver ver+    DisplayGroupList  {}  -> pDisplayGroupList sver ver+    DisplayGroupUpdated  {}  -> pDisplayGroupUpdated sver ver+    _         -> return IBUnknown  
+ src/IB/Client/Request.hs view
@@ -0,0 +1,601 @@+{-# LANGUAGE NamedFieldPuns #-}++module IB.Client.Request +  (+    -- * Types+    Request(..)+  +    -- * Functions+  , request +  , wFlush+  , write+  , show'+  , debugWrite+  ) where++import Control.Concurrent.MVar+import Control.Exception+import Control.Monad (when)+import Text.Printf+import qualified System.IO as S+import qualified Data.ByteString.Char8 as B+import Data.Maybe++import IB.Client.Exception+import IB.Client.Nums+import IB.Client.Types++data ReqHeader = +    ReqHeader +    { rqh_msgId :: Int +    , rqh_proVer :: Int+    , rqh_errId :: Int+    , rqh_errMsg :: String+    , rqh_minVer :: Int+    , rqh_exAuth :: Bool+    }++defReqHeader = ReqHeader 1 1 no_valid_id "" undefined undefined++(<++>) :: B.ByteString -> B.ByteString -> B.ByteString+a <++> b =  a `B.append` nullch `B.append` b `B.append` nullch++debugWrite :: IBServer -> String -> IO ()+debugWrite s msg =+    (when (s_debug s) $ putStrLn msg)++write :: IBServer -> B.ByteString -> IO ()+write s msg = do+    debugWrite s $ "<< " ++ B.unpack msg +    B.hPutStr h (msg <++> B.pack "\0")+    where h = fromJust $ s_sock s++wFlush :: IBServer -> IO ()+wFlush s = S.hFlush h+    where h = fromJust $ s_sock s++show' :: Show a => a -> B.ByteString+show' = B.pack . show++nullch :: B.ByteString+nullch = B.pack "\0"++encodeDbl :: Double -> B.ByteString +encodeDbl val = B.pack (printf "%.2f" val)++encodeIntMax :: Int -> B.ByteString +encodeIntMax val +    | val == int32max = B.pack "" +    | otherwise = show' val++encodeDblMax :: Double -> B.ByteString +encodeDblMax val+    | val == dblMaximum = B.pack "" +    | otherwise = encodeDbl val++encodeExecutionFilter :: ExecutionFilter -> B.ByteString +encodeExecutionFilter exf = (show' $ exf_clientId exf )+                                    <++> (B.pack $ exf_acctCode exf)+                                    <++> (B.pack $ exf_time exf)+                                    <++> (B.pack $ exf_symbol exf)+                                    <++> (B.pack $ exf_secType exf)+                                    <++> (B.pack $ exf_exchange exf)+                                    <++> (B.pack $ exf_side exf )+++encodeSubscription :: ScannerSubscription -> B.ByteString +encodeSubscription subs = (encodeIntMax $ ssb_numberOfRows subs)+                             <++> (B.pack $ ssb_instrument subs)+                             <++> (B.pack $ ssb_locationCode subs)+                             <++> (B.pack $ ssb_scanCode subs)+                             <++> (encodeDblMax $ ssb_abovePrice subs)+                             <++> (encodeDblMax $ ssb_belowPrice subs)+                             <++> (encodeIntMax $ ssb_aboveVolume subs)+                             <++> (encodeDblMax $ ssb_marketCapAbove subs)+                             <++> (encodeDblMax $ ssb_marketCapBelow subs)+                             <++> (B.pack $ ssb_moodyRatingAbove subs)+                             <++> (B.pack $ ssb_moodyRatingBelow subs)+                             <++> (B.pack $ ssb_spRatingAbove subs)+                             <++> (B.pack $ ssb_spRatingBelow subs)+                             <++> (B.pack $ ssb_maturityDateAbove subs)+                             <++> (B.pack $ ssb_maturityDateBelow subs)+                             <++> (encodeDblMax $ ssb_couponRateAbove subs)+                             <++> (encodeDblMax $ ssb_couponRateBelow subs)+                             <++> (encodeIntMax $ ssb_excludeConvertible subs)+                             <++> (encodeIntMax $ ssb_averageOptionVolumeAbove subs)+                             <++> (B.pack $ ssb_scannerSettingPairs subs)+                             <++> (B.pack $ ssb_stockTypeFilter subs)++                              +encodeTagValue :: TagValue -> B.ByteString +encodeTagValue tv = B.pack $ tv_tag tv ++ "=" ++ tv_value tv ++ ";" + +encodeTagValueList :: [TagValue] -> B.ByteString+encodeTagValueList tvl = B.concat $ map encodeTagValue tvl++encodeUnderComp :: UnderComp -> B.ByteString +encodeUnderComp uc = show' 1 <++> (show' $ uc_conId uc )+                        <++> (show' $ uc_price uc)++encodeComboLeg :: ComboLeg -> B.ByteString +encodeComboLeg cl =  (show' $ cl_conId cl)+                        <++> (show' $ cl_ratio cl )+                        <++> (B.pack $ cl_action cl )+                        <++> (B.pack $ cl_exchange cl)++encodeComboLegList :: [ComboLeg] -> B.ByteString +encodeComboLegList cll = (show' $ length cll) <++> (B.concat $ map encodeComboLeg cll )++encodeContract :: IBServer -> Contract -> Bool -> IO B.ByteString +encodeContract s con pexch = +    do let serv_ver = s_version s +           bs | serv_ver >= min_server_ver_trading_class = show' $ ct_conId con+              | otherwise = B.empty +           out = bs <++> (B.pack $ ct_symbol con)+                    <++> (B.pack $ ct_secType con)+                    <++> (B.pack $ ct_expiry con)+                    <++> (show' $ ct_strike con)+                    <++> (B.pack $ ct_right con)+                    <++> (B.pack $ ct_multiplier con)+                    <++> (B.pack $ ct_exchange con)+           out' | pexch = out <++> ( B.pack $ ct_primaryExchange con )+                | otherwise = out+           out'' = out' <++> (B.pack $ ct_currency con)+                        <++> (B.pack $ ct_localSymbol con)++       if (serv_ver >= min_server_ver_trading_class)+            then return $ out'' <++> (B.pack $ ct_tradingClass con)+            else return out'' + +getHeaderCon :: IBServer -> ReqHeader -> Contract -> IO B.ByteString +getHeaderCon s rqh con = +    do let hndle =  s_sock s +           connected = s_connected s +           serv_ver = s_version s +           mExtraAuth = s_extraAuth s + +       case () of+        _ | not connected -> throwIO $ IBExc (rqh_errId rqh) NotConnected ""  +          | rqh_minVer rqh /= undefined -> +                if ((serv_ver < (rqh_minVer rqh)) && ((not $ null ( ct_tradingClass con)) || (ct_conId con) > 0))+                    then throwIO $ IBExc (rqh_errId rqh) UpdateTWS (rqh_errMsg rqh)+                    else return ()++       return $ (show' $ rqh_msgId rqh) <++> (show' $ rqh_proVer rqh)++getHeader :: IBServer -> ReqHeader -> IO B.ByteString +getHeader s rqh = +    do let hndle =  s_sock s +           connected = s_connected s +           serv_ver = s_version s +           mExtraAuth = s_extraAuth s + +       case () of+        _ | not connected -> throwIO $ IBExc (rqh_errId rqh) NotConnected ""  +          | rqh_minVer rqh /= undefined -> if (serv_ver < rqh_minVer rqh) then throwIO $ IBExc (rqh_errId rqh) UpdateTWS (rqh_errMsg rqh)+                                                               else return ()+          | rqh_exAuth rqh /= undefined -> if (not mExtraAuth) then throwIO $ IBExc (no_valid_id) UpdateTWS "  Intent to authenticate needs to be expressed during initial connect request."+                                                               else return ()++       return $ (show' $ rqh_msgId rqh) <++> (show' $ rqh_proVer rqh)++request :: IBServer -> Request -> IO ()++request s inp @ (MktDataReq { }) = +    do let hndle =  s_sock s +           connected = s_connected s +           serv_ver = s_version s +           mExtraAuth = s_extraAuth s +           ct = mdr_contract inp+           tickerId = rqp_tickerId inp+           version = 11++       case () of+        _ | not connected -> throwIO $ IBExc tickerId NotConnected ""  +          | (serv_ver < min_server_ver_under_comp) && (ct_underComp ct /= undefined) -> throwIO $ IBExc tickerId UpdateTWS "  It does not support fundamental data requests." +          | (serv_ver < min_server_ver_req_mkt_data_conid) && (ct_conId ct > 0) -> throwIO $ IBExc tickerId UpdateTWS "  It does not support conId parameter."  +          | (serv_ver < min_server_ver_trading_class) && (not $ null (ct_tradingClass ct)) -> throwIO $ IBExc tickerId UpdateTWS "  It does not support tradingClass parameter in reqMktData."   +          | otherwise -> return ()++       let bs = (show' (reqToId MktDataReq {}))+                 <++> (show' version)+                 <++> (show' tickerId)+           conbs | serv_ver >= min_server_ver_req_mkt_data_conid = show' $ ct_conId ct +                 | otherwise = B.empty++           bs' = bs <++> conbs+            <++> (B.pack $ ct_symbol ct )+            <++> (B.pack $ ct_secType ct)+            <++> (B.pack $ ct_expiry ct)+            <++> (show' $ ct_strike ct)+            <++> (B.pack $ ct_right ct)+            <++> (B.pack $ ct_multiplier ct )+            <++> (B.pack $ ct_exchange ct)+            <++> (B.pack $ ct_primaryExchange ct)+            <++> (B.pack $ ct_currency ct)+            <++> (B.pack $ ct_localSymbol ct)++           tclass | serv_ver >= min_server_ver_trading_class = (show' $ ct_tradingClass ct )+                  | otherwise = B.empty++           clist | compare (ct_secType ct) "BAG" == EQ = encodeComboLegList (ct_comboLegsList ct) +                 | otherwise = B.empty+           ucomp | serv_ver >= min_server_ver_under_comp && ct_underComp ct /= undefined = encodeUnderComp (ct_underComp ct) +                 | otherwise = show' 0+           bs'' = bs'  +                    <++> tclass +                    <++> clist +                    <++> ucomp +                    <++> (B.pack $ mdr_genericTicks inp )+                    <++> (show' $ fromBool ( mdr_snapshot inp))++       if (serv_ver >= min_server_ver_linking)+           then write s $ bs'' <++> ( encodeTagValueList $ mdr_mktDataOptions inp)+           else write s bs'' ++       wFlush s++request s rq @ (CancelMktData { rqp_tickerId = tid }) =+    do  hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                                        , rqh_proVer = 2+                                        , rqh_errId = tid+                                        }+        write s $ hdr <++> show' tid+        wFlush s++request s rq @ (PlaceOrder { rqp_orderId = oid }) =+    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                                       , rqh_proVer = 2+                                       , rqh_errId = oid+                                       }+       write s $ hdr <++> show' oid+       wFlush s+-- TODO PlaceOrder Complete++request s rq @ (CancelOrder oid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                                       , rqh_errId = oid+                                       }+       write s $ hdr <++> show' oid+       wFlush s++request s rq @ (OpenOrdersReq) = do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq } +                                    write s hdr +                                    wFlush s++request s rq @ (AccountUpdatesReq {aur_subscribe = subscribe, aur_acctCode = acctCode}) = +     do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                                        , rqh_proVer = 2+                                        }+        write s $ (show' ( fromBool subscribe)) <++> B.pack acctCode+        wFlush s++request s rq @ (ExecutionsReq req_id exc_filt) =+    do  hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                                      , rqh_proVer = 3+                                      }+        let serv_ver = s_version s +            reqbs | serv_ver >= min_server_ver_execution_data_chain = show' req_id+                  | otherwise = B.empty++        write s $ hdr <++> reqbs <++> encodeExecutionFilter exc_filt+        wFlush s++request s rq @ (IdsReq numIds) = do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq, rqh_errId = numIds }+                                    write s $ hdr <++> show' numIds+                                    wFlush s+--TODO+--request s rq @ (ContractDetailsReq req_id contract) = ++request s rq @ (MktDepthReq { rqp_tickerId = tid+                            , mkr_contract = con+                            , mkr_numRows = numRows+                            , mkr_mktDepthOptions = mkDepthOpts+                            }) =  +    do let serv_ver = s_version s ++       hdr <- getHeaderCon s defReqHeader { rqh_msgId = reqToId rq+                                        , rqh_proVer = 5+                                        , rqh_minVer = min_server_ver_trading_class+                                        , rqh_errId = tid+                                        , rqh_errMsg = "  It does not support conId and tradingClass parameters in reqMktDepth."+                                        } con+       con' <- encodeContract s con False++       write s $ hdr <++> (show' tid) <++> con' <++> (show' numRows)++       if (serv_ver >= min_server_ver_linking)+           then write s $ encodeTagValueList mkDepthOpts+           else return () ++       wFlush s+ +request s rq @ (CancelMktDepth tid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq,+                                 rqh_errId = tid}+       write s $ hdr <++> show' tid +       wFlush s++request s rq @ (NewsBulletinsReq allMsgs) =+    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq}+       write s $ hdr <++> show' ( fromBool allMsgs)+       wFlush s++request s rq @ (CancelNewsBulletins) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq } +       write s hdr++request s rq @ (SetServerLogLevel llvl) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq }+       write s $ hdr <++> show' llvl+       wFlush s++request s rq @ (AutoOpenOrdersReq autoBind) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq }+       write s $ hdr <++> show' (fromBool autoBind)+       wFlush s++request s rq @ (AllOpenOrdersReq) =+    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq } +       write s hdr+       wFlush s++request s rq @ (ManagedAcctsReq) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq }   +       write s hdr+       wFlush s++request s rq @ (FAReq fad) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq}  +       write s $ hdr <++> show' ( fromEnum' fad)++request s rq @ (FAReplaceReq fad cxml) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq}  +       write s $ hdr <++> show' (fromEnum' fad) <++> B.pack cxml+       wFlush s++request s rq @ (HistoricalDataReq {rqp_tickerId = tid+                                    , hdr_contract = con+                                    , hdr_endDataTime = edt+                                    , hdr_durationStr = durStr+                                    , hdr_whatToShow = whatToShow+                                    , hdr_formatDate = formatDate+                                    , hdr_chartOptions = chartOptions+                                    , hdr_useRTH = useRTH+                                    , hdr_barSizeSetting = barSizeSetting+                                    }) =  +    do  let serv_ver = s_version s +        hdr <-  getHeaderCon s defReqHeader { rqh_msgId = reqToId rq+                                   , rqh_proVer = 6+                                   , rqh_errId = tid+                                   , rqh_minVer = min_server_ver_trading_class+                                   , rqh_errMsg = "  It does not support conId and tradingClass parameters in reqHistoricalData."+                                   } con+        con' <- encodeContract s con True++        write s $ (hdr <++> show' tid)+            <++> con'+            <++> (show' $ fromBool $ ct_includeExpired con  )+            <++> (B.pack edt)+            <++> (B.pack barSizeSetting)+            <++> (B.pack durStr)+            <++> (show' useRTH)+            <++> (B.pack whatToShow)+            <++> (show' formatDate)++        if (compare (ct_secType con) "BAG" == EQ)+            then write s $ encodeComboLegList (ct_comboLegsList con) +            else return () +      +        if (serv_ver >= min_server_ver_linking)+            then write s $ encodeTagValueList chartOptions+            else return ()++        wFlush s+ +request s rq @ (ExerciseOptionsReq { rqp_tickerId = tid+                                   , eor_contract = con +                                   , eor_exerciseAction = exerciseAction +                                   , eor_exerciseQuantity = exerciseQty +                                   , eor_account = account +                                   , eor_override = override +                                   }) =  +    do  let serv_ver = s_version s +        hdr <-  getHeaderCon s defReqHeader { rqh_msgId = reqToId rq+                                         , rqh_proVer = 2+                                         , rqh_errId = tid+                                         , rqh_minVer = min_server_ver_trading_class+                                         , rqh_errMsg = "  It does not support conId and tradingClass parameters in reqHistoricalData."+                                         } con+        con' <- encodeContract s con False++        write s $ hdr <++> show' tid+                <++> con'+                <++> (show' exerciseAction)+                <++> (show' exerciseQty)+                <++> (B.pack account)+                <++> (show' override )+        wFlush s++request s rq @ (ScannerSubscriptionReq { rqp_tickerId = tid+                                       , ssr_subscription = subs+                                       , ssr_subscriptionOptions = subsOpts+                                       }) = +    do  let serv_ver = s_version s+        hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq +                                      , rqh_proVer = 4+                                      , rqh_errId = tid+                                      }+        write s $ show' tid <++> encodeSubscription subs++        if (serv_ver >= min_server_ver_linking)+            then write s $ encodeTagValueList subsOpts+            else return ()++        wFlush s++request s rq @ (CancelScannerSubscription tid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                                     , rqh_errId = tid +                                     }+       write s $ hdr <++> show' tid+       wFlush s++-- TODO: verify correctness+request s rq @ (ScannerParametersReq) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq }+       write s $ hdr+       wFlush s++request s rq @ (CancelHistoricalData tid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_errId = tid +                               } +       write s $ hdr <++> show' tid+       wFlush s++++request s rq @ (CurrentTimeReq) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq } +       write s hdr+       wFlush s++-- TODO needs dev+--+request s rq @ (RealTimeBarsReq {}) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq } +       write s hdr+       wFlush s++request s rq @ (CancelRealTimeBars tid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_errId = tid } +       write s $ hdr <++> show' tid+       wFlush s+++request s rq @ (CancelFundamentalData tid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                                     , rqh_errId = tid+                                     , rqh_minVer = min_server_ver_fundamental_data+                                     , rqh_errMsg = "  It does not support fundamental data requests." +                                     }+       write s $ hdr <++> show' tid+       wFlush s++--TODO+--request s rq @ (CalcOptionPriceReq {}) = ++request s rq @ (CancelCalcImpliedVolatility tid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                                     , rqh_errId = tid+                                     , rqh_minVer = min_server_ver_cancel_calc_implied_volat+                                     , rqh_errMsg = "  It does not support calculate implied volatility cancellation." +                                     }+       write s $ hdr <++> show' tid+       wFlush s++request s rq @ (CancelCalcOptionPrice tid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_errId = tid+                               , rqh_minVer = min_server_ver_cancel_calc_option_price+                               , rqh_errMsg = "  It does not support calculate option price cancellation." +                               }+       write s $ hdr <++> show' tid+       wFlush s++request s rq @ (GlobalCancelReq) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq +                                     , rqh_errMsg = "  It does not support globalCancel requests."+                                     , rqh_minVer = min_server_ver_req_global_cancel+                                     }  +       write s $ hdr+       wFlush s++request s rq @ (MarketDataTypeReq tid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq}+       write s $ hdr <++> show' tid+       wFlush s+++request s rq @ (PositionsReq) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq}+       write s $ hdr +       wFlush s+--TODO+--request s rq @ (AccountSummaryReq {}) = ++request s rq @ (CancelAccountSummary req_id) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                                     , rqh_minVer =  min_server_ver_account_summary+                                     , rqh_errMsg = "  It does not support account summary cancellation." +                                     }+       write s $ hdr+       wFlush s+                               +request s rq @ (CancelPositions) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_errMsg = "  It does not support positions cancellation." +                               , rqh_minVer = min_server_ver_positions+                               }+       write s $ hdr+       wFlush s+++request s rq @ (VerifyReq apiName apiVersion) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_minVer = min_server_ver_linking+                               , rqh_errMsg = "  It does not support verification message sending." +                               , rqh_exAuth = True+                               } +       write s $ hdr <++> B.pack apiName <++> B.pack apiVersion+       wFlush s++request s rq @ (VerifyMessage apiData) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_minVer = min_server_ver_linking+                               , rqh_errMsg = "  It does not support verification message sending." +                               } +       write s $ hdr <++> B.pack apiData+       wFlush s++request s rq @ (QueryDisplayGroups rid) =+    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_minVer = min_server_ver_linking+                               , rqh_errMsg = "  It does not support queryDisplayGroups request." +                               } +       write s $ hdr <++> show' rid+       wFlush s+  +request s rq @ (SubscribeToGroupEvents reqId gid) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_minVer = min_server_ver_linking+                               , rqh_errMsg = "  It does not support subscribeToGroupEvents request." +                               } +       write s $ hdr <++> show' reqId+                <++> show' gid+       wFlush s++request s rq @ (UpdateDisplayGroup reqId contractInfo) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_minVer = min_server_ver_linking+                               , rqh_errMsg = "  It does not support updateDisplayGroup request." +                               } +       write s $ show' reqId+            <++> B.pack contractInfo+       wFlush s++request s rq @ (UnsubscribeFromGroupEvents reqId) = +    do hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq+                               , rqh_minVer = min_server_ver_linking+                               , rqh_errMsg = "  It does not support unsubscribeFromGroupEvents request." +                               } +       write s $ hdr <++> show' reqId+       wFlush s++request s rq @ (StartApi) = +    do  let clientId = s_clientId s+        hdr <- getHeader s defReqHeader { rqh_msgId = reqToId rq } +        write s $ hdr <++> show' clientId+        wFlush s
+ src/IB/Client/Types.hs view
@@ -0,0 +1,824 @@+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DeriveDataTypeable #-}++module IB.Client.Types where++import Control.Concurrent+import Control.Concurrent.MVar+import Data.Int+import System.IO+import Data.Data++data Request =  +    MktDataReq +    { rqp_tickerId :: TickerId+    , mdr_contract :: Contract+    , mdr_genericTicks :: String+    , mdr_snapshot :: Bool+    , mdr_mktDataOptions :: [TagValue]+    }+    | CancelMktData { rqp_tickerId  :: TickerId }+    | PlaceOrder+    { rqp_orderId :: OrderId+    , por_contract :: Contract+    , por_order :: Order+    } +    | CancelOrder { rqp_orderId :: OrderId }+    | OpenOrdersReq+    | AccountUpdatesReq { aur_subscribe :: Bool, aur_acctCode :: String }+    | ExecutionsReq+    { rqp_reqId :: ReqId+    , exe_filter :: ExecutionFilter+    } +    | IdsReq Int +    | ContractDetailsReq+    { rqp_reqId :: ReqId+    , cdr_contract :: Contract+    }+    |  MktDepthReq  +    { rqp_tickerId :: TickerId+    , mkr_contract :: Contract+    , mkr_numRows :: Int +    , mkr_mktDepthOptions :: [TagValue]+    } +    | CancelMktDepth TickerId+    | NewsBulletinsReq Bool+    | CancelNewsBulletins+    | SetServerLogLevel Int+    | AutoOpenOrdersReq Bool+    | AllOpenOrdersReq+    | ManagedAcctsReq+    | FAReq FaDataType+    | FAReplaceReq +    { far_pFaDataType :: FaDataType +    , far_cxml :: String+    }+    | HistoricalDataReq +    { rqp_tickerId :: TickerId+    , hdr_contract :: Contract+    , hdr_endDataTime :: String+    , hdr_durationStr :: String+    , hdr_barSizeSetting :: String+    , hdr_whatToShow :: String+    , hdr_useRTH :: Int+    , hdr_formatDate :: Int+    , hdr_chartOptions :: [TagValue]+    }+    | ExerciseOptionsReq  +    { rqp_tickerId :: TickerId+    , eor_contract :: Contract+    , eor_exerciseAction :: Int+    , eor_exerciseQuantity :: Int+    , eor_account :: String+    , eor_override :: Int+    }  +    | ScannerSubscriptionReq+    { rqp_tickerId :: TickerId+    , ssr_subscription :: ScannerSubscription+    , ssr_subscriptionOptions :: [TagValue]+    }+    | CancelScannerSubscription TickerId+    | ScannerParametersReq  +    | CancelHistoricalData TickerId+    | CurrentTimeReq+    | RealTimeBarsReq   +    { rqp_tickerId :: TickerId+    , rtb_contract :: Contract+    , rtb_barSize :: Int +    , rtb_whatToShow :: String+    , rtb_useRTH :: Bool+    , rtb_realTimeBarsOptions :: [TagValue]+    }+    | CancelRealTimeBars TickerId+    | FundamentalDataReq+    { rqp_reqId :: TickerId+    , fdr_contract :: Contract+    , fdr_reportType :: String+    }+    | CancelFundamentalData TickerId+    | ImpliedVolatilityReq+    { rqp_tickerId :: TickerId+    , ivr_contract :: Contract+    , ivr_optionPrice :: Double+    , ivr_underPrice :: Double+    }+    | CalcOptionPriceReq  +    { rqp_tickerId :: TickerId+    , opr_contract :: Contract+    , opr_volatility :: Double+    , opr_underPrice :: Double+    }+    | CancelCalcImpliedVolatility TickerId+    | CancelCalcOptionPrice TickerId+    | GlobalCancelReq+    | MarketDataTypeReq TickerId+    | PositionsReq+    | AccountSummaryReq+    { rqp_reqId :: ReqId+    , asr_groupName :: String+    , asr_tags :: String+    }+    | CancelAccountSummary ReqId+    | CancelPositions+    | VerifyReq+    { vr_apiName :: String+    , vr_apiVer :: String+    } +    | VerifyMessage String+    | QueryDisplayGroups ReqId+    | SubscribeToGroupEvents ReqId GroupId+    | UpdateDisplayGroup+    { rqp_reqId :: Int+    , udg_contractInfo :: String+    } +    | UnsubscribeFromGroupEvents ReqId+    | StartApi+        deriving (Typeable, Data) ++data IBMessage +    = TickPrice +    { tickerId :: Int+    , tickType :: Int+    , price   :: Double+    , size    :: Int+    , canAutoExecute :: Int+    } +    | TickSize +    { tickerId :: Int+    , tickType :: Int+    , price   :: Double+    , size    :: Int+    } +    | OrderStatus +    { orderId :: Int+    , status :: String+    , filled :: Int+    , remaining :: Int+    , avgFillPrice :: Double+    , permId      :: Int+    , parentId    :: Int+    , lastFillPrice :: Double+    , clientId    :: Int+    , whyHeld :: String+    }+    | Err  +    { errorCode   :: Int+    , errorMsg :: String+    }+    | OpenOrder +    { order   :: Order+    , contract :: Contract +    , comboLeg :: [ComboLeg]+    , orderComboLegs :: [OrderComboLeg]+    , orderState :: OrderState+    }+    | AcctValue  +    { key     :: String+    , val     :: String+    , cur     :: String+    , accountName :: String +    }+    | PortfolioValue+    { contract    :: Contract+    , position    :: Int+    , marketPrice :: Double+    , marketValue :: Double+    , averageCost :: Double+    , unrealizedPNL :: Double+    , realizedPNL :: Double+    , accountName :: String+    }+    | AcctUpdateTime String +    | NextValidId Int  +    | ContractData ContractDetails  +    | ExecutionData  +    { reqId :: Int+    , orderId :: Int+    , contract :: Contract+    , exec    :: Execution+    }+    | MarketDepth +    { id :: Int +    , position :: Int +    , operation :: Int +    , side :: Int +    , price :: Double +    , size :: Int +    }+    | MarketDepthL2 +    { id :: Int +    , position :: Int +    , marketMaker :: String +    , operation :: Int +    , side :: Int +    , price :: Double +    , size :: Int +    }+    | NewsBulletins  +    { msgId :: Int +    , msgType :: Int +    , newsMessage :: String +    , originatingExch :: String +    }+    | ManagedAccts String  +    | ReceiveFA  +    { faDataTypeInt :: Int+    , cxml :: String    +    }+    | HistoricalData +    { reqId :: Int+    , startDateStr :: String+    , endDateStr :: String+    , barDataList :: [BarData] +    }+    | BondContractData ContractDetails  +    | ScannerParameters String  +    | ScannerData  +    { tickerId :: Int+    , scannerDataList :: [ScanData] +    }+    | TickOptionComputation +    { tickerId :: Int+    , tickType :: Int+    , impliedVol :: Double+    , delta       :: Double+    , optPrice    :: Double+    , pvDividend  :: Double+    , gamma       :: Double+    , vega        :: Double+    , theta       :: Double+    , undPrice    :: Double+    }+    | TickGeneric  +    { tickerId :: Int+    , tickType :: Int+    , tg_value :: Double+    }+    | TickString+    { tickerId :: Int+    , tickType :: Int+    , ts_value :: String+    }+    | TickEFP  +    { tickerId :: Int+    , tickType :: Int+    , basisPoints	:: Double+    , formattedBasisPoints	:: String+    , impliedFuturesPrice	:: Double+    , holdDays	:: Int+    , futureExpiry	:: String+    , dividendImpact	:: Double+    , dividendsToExpiry	:: Double+    } +    | CurrentTime Int   +    | RealTimeBars  +    { reqId :: Int+    , time :: Int+    , open :: Double+    , high :: Double+    , low :: Double+    , close :: Double+    , volume :: Int+    , average :: Double+    , count :: Int+    }+    | FundamentalData +    { reqId :: Int+    , fdata :: String+    }+    | ContractDataEnd ReqId  +    | OpenOrderEnd  +    | AcctDownloadEnd String  +    | ExecutionDataEnd ReqId  +    | DeltaNeutralValidation  +    { reqId :: Int+    , underComp :: UnderComp+    }+    | TickSnapshotEnd ReqId  +    | MarketDataType +    { reqId :: Int+    , marketDataType :: Int+    } +    | CommissionReport  +    { execId :: String +    , commission :: Double+    , currency :: String+    , realizedPNL :: Double+    , yield :: Double+    , yieldRedemptionDate :: Int +    }+    | PositionData  +    { account :: String+    , contract :: Contract+    , position :: Int+    , avgCost :: Double+    }+    | PositionEnd  +    | AccountSummary  +    { reqId :: Int+    , account :: String+    , tag :: String+    , value :: String+    , currency :: String+    }+    | AccountSummaryEnd ReqId +    | VerifyMessageAPI String   +    | VerifyCompleted  +    { isSuccessful :: String+    , errorText :: String+    }+    | DisplayGroupList  +    { reqId :: Int+    , groups :: String+    }+    | DisplayGroupUpdated  +    { reqId :: Int+    , contractInfo :: String+    }+    | IBUnknown +        deriving (Typeable, Data)++data RecvMsg = +    RecvMsg+    { rc_msgId  ::  Int+    , rc_version :: Int+    , rc_msgBody :: IBMessage+    } ++type ReqId = Int+type OrderComboLeg = Double+type TickerId = Int+type OrderId  = Int+type GroupId  = Int+type MIB = MVar IBServer++type HandlerFunc = (MIB -> IBMessage -> IO ())++data IBServer = +    IBServer+    { s_addr :: String+    , s_port :: Int+    , s_clientId :: Int+    , s_extraAuth :: Bool+    , s_version :: Int+    , s_connected :: Bool+    , s_twsTime :: Int+    , s_debug :: Bool+    , s_sock :: Maybe Handle+    , s_msgThread :: Maybe ThreadId+    , s_timeoutInterval :: Int+    , s_handler :: HandlerFunc+    }++data TickType = BID_SIZE | +                BID      | +                ASK      | +                ASK_SIZE | +                LAST     | +                LAST_SIZE|+				HIGH     | +                LOW      | +                VOLUME   | +                CLOSE    |+				BID_OPTION_COMPUTATION | +				ASK_OPTION_COMPUTATION | +				LAST_OPTION_COMPUTATION|+				MODEL_OPTION |+				OPEN |+				LOW_13_WEEK |+				HIGH_13_WEEK |+				LOW_26_WEEK |+				HIGH_26_WEEK |+				LOW_52_WEEK |+				HIGH_52_WEEK |+				AVG_VOLUME |+				OPEN_INTEREST |+				OPTION_HISTORICAL_VOL |+				OPTION_IMPLIED_VOL |+				OPTION_BID_EXCH |+				OPTION_ASK_EXCH |+				OPTION_CALL_OPEN_INTEREST |+				OPTION_PUT_OPEN_INTEREST |+				OPTION_CALL_VOLUME |+				OPTION_PUT_VOLUME |+				INDEX_FUTURE_PREMIUM |+				BID_EXCH |+				ASK_EXCH |+				AUCTION_VOLUME |+				AUCTION_PRICE |+				AUCTION_IMBALANCE |+				MARK_PRICE |+				BID_EFP_COMPUTATION |+				ASK_EFP_COMPUTATION |+				LAST_EFP_COMPUTATION |+				OPEN_EFP_COMPUTATION |+				HIGH_EFP_COMPUTATION |+				LOW_EFP_COMPUTATION |+				CLOSE_EFP_COMPUTATION |+				LAST_TIMESTAMP |+				SHORTABLE |+				FUNDAMENTAL_RATIOS |+				RT_VOLUME |+				HALTED |+				BID_YIELD |+				ASK_YIELD |+				LAST_YIELD |+				CUST_OPTION_COMPUTATION |+				TRADE_COUNT |+				TRADE_RATE |+				VOLUME_RATE |+				LAST_RTH_TRADE |+				NOT_SET +                    deriving (Show, Read, Eq, Enum)++data FaDataType =+    GROUPS |+    PROFILES |+    ALIASES +        deriving (Data, Typeable, Show, Read, Eq, Enum)++data Origin =+    CUSTOMER |+    FIRM     |+    UNKNOWN +        deriving (Data, Typeable, Show, Eq, Read, Enum)++data NewsBulletin =+    NEWS_MSG | EXCHANGE_AVAIL_MSG | EXCHANGE_UNAVAIL_MSG+        deriving (Show, Read, Enum)+++dblMaximum = encodeFloat 1 $ snd $ floatRange (0.0::Double)++int32max :: Int+int32max = fromIntegral (maxBound :: Int32) :: Int+int32min :: Int+int32min = fromIntegral (minBound :: Int32) :: Int++dblCheckNegative :: Double -> Double+dblCheckNegative inp+    | inp < 0 = dblMaximum+    | otherwise = inp++dblDefaultCheck :: Double -> Double+dblDefaultCheck inp = dblBoundsCheck 1.0 (-1.0) inp++dblBoundsCheck :: Double -> Double -> Double -> Double+dblBoundsCheck upperBounds lowerBounds inp+    | inp > upperBounds || inp < lowerBounds = dblMaximum+    | otherwise = inp++fromEnum' :: Enum a =>  a -> Int+fromEnum' a = (fromEnum a) +1++fromBool :: Num a => Bool -> a+fromBool False  = 0+fromBool True   = 1++isPrice :: TickType -> Bool+isPrice x = (x == BID) || (x == ASK) || (x == LAST) ++conToId :: Data a => a -> Int +conToId = constrIndex . toConstr ++msgToId :: IBMessage -> Int+msgToId = conToId++reqToId :: Request -> Int+reqToId = conToId++idToMsg :: Int -> IBMessage+idToMsg  = fromConstr . indexConstr (dataTypeOf IBUnknown) ++data Preamble = +    Preamble+    { pre_serverVersion :: Int+    , pre_twsTime :: Int+    }++data Execution = +    Execution +    { ex_execId	:: String+    , ex_time	:: String+    , ex_acctNumber	:: String+    , ex_exchange	:: String+    , ex_side	:: String+    , ex_shares	:: Int+    , ex_price	:: Double+    , ex_permId	:: Int+    , ex_clientId	:: Int+    , ex_liquidation	:: Int+    , ex_orderId	:: Int+    , ex_cumQty	:: Int+    , ex_avgPrice	:: Double+    , ex_orderRef	:: String+    , ex_evRule	:: String+    , ex_evMultiplier	:: Double+    } deriving (Data, Typeable)++data ExecutionFilter =+    ExecutionFilter+    { exf_clientId :: Int+    , exf_acctCode :: String+    , exf_time :: String+    , exf_symbol :: String+    , exf_secType :: String+    , exf_exchange :: String+    , exf_side :: String+    } deriving (Data, Typeable)++data BarData = +    BarData +    { bar_date :: String+    , bar_open :: Double+    , bar_high :: Double+    , bar_low :: Double+    , bar_close :: Double+    , bar_volume :: Int+    , bar_average :: Double+    , bar_hasGaps :: String+    , bar_barCount :: Int+    } deriving (Typeable, Data)++data ScanData  =+    ScanData+    { sd_rank :: Int+    , sd_contract :: ContractDetails+    , sd_distance :: String+    , sd_benchmark :: String+    , sd_projection :: String+    , sd_legsStr :: String+    } deriving (Typeable, Data)++data OrderState = +    OrderState +    { os_status	:: String+    , os_initMargin	:: String+    , os_maintMargin	:: String+    , os_equityWithLoan	:: String+    , os_commission	:: Double+    , os_minCommission	:: Double+    , os_maxCommission	:: Double+    , os_commissionCurrency	:: String+    , os_warningText	:: String+    } deriving (Typeable, Data)++data TagValue = +    TagValue +    { tv_tag :: String+    , tv_value :: String+    } deriving (Typeable, Data)+++data ScannerSubscription = +    ScannerSubscription+    { ssb_numberOfRows :: Int +    , ssb_instrument :: String +    , ssb_locationCode :: String +    , ssb_scanCode :: String +    , ssb_abovePrice :: Double +    , ssb_belowPrice :: Double +    , ssb_aboveVolume :: Int +    , ssb_marketCapAbove :: Double +    , ssb_marketCapBelow :: Double +    , ssb_moodyRatingAbove :: String +    , ssb_moodyRatingBelow :: String +    , ssb_spRatingAbove :: String +    , ssb_spRatingBelow :: String +    , ssb_maturityDateAbove :: String +    , ssb_maturityDateBelow :: String +    , ssb_couponRateAbove :: Double +    , ssb_couponRateBelow :: Double +    , ssb_excludeConvertible :: Int +    , ssb_averageOptionVolumeAbove :: Int +    , ssb_scannerSettingPairs :: String +    , ssb_stockTypeFilter :: String +    } deriving (Data, Typeable)++defScannerSubscription = ScannerSubscription { ssb_numberOfRows = -1+                                             , ssb_instrument = ""+                                             , ssb_locationCode = ""+                                             , ssb_scanCode = ""+                                             , ssb_abovePrice = dblMaximum+                                             , ssb_belowPrice = dblMaximum+                                             , ssb_aboveVolume = int32max+                                             , ssb_marketCapAbove = dblMaximum+                                             , ssb_marketCapBelow = dblMaximum+                                             , ssb_moodyRatingAbove = ""+                                             , ssb_moodyRatingBelow = ""+                                             , ssb_spRatingAbove = ""+                                             , ssb_spRatingBelow = ""+                                             , ssb_maturityDateAbove = ""+                                             , ssb_maturityDateBelow = ""+                                             , ssb_couponRateAbove = dblMaximum+                                             , ssb_couponRateBelow = dblMaximum+                                             , ssb_excludeConvertible = 0+                                             , ssb_averageOptionVolumeAbove = 0+                                             , ssb_scannerSettingPairs = ""+                                             , ssb_stockTypeFilter = ""+                                             }+data ComboLeg = +    ComboLeg +    { cl_conId	:: Int+    , cl_ratio	:: Int+    , cl_action	:: String --BUY/SELL/SSHORT+    , cl_exchange	:: String+    , cl_openClose	:: Int -- LegOpenClose enum values+    , cl_shortSaleSlot	:: Int -- 1 = clearing broker, 2 = third party+    , cl_designatedLocation	:: String+    , cl_exemptCode	:: Int+    } deriving (Typeable, Data)++data UnderComp = +    UnderComp +    { uc_conId   :: Int+    , uc_delta   :: Double+    , uc_price   :: Double+    } deriving (Typeable, Data, Eq)++data Contract = +    Contract+    { ct_conId	:: Int+    , ct_symbol	:: String+    , ct_secType	:: String+    , ct_expiry	:: String+    , ct_strike	:: Double+    , ct_right	:: String+    , ct_multiplier	:: String+    , ct_exchange	:: String+    , ct_primaryExchange	:: String -- pick an actual (ie non-aggregate) exchange that the contract trades on.  DO NOT SET TO SMART.+    , ct_currency	:: String+    , ct_localSymbol	:: String+    , ct_tradingClass	:: String+    , ct_includeExpired	:: Bool+    , ct_secIdType	:: String		-- CUSIPSEDOLISINRIC+    , ct_secId	:: String+     +     -- COMBOS+    , ct_comboLegsDescrip	:: String -- received in open order 14 and up for all combos+    , ct_comboLegsList :: [ComboLeg] +     -- combo legs+     --typedef std::vector<ComboLegSPtr> ComboLegList+     --typedef shared_ptr<ComboLegList> ComboLegListSPtr+     +     --ComboLegListSPtr comboLegs+     +     -- delta neutral+    , ct_underComp :: UnderComp+    } deriving (Typeable, Data)++data ContractDetails = +    ContractDetails+    { ctd_summary   :: Contract+    , ctd_marketName	:: String+    , ctd_minTick	:: Double+    , ctd_orderTypes	:: String+    , ctd_validExchanges	:: String+    , ctd_priceMagnifier	:: Int+    , ctd_underConId	:: Int+    , ctd_longName	:: String+    , ctd_contractMonth	:: String+    , ctd_industry	:: String+    , ctd_category	:: String+    , ctd_subcategory	:: String+    , ctd_timeZoneId	:: String+    , ctd_tradingHours	:: String+    , ctd_liquidHours	:: String+    , ctd_evRule	:: String+    , ctd_evMultiplier	:: Double+    , ctd_secIdList	:: [TagValue]+      --BOND	values+    , ctd_cusip	:: String+    , ctd_ratings	:: String+    , ctd_descAppend	:: String+    , ctd_bondType	:: String+    , ctd_couponType	:: String+    , ctd_callable	:: Bool+    , ctd_putable	:: Bool+    , ctd_coupon	:: Double+    , ctd_convertible	:: Bool+    , ctd_maturity	:: String+    , ctd_issueDate	:: String+    , ctd_nextOptionDate	:: String+    , ctd_nextOptionType	:: String+    , ctd_nextOptionPartial	:: Bool+    , ctd_notes	:: String+    } deriving (Data, Typeable)++data Order = +    Order +    { ord_orderId	:: Int+    , ord_clientId	:: Int+    , ord_permId	:: Int++    , ord_action	:: String+    , ord_totalQuantity	:: Int+    , ord_orderType	:: String+    , ord_lmtPrice	:: Double+    , ord_auxPrice	:: Double++    , ord_tif	:: String           -- "Time in Force" - DAY, GTC, etc.+    , ord_activeStartTime	:: String	-- for GTC orders+    , ord_activeStopTime	:: String	-- for GTC orders+    , ord_ocaGroup	:: String      -- one cancels all group name+    , ord_ocaType	:: Int       -- 1 = CANCEL_WITH_BLOCK, 2 = REDUCE_WITH_BLOCK, 3 = REDUCE_NON_BLOCK+    , ord_orderRef	:: String      -- order reference+    , ord_transmit	:: Bool      -- if false, order will be created but not transmited+    , ord_parentId	:: Int      -- Parent order Id, to associate Auto STP or TRAIL orders with the original order.+    , ord_blockOrder	:: Bool+    , ord_sweepToFill	:: Bool+    , ord_displaySize	:: Int+    , ord_triggerMethod	:: Int -- 0=Default, 1=Double_Bid_Ask, 2=Last, 3=Double_Last, 4=Bid_Ask, 7=Last_or_Bid_Ask, 8=Mid-po:: Int+    , ord_outsideRth	:: Bool+    , ord_hidden	:: Bool+    , ord_goodAfterTime	:: String    -- Format: 20060505 08:00:00 {time zone}+    , ord_goodTillDate	:: String     -- Format: 20060505 08:00:00 {time zone}+    , ord_rule80A	:: String -- Individual = 'I', Agency = 'A', AgentOtherMember = 'W', IndividualPTIA = 'J', AgencyPTIA = 'U', AgentOtherMemberPTIA = 'M', IndividualPT = 'K', AgencyPT = 'Y', AgentOtherMemberPT = 'N'+    , ord_allOrNone	:: Bool+    , ord_minQty	:: Int+    , ord_percentOffset	:: Double -- REL orders only+    , ord_overridePercentageConstraints	:: Bool+    , ord_trailStopPrice	:: Double -- TRAILLIMIT orders only+    , ord_trailingPercent	:: Double+        -- financial advisors only+    , ord_faGroup	:: String+    , ord_faProfile	:: String+    , ord_faMethod	:: String+    , ord_faPercentage	:: String+        -- institutional (ie non-cleared) only+    , ord_openClose	:: String -- O=Open, C=Close+    , ord_origin :: Origin    -- 0=Customer, 1=Firm+    , ord_shortSaleSlot	:: Int -- 1 if you hold the shares, 2 if they will be delivered from elsewhere.  Only for Action="SSHORT+    , ord_designatedLocation	:: String -- set when slot=2 only.+    , ord_exemptCode	:: Int+        -- SMART routing only+    , ord_discretionaryAmt	:: Double+    , ord_eTradeOnly	:: Bool+    , ord_firmQuoteOnly	:: Bool+    , ord_nbboPriceCap	:: Double+    , ord_optOutSmartRouting	:: Bool+        -- BOX exchange orders only+    , ord_auctionStrategy	:: Int -- AUCTION_MATCH, AUCTION_IMPROVEMENT, AUCTION_TRANSPARENT+    , ord_startingPrice	:: Double+    , ord_stockRefPrice	:: Double+    , ord_delta	:: Double+      -- pegged to stock and VOL orders only+    , ord_stockRangeLower	:: Double+    , ord_stockRangeUpper	:: Double+      -- VOLATILITY ORDERS ONLY+    , ord_volatility	:: Double+    , ord_volatilityType	:: Int     -- 1=daily, 2=annual+    , ord_deltaNeutralOrderType	:: String+    , ord_deltaNeutralAuxPrice	:: Double+    , ord_deltaNeutralConId	:: Int+    , ord_deltaNeutralSettlingFirm	:: String+    , ord_deltaNeutralClearingAccount	:: String+    , ord_deltaNeutralClearingIntent	:: String+    , ord_deltaNeutralOpenClose	:: String+    , ord_deltaNeutralShortSale	:: Bool+    , ord_deltaNeutralShortSaleSlot	:: Int+    , ord_deltaNeutralDesignatedLocation	:: String+    , ord_continuousUpdate	:: Bool+    , ord_referencePriceType	:: Int -- 1=Average, 2 = BidOrAsk+        -- COMBO ORDERS ONLY+    , ord_basisPoints	:: Double      -- EFP orders only+    , ord_basisPointsType	:: Int  -- EFP orders only+     -- SCALE ORDERS ONLY+    , ord_scaleInitLevelSize	:: Int+    , ord_scaleSubsLevelSize	:: Int+    , ord_scalePriceIncrement	:: Double+    , ord_scalePriceAdjustValue	:: Double+    , ord_scalePriceAdjustInterval	:: Int+    , ord_scaleProfitOffset	:: Double+    , ord_scaleAutoReset	:: Bool+    , ord_scaleInitPosition	:: Int+    , ord_scaleInitFillQty	:: Int+    , ord_scaleRandomPercent	:: Bool+    , ord_scaleTable	:: String+      -- HEDGE ORDERS+    , ord_hedgeType	:: String  -- 'D' - delta, 'B' - beta, 'F' - FX, 'P' - pair+    , ord_hedgeParam	:: String -- 'beta=X' value for beta hedge, 'ratio=Y' for pair hedge+      -- Clearing info+    , ord_account	:: String -- IB account+    , ord_settlingFirm	:: String+    , ord_clearingAccount	:: String -- True beneficiary of the order+    , ord_clearingIntent	:: String -- "" (Default), "IB", "Away", "PTA" (PostTrade)+    , ord_-- ALGO ORDERS ONLY+    , ord_algoStrategy	:: String+    , ord_algoParams    :: [TagValue]+    , ord_smartComboRoutingParams   :: [TagValue]+      -- What-if+    , ord_whatIf	:: Bool+      -- Not Held+    , ord_notHeld	:: Bool+        +    -- order combo legs+    --typedef std::vector<OrderComboLegSPtr> OrderComboLegList+    --typedef shared_ptr<OrderComboLegList> OrderComboLegListSPtr+    --+    --orderComboLegs	OrderComboLegListSPtr+    --orderMiscOptions	TagValueListSPtr+    } deriving (Data, Typeable)++