• Have any questions?
  • info.zbook.org@gmail.com

You’re Right, But Leave It. - Undocumented Matlab

8d ago
7 Views
0 Downloads
1.71 MB
10 Pages
Last View : 5d ago
Last Download : n/a
Upload by : Jacoby Zeller
Share:
Transcription

SOFTWARE REVIEWRY, surely?COVER STOit.You’re right, but leaveYeah right.Mashup!Well yes OK, we know we’re rather stretchingthe definition of “mashup” here, but it hasrather more punch as a title than “we attempt tocobble together some random bits of softwareinto a trading application/model doing a spotof (re)reviewing along the way”. Though that’sprobably a more accurate description of what theWrecking Crew and Automated Trader’s Founder,Andy Webb, have actually been up to for the lastmonth or two.ISo we started from the premise of doing ourpreliminary modelling in MATLAB and deployingany resulting models via IB-MATLAB to InteractiveBrokers’ trading API. However, just to make thingsa little more demanding, some of the modellinginvolved sufficiently hefty workloads to justify givingour test workstation’s CPUs a helping hand by usingits installed GPUs – courtesy of AccelerEyes Jacket –to rev up our MATLAB number crunching. While wecould have used Interactive Brokers’ historical data tofeed this set-up, this has some limitations regardingthe amount of data available. We therefore decidedto take CQG’s API for a spin by hooking it up toMATLAB to provide historical data.We could have left it there, with anyone wanting tomonitor automated trading activity using InteractiveBrokers’ Trader Workstation (TWS). But by this stagethe Wrecking Crew had its collective bit between itsteeth and it was decided that we would knock upsome form of monitoring station in Excel that wouldsn that perfect trading world in which we all exist,everybody has a single homogenous environmentthat handles everything – development, testing,live deployment, the lot. There’s never even the tiniestthing that your perfect environment cannot handle.Code never has to be ported to another application,everything is seamless so you don’t even have to knowwhat API stands for – let alone use one. Nothing evergoes wrong, the word “exception” is never heard (norare any of the other words that feature so regularly inthe Wrecking Crew’s vocabulary), optimisations takeseconds, if that, and trade execution nanoseconds.things is the Wrecking Crew’s forte and that tryingto get multiple things to work together implies morewreckage and greater job satisfaction, we thought thatin this issue we might try this “plugging together” outand revisit a few old friends along the way (while alsolooking at some new technology).Over here in the real world (and believe us, a worldinhabited by the Wrecking Crew can’t get muchmore real) budgets get cut, heads of IT insist thatVista is the One True Way, and not everybody hadKernighan and Ritchie as their bedtime reading atthe age of two. People want the flexibility to test anddeploy trade ideas quickly without having to spend asovereign defence budget on technology. Particularlyamong smaller hedge funds and proprietary tradinggroups, that often requires plugging various separateapplications together to achieve the desiredfunctionality, ease of use and time to market.Old friendsWhile things have improved dramatically inrecent years, the phrase “plugging variousseparate applications together” in theprevious paragraph can still easily end upas a synonym for “hours of frustration andnothing working”. Given that breakingQ1 2012 Automated Trader 8 061

Mashup!be fed via its COM interface withposition info from MATLAB (comingvia IB-MATLAB from IB) and viaCQG’s RTD server with real time andhistorical data. The extremist wing ofthe Wrecking Crew also wanted to adda manual trading interface to Excel onthe premise that any trader monitoringautomated models would soon becomebored playing park keeper and wouldwant to punt about a bit on their own.Fortunately reason prevailed (up toa point) and the moderate majorityheaded that one off at the pass.Unfortunately this proved to be anopening for the Crew’s oldest member.Horace (see Automated Trader Q22010) has been grumbling because recent reviewshaven’t given his natural talent for distrust much of anoutlet – no compliance manuals to read, no securityaudits to conduct. To get some peace and quiet, a furtheract of lunacy was added to the brew: instead of havingMATLAB send the position info direct to Excel, it wouldsend it to a local version of Excel in our server room,which would be automatically checked for updates by aninstance of Excel running on the park keeper’s/trader’sworkstation – in Italy. Or to be more precise, near thetop of a mountain in Italy with only a restricted capacitycommunity wireless internet link. Sigh.This immediately raised the issue of security, which inturn prompted a massive row about how to protect thelink between the two instances of Excel. Those of uslooking for a quiet life (and to finish this review before2014) opted for LogMeIn Hamachi, the hard geekcorewanted to use OpenVPN (and wanted to installTomatoVPN firmware on all our routers), but Horaceinsisted that we should use a Billion BiGuard S20 SSLVPN box that he had found in our spare parts bincovered in cobwebs and dust. (The fact that we didn’thave and could no longer buy the security tokens togenerate the one time passwords to use with this didn’tdeter him.)Having assembled this recipe for catastrophe, off weset.CQG MATLABAs the “consensus” was that we should try and puttogether some statarb strategies for equities, our firststep was to get some historical equity data from CQGinto MATLAB. From a programmer’s perspective,CQG’s API is thoroughly documented (although062 8 Automated Trader Q1 2012Figure 1some less experienced programmers might strugglewith figuring out how it all fits together). Fortunately,CQG provides a decent selection of MATLAB codesamples that illustrate how to connect everything upand actually get historical and real time data throughthe API. (Although CQG’s API supports a lot morethan just real time and historical data – includingaccount, position and order management – it doesn’tas yet provide execution in equity markets so we wereopting to use IB for that part of the brew.)While the CQG examples were perfectly adequate forour purposes, we actually chose to take advantage ofMATLAB’s ability to define custom object orientedclasses. One of our former Wrecking Crew members,Dr Yang Wang (see Automated Trader Q3 2010 andQ2 2011) had already knocked up a class packedfull of overloads that let us explore just about everypossible way of importing CQG data with negligibleeffort. We took full advantage.In doing so, we came across a curious problem thatat the time of going to press we still haven’t quite gotto the bottom of – though we have found a simplean effective workaround. We started out by invokingour object based on Dr Wang’s class from within afunction we had written to collect data from CQG,validate it for errors and to append it to an existingdatabase. Big mistake. A frustrating few hours thenensued as the data we had just requested from ourfunction kept disappearing. We created our objectwithin the function (“CQGMAT” being the classname) with:CQGMAT.new(‘cqg’);We could then see (see Figure 1) that our emptyobject had been successfully created in the function’s

SOFTWARE REVIEWworkspace (highlighted in red in Figure 1) from aquick look MATLAB’s Variable Editor.Running the next line of our function:cqg ssfully populated the necessary inputarguments (see Figure 2).Figure 2Then we ran the next line of the function:cqg cqg.Start();.which fired up the CQG interface and passes thearguments highlighted in Figure 2 for the desiredstock (in this case Maurel & Prom), the time frameof the bars requested (daily) and the number of barsrequired (8).Then nothing. No data ever came back!In MATLAB an object can obviously only remain inscope for a function while the invoking function isrunning (assuming the object hasn’t been explicitlymade global). As soon as the function exits, the objectdisappears. But this wasn’t our problem – the callingfunction had definitely not exited. We “F11d” throughthe code above and could see the object being created inthe MATLAB base workspace (complete with the pricebars we wanted) but the version of the object in thefunction’s workspace remained forever bar-less.code provided by CQG while trying to resolve ourdisappearing data problem above we found the APIworked perfectly. Although we were retrieving data forhistorical testing via the CQG API, we also did somedabbling with real time updates to try and get a feel forits capacity. Our portfolio of pairs was based upon a totalof 175 securities, of which more than half were largecaps with pretty frequent updates. While we didn’t haveany spectacularly fast markets during the test period toreally stress test things, we didn’t have any problems interms of bottlenecks. Just for the hell of it we also createdsome custom studies inCQG and pulled the valuesfor those into MATLABwithout any problems.However, as part of theCQG MATLAB process,we did come across oneother “interesting” potentialsnag – exchanges. Someexchanges have become extremely twitchy aboutdata vendors allowing their clients to access exchangedata through an API (the potential for “informal”redistribution of this data and loss of revenue for theexchange presumably being the issue at point). WhileCQG were extremely helpful with the authorisationprocess associated with this (major hat tips here to AliceMorrison and Brian Vancil of CQG – thanks both),certain exchanges didn’t exactly hurry. One Europeanexchange was first approached on December 1st 2011about API access to their data (and then politely andregularly reminded regularly thereafter) but took untilJanuary 20th 2012 to actually authorise data access.So the lesson appears to be that even if you can see anexchange’s data within your data vendor’s application,don’t assume that accessing that same data throughan API is a trivial matter – start the paperwork andnagging process as early as possible!This was clearly not a problem related to CQGand when we briefly reverted to using the sampleWe started by running two instances of our code ontwo machines – one with the code incorporating thesIn the end we lost patience and simply converted thefunction to script (which unlike a standard functioncan access the MATLAB base workspace) and retrievedour data that way (we could alternatively have left itas a function and used MATLAB’s evalin.m functionto access the data). Hopefully when Dr W returnsfrom Chinese New Year we’ll get to the bottom of theproblem and publish an update.First stepsIn our quest to make things as difficult as possible,it was decided that any testing of our initial model(which was for pairs) should include cointegrationtests across multiple time windows for each pair. Wehad over 1000 potential pairs to test and we ended updeciding to cointegration test 350 time windows foreach pair. We tried this using both MATLAB’s ownegcitest.m function for the Engle-Granger test fromits Econometrics Toolbox, as well as the equivalentcadf.m function provided in the freely available SpatialEconometrics toolbox.Q1 2012 Automated Trader 8 063

Mashup!MATLAB version of the Engle-Granger test and oneincorporating the Spatial Econometrics’ version. (Werather cut corners before doing this by only testingthat both stocks in each pair had unit roots once foreach pair across all the available data, using MATLAB’sversion of the augmented Dickey-Fuller test.)then calculating the values of all tiles at the same timeusing the individual cores of a CUDA-enabled GPU.However, while this has the potential to massivelyreduce computation times, the gfor loop does have afew limitations some of which would require changesto the functions we were using.We set the tests running, but after about forty minuteslost interest and went to find some beer.A case in point relates to “if ” statements, which arenot officially permitted at all inside gfor loops, becausethey implicitly pull data back to the CPU from theGPU. This could have been a major hassle for usin our testing, as both the MATLAB and SpatialEconometrics versions of the Engle-Granger test arelittered with conditional statements – as are many ofthe other functions that they call.MATLAB JACKETSince we originally reviewed it in early 2010, Jackethas changed beyond recognition. The number ofMATLAB functions it supports has ballooned andamong many other things now also includes supportfor doubles using left matrix divide (mldivide or \ inMATLAB), which was something we were whingeingabout in our original review. Another significantchange is that are you are no longer obliged to havethe MATLAB PCT in order to run Jacket acrossmultiple GPUs.We had already spent a fair bit of time trying to“vectorise” our MATLAB code in order to reduce thenumber of for loops (which – depending on the exactcircumstances – can significantly slow code executionin MATLAB). However, we were still left with a fewloops that we couldn’t eradicate, so we thought wewould use Jacket’s “gfor/gend” loops for the largestand innermost of these. Unlike conventional CPUbased looping, Jacket’s gfor/gend construct runs alliterations of a loop simultaneously. It achieves thisby “tiling out” the values of all loop iterations and064 8 Automated Trader Q1 2012if (p -1);error(‘p cannot be -1 in gcadf’);end;.then no errors were generated and the code wouldrun OK. However, if the “if ” statement involvedJacket-specific data types (such as gdouble or gsingle)then an error would throw.if((abs(adf) abs(crit(critval))))H 1;elseH 0;endAccelerEyes offer a number of suggested ratherelegant workarounds for this including one thatworks by expressing the conditional statement as amultiplication by logical values (see wiki.accelereyes.com/wiki/index.php/GFOR Usage#No logicalindexing). We took the rather more crude approachof, wherever possible, retrieving the values that wouldhave been involved in an “if ” statement back to thecalling function. So our original if statement aboveended up as:resultcoint abs(adf) abs(crit(critval));!The hard geekcore had originally wanted to use theJohansen cointegration test framework (also availablein both MATLAB’s Econometrics toolbox and theSpatial Econometrics toolbox), but the rest of theteam had a nasty feeling where that might lead towhen we tried to cut execution times, so we managedto kill that idea off. How right we were, as now theclamour was to cut execution times further by usingthe CUDA-enabled NVIDIA Tesla C1060s GPUs (seewww.nvidia.com/object/cuda home new.html) in theworkstations in conjunction with AccelerEyes Jacket.Fortunately, this wasn’t as much of a problem as weinitially expected. Firstly, we found that it appears thatyou can get away with “if ” statements in gfor loopsin certain circumstances. More specifically, if the “if ”statement was in a function called by the gfor loop,only involved MATLAB single or double data typesand was relatively straightforward, such as:NOUpon our return we found that both tests had finishedat about the same time (around the seventy minutemark). Wanting to cut this down significantly, wedecided to fire up MATLAB’s Parallel ComputingToolbox (PCT), which would let us distribute thetask across all four of the CPU cores available in eachtest workstation. That knocked the test times down toabout 22 minutes by replacing our original for loopswith the “parfor” loops available in the PCT.YES!.in the function inside the gfor loop. Then when we

SOFTWARE REVIEWhad built the complete table of resultcoint values andhad completed the gfor/gend loop we simply evaluatedthem all with:resultcoint(resultcoint 0) 0;resultcoint(resultcoint 0) 1;Hardly rocket science (to put it mildly) but it worked.Incidentally, we couldn’t have used the above linewithin the loop because apart from if statements, gfor/gend loops don’t allow logical indexing.Another thing not permitted in gfor/gend loops isusing the loop iterator in colon expressions, which isa popular construct for many MATLAB users. Again,there are ways around this that aren’t too demanding,the most straightforward of which is pre-calculate anyoffsets, e.g.:idx gsingle(0:350); rc gnan(1,datacols); rp gnan(1,datacols); ra gnan(1,datacols);gfor kdx 1:(rows(xdata)-350)[ tmprc, tmprp] gcadf(ydata(kdx idx,:),xdata(kdx idx,:),0,1,2); rc(1,kdx) tmprc; rp(1,kdx) tmprp;gendFurthermore, if you create the offset vector (idx gsingle(0:350);)as a Jacket data type such asgsingle, this “marks” it for the GPU which delivers afurther speed boost.sOn that point, the difference Jacket made to our codeperformance was pretty dramatic. Using one GPUon our single Jacket gfor/gend loop cut the totalfunction execution time from the 22 minutes achievedby MATLAB’s PCT “parfor” loops, to just over fiveminutes. Impressive, but then we remembered thatJacket now no longer depends on MATLAB’s PCTin order to run calculations across multiple GPUs.The temptation to see whether we could furtherimprove things by using all three of the GPUs in ourworkstation became irresistible.

Mashup!of least resistance that appeals to thereview team.MATLAB IB-MATLAB IBWhen we reviewed IB-MATLABin Q3 2011, one of the things weremarked upon was its stability. Fromconversations with developer YairAltman, it became clear that therewas quite a lot going on under thehood in IB-MATLAB to managemessage flow more efficiently andprevent lockups or crashes.Wrecking Crew mashing upbutcheryHowever, after reading the online docs and arguing forhalf an hour we couldn’t figure out the right syntax toaccomplish this, so posted a query on the AccelerEyesforum. Within less than eight hours we had theanswer from Pavan Yalamanchili, one of AccelerEyes’core developers (whose tag on the forum “If it is notbroken, you have not tried hard enough” has nowbeen adopted as the new Wrecking Crew missionstatement). After staring blankly at the sample codeprovided by Pavan for about an hour, we actually gotround to reading the rest of his post properly andfinally appreciated the massive significance of hisphrase: “multiple gpus can be run concurrently, even iftheir jobs are assigned serially”. In our simple serialminded way we hadn’t previously been able to figureout how GPU two could start work before GPU onehad finished (ditto for GPU three/two).Collective senior moment finally over, we were able torun our code across all 3 GPUs – completing in oneminute fifty-two seconds.It has to be said that we had to do a fair bit of hackingof the original Spatial Econometrics functions toproduce our own “Jacketised” versions that would runsatisfactorily. Including any sub-functions called, thistook us probably half a day in total, which given thespeed improvement and the opportunity for reusingthose functions, we felt was a good return on effortexpended.066 8 Automated Trader Q1 2012One thing that helps in this endeavour is that IBdoesn’t appear to transmit flat price ticks (trades at thesame price as the previous trade). We certainly didn’tsee any when we ran the following:load(‘dow stks.mat’);tic;for i 1:rows(stk) stk{i,1} IB 3}, ‘QuotesNumber’,inf,‘QuotesBufferSize’, 1000);endtoc;pause(10);tic;for i 1:rows(stk) stk{i,2} IB trade(‘action’,‘Query’,‘symbol’, stk{i,3},‘QuotesNumber’, -1);endtoc;The first section of code requests continuous streamingquotes (by using the MATLAB inf value as an input)for all 30 stocks in the Dow and specifies a quotesbuffer capable of holding 1000 ticks. After a tensecond pause, the second section of code accesses thoseticks (bids, asks, trades and timestamps) which havesWe also tried to do the same with the MATLABegcitest.m function but kept running into subfunctions that it calls – such as qr.m (orthogonaltriangular decomposition) – which Jacket doesn’t yetsupport. With sufficient diligence we could probablyhave found a way round these obstacles, but thealternative of recasting a few “if ” statements in theSpatial Econometrics functions was the sort of pathWe were therefore particularly keento take a look at the latest version ofIB-MATLAB as it now incorporatesstreaming quote functionality that was not availableat the time of our original review. In view of thepublished capacity of 50 messages per second of the“standard” IB API (the FIX version of the API has ahigher capacity) we were intrigued to see how IBMATLAB would deal with unreasonable users (suchas?) who tried to run streaming quotes on a largenumber of highly active issues.

Mashup!been stored in a MATLAB struct but by specifying‘QuotesNumber’, -1 does not interrupt theongoing collection of ticks. Using this mechanism, it isstraightforward to write ticks to disk, build time or tickbars or do pretty much anything else with the raw data.Although it was hardly what you’d describe as thecutting edge of high frequency, it didn’t take verylong to get the process going. The output below wasgenerated the MATLAB command prompt as a resultof running the code above. To register the initialrequests and subscribe for the 30 stocks via the IB APItook just under 10 seconds. Writing the buffered datato a cell array of structs was obviously a lot faster. DowStocksStreamQuoteTestconnecting to IB.Server Version:59TWS Time at connection:2012012517:29:11 GMT API.msg2] Market data farm[connection is OK:eurofarm {-1,2104} API.msg2] Market data farm[connection is OK:cashfarm {-1,2104} API.msg2] Market data farm[connection is OK:usfarm {-1,2104}Elapsed time is 9.967258 seconds.Elapsed time is 0.061849 seconds.An important point about IB-MATLAB is that it usesMATLAB’s Java interface and not COM/ActiveX.Apart from allowing it to run on both Windows andnon-Windows platforms, this has important benefitswhen it comes to processing data. If you have a functionrunning in MATLAB when IB’s TWS fires an eventvia a COM interface then MATLAB will not processthe event until after the function has completed, whichcan result in dropped ticks and subsequent calculationsbeing applied to the wrong tick. By contrast, whenusing the Java API, any fired event is automaticallycaught by Java in the background to ensure processingof the correct price tick.From a statarb or even just a general short sellingperspective one of the most useful aspects of thenew IB-MATLAB tick functionality is its ability toquery multiple other data fields via the IB API. IB068 8 Automated Trader Q1 2012MATLAB can request what IB terms “Generic TickTypes”, which includes data such as stock optionvolume, option open interest and historical/impliedvol by specifying the relevant “Integer ID Value” inany data request. However, from our perspective, themost useful Integer ID Value was 236 as this returnsa value that indicates whether a stock is shortable.Furthermore, the value also indicates how muchinventory IB has available for shorting. So (amongother things removed to save space) this: data IBtrade(‘action’,‘QUERY’, 36’).returnsdata reqId: 147771273.shortable: 3A shortable value of 3 (because it is greater than 2.5)indicates that IB has at least 1000 shares of inventoryavailable for a short sale. A value between 1.5 and2.5 would indicate a stock is available for short sale ifshares can be located, while a value between 0.5 and1.5 means the stock is not shortable. Granted, thisinformation is nowhere near as comprehensive as IB’sShort Stock Availability Tool, which provides far moregranular data on both shortable individual stocks anda portfolio uploaded as a file, but for smaller trades it’sstill extremely useful. The only downside is that wecould only get generic tick 236 to work for US stocks.In view of the various and ongoing regulatory changesregarding shorting in Europe, we’re obviously followingup with IB on this to double check whether this wasjust an error on our part or simply not available forEuropean stocks. Expect an update shortly.All told, we regarded the enhancements to IBMATLAB since we last reviewed it as significant. Theorder submission process was rock solid as before, butthe new capabilities really open up the possibilities –especially for trading that is analytically intensive butnot high frequency. We were able to deploy multiplemodels in real time to IB’s simulated (nope – theeditorial budget still doesn’t stretch to funding anaccount) trading platform without any difficulties orglitches.MATLAB Excel, CQG Excel and Excel Excel Up a MountainIt has to be said that this leg of the review project wasfrankly a bit of a luxury. Interactive Brokers’ TWS(see Figures 3a, 3b and 3c) provides pretty much every

SOFTWARE REVIEWpossible tool necessary to monitor trading activity.However, the Wrecking Crew were adamant that thepark keeper/trader would also want to have accessto the parameters of any error correction model wewere using, plus the ability to track the spread andfollowing trading signals in real time. Since noneof the statarb models we had cobbled together inMATLAB were remotely high frequency there wassome degree of realism to this. We therefore usedMATLAB to shunt error correction model updatesand other values both daily and every ten minutes intoExcel, while real time market data that could be usedin conjunction with these values was fed into Excel viaCQG’s RTD server.MATLAB ExcelWhen it came to moving data from MATLABinto CQG, we considered a couple of options.MATLAB has the xlswrite.m function as a quickand straightforward way to shunt data into Excel.However, while it is perfectly effective for small/simpleexports, it can become slow when writing to multipleworksheets as it has to open/close Excel every time itwrites to a separate sheet. By contrast, establishing aCOM/ActiveX connection to Excel allows for far moregranular control. One quick way to get an inkling ofjust how much control is to start the ActiveX server inMATLAB, with (for example):Figure 3aFigure 3bexcel actxserver (‘Excel.Application’);.then type:excel.invoke;at the MATLAB command prompt. This returns a listof more than 50 available methods, while typing:excel.get;.returns a list of nearly 200 available properties.Figure 3cThis was an astonishingly painless process. We were ableto do both daily and intraday updates of the models,write the parameters to Excel, run a few macros andclose Excel in a matter of seconds. Well, to be strictlyaccurate, it was sometimes more than a few secondswhen we ran up against the old problem we encounteredin our original MATLAB review nearly three years ago,which wasn’t actually a MATLAB issue at all. Whetheryou are using MATLAB’s xlswrite.m function (or forthat matter its xlsread.m or xlsinfo.m cousins) or yourQ1 2012 Automated Trader 8 069sApart from relatively mundane things that thexlswrite.m function can do anyway (such as write datato worksheet ranges) using a COM/ActiveX connectionto Excel allows you to do things such as run macrosfrom within MATLAB. We used this capability to autogenerate charts of some of the various models – forexample, Figure 4 shows the historic spread of a simplepairs model applied to two European oil stocks – as wellas to run an Excel AutoFilter so that the park keeper/trader would only see tradable (rather than all possible)instrument combinations or those in which a positionwas already open.

Mashup!MATLABwww.fa5t.net/rxwww.fa5t.net/rwThe underlying problem is thatother applications may have silentlyestablished connections to Excel(Google Desktop Search sometimesused to be a sinner here) and won’tlet go. Fortunately, it’s possible torun system-wide commands at theMATLAB command prompt or inMATLAB functions/scripts, so if youwant to terminate Excel with extremeprejudice:system(‘taskkill /F /IM EXCEL.EXE’);.seems to do the trick pretty reliably.AccelerEyes Jacketwww.fa5t.net/rzwww.fa5t.net/ryCQG .net/s2www.fa5t.net/s3Interactive Brokers APIwww.fa5t.net/s4070 8 Automated Trader Q1 2012Just for the hell of it, we did oneadditional test that wasn’t in ouroriginal game plan, which was to takedata received into MATLAB from IBvia IB-MATLAB and immediatelyretransmit it to Excel. We opted todo this on a five minute batch basis,using a custom MATLAB function tocompile the raw trade ticks into tick(as opposed to time) bars. Again, wewere fortunate in having no difficultyin doing this, but while automated,the process could undoubtedly havebeen slicker. As a result, we’re planningto run a review of KaiTrade’s genericK2 RTD Handler in our next issuethat will allow us to stream the quotesfrom IB to Excel in real time.CQG ExcelGetting real time data into our parkkeeper/trader’s instance of Excelwas similarly straightforward. OnceCQG’s Integrated Client applicationis started, its RTD server just works– period. OK, we could have donewith fewer double quote marks in theformulas making us cross y”,,,,”T”).but all told this was pretty painless.While Microsoft Real-Time DataComponents have been aroundfor nearly ten years and are wellestablished, we were still intriguedto see how far they could be pushed.Painful memories of how RTD’s DDEforebear used to keel over remarkablyeasily (or just drop data all over theplace if the going got tough) made uswonder what was practically possiblein terms of throughput. In the caseof CQG’s implementation, the shortanswer seems to be “quite a lot”. Forthe hell of it, we dumped RTD linksfor more than 3000 NASDAQ/NYSEstocks into an Excel spreadsheet andsat back. CQG’s Integrated Clientapplication started using rather morememory and CPU cycles but that wasabout all – no drama, loads of updates.Another hat tip at this point to CQG’sThom Hartle, who seems to be makingpushing RTD/Excel to the limit andbeyond his life’s work. Thom kindlyshared some of his handiwork with us,from which we plagiarised several ofour RTD worksheet formulas. (Figure5 illustrates what’s possible

position info from MATLAB (coming via IB-MATLAB from IB) and via CQG’s RTD server with real time and historical data. The extremist wing of the Wrecking Crew also wanted to add a manual trading interface to Excel on the premise that any trader monitoring automated mod