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 +674/−0
- Setup.hs +2/−0
- ib-api.cabal +70/−0
- src/Examples/Example.hs +34/−0
- src/IB/Client.hs +172/−0
- src/IB/Client/Exception.hs +84/−0
- src/IB/Client/Nums.hs +42/−0
- src/IB/Client/Parser.hs +1273/−0
- src/IB/Client/Request.hs +601/−0
- src/IB/Client/Types.hs +824/−0
+ 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)++