Visual Chart
The integration with Visual Chart supports both:
Live Data feeding
Live Trading
Visual Chart is a complete trading solution:
Integrated Charting, data feed and brokering in a single platform
For more information visit:www.visualchart.com
Requirements
VisualChart 6
Windows - the one VisualChart is running on
comtypesfork:https://github.com/mementum/comtypesInstall it with:
pip installhttps://github.com/mementum/comtypes/archive/master.zipTheVisual Chart API is based onCOM.
The current
comtypesmain branch doesn’t support unpacking ofVT_ARRAYSofVT_RECORD. And this is used byVisual ChartPull Request #104 hasbeen submitted but not yet integrated. As soon as it is integrated, themain branch can be used.
pytz(optional but really recommended)To make sure each and every data is returned in the market time.
This is true for most markets but some are really an exception (
GlobalIndicesbeing a good example)Time Management insideVisual Chart and its relation with the deliveredtimes overCOM is complex and having
pytztends to simplify things.
Sample Code
The sources contain a full sample under:
samples/vctest/vctest.py
The sample cannot cover every possible use case but it tries to provide broadinsight and should highlight that there is no real difference when it comes touse the backtesting module or the live data module
One thing could be pin-pointed:
The sample waits for a
data.LIVEdata status notification before any trading activity takes place.This would probably is something to consider in any live strategy
VCStore - the store
The store is the keystone of the live data feed/trade support, providing alayer of adaptation between theCOM API and the needs of a data feedand a broker proxy.
Providesaccess to getting abroker instance with the method:
VCStore.getbroker(*args, **kwargs)
Provides access to getterdata feed instances
VCStore.getedata(*args, **kwargs)
In this case many of the
**kwargsare common to data feeds likedataname,fromdate,todate,sessionstart,sessionend,timeframe,compressionThe data may provide other params. Check the reference below.
TheVCStore will try to:
Automatically locateVisualChart in the system using theWindows Registry
If found, the installation directory will be scanned for theCOM DLLs to create theCOMtypelibs and be able to instantiate the appropriate objects
If not found, then an attempt will be made with known and hardcodedCLSIDs to do the same.
Note
Even if the DLLs can be found by scanning the filesystem,Visual Chartitself has to be running. backtrader won’t startVisual Chart
Other responsibilities of theVCStore:
- Keeping general track of the connectivity status ofVisual Chart to the server
VCData feeds
General
The data feed offered byVisual Chart has some interesting properties:
Resampling is done by the platform
Not in all cases:Seconds is not supported and has still to be done bybacktrader
As such and only when doing something with seconds would the end user needto do:
vcstore=bt.stores.VCStore()vcstore.getdata(dataname='015ES',timeframe=bt.TimeFrame.Ticks)cerebro.resampledata(data,timeframe=bt.TimeFrame.Seconds,compression=5)In all other cases it is enough with:
vcstore=bt.stores.VCStore()data=vcstore.getdata(dataname='015ES',timeframe=bt.TimeFrame.Minutes,compression=2)cerebro.addata(data)
The data will calculate atimeoffset internally by comparing the internalequipment clock and theticks delivered by the platform in order todeliver theautomatically resampled bars as early as possible if no new ticksare coming in.
Instantiating the data:
Pass the symbol seen on the top-left side ofVisualChart without spaces. For example:
- ES-Mini is displayed as
001 ES. Instantiate it as:
data=vcstore.getdata(dataname='001ES',...)- EuroStoxx 50 is displayed as
015 ES. Instantiate it as:
data=vcstore.getdata(dataname='015ES',...)- ES-Mini is displayed as
Note
backtrader will make an effort and clear out a whitespace located atthe fourth position if the name is directly pasted fromVisual Chart
Time management
The time management follow the general rules ofbacktrader
- Give the time inMarket time, to make sure the code is not dependent on DST transitions happening at different times and making local time not reliable for time comparisons.
This works for most markets inVisual Chart but some specific management isdone for some markets:
Datas in the exchange
096which is namedInternational Indices.These are theoretically reported to be in the timezone
Europe/Londonbut tests have revealed this seems to be partially true and some internalmanagement is in place to cover for it.
The use of realtimezones for time management can be enabled by passing theparameterusetimezones=True. This tries to usepytz if available. It isnot needed, as for most markets the internal time offsets provided byVisualChart allow for the seamless conversion to the market time.
In any case it would seem to be pointless to report the096.DJI inEurope/London time when it is actually located inUS/Eastern. Assuchbacktrader will report it in the later. In that case the use ofpytz is more than recommended.
Note
TheDow Jones Industrials index (not the global version) islocated at099I-DJI
Note
All this time management is pending a real test during a DSTtransition in which local and remote markets happend to be out ofsync with regards to DST.
List ofInternational Indices for which the outputtimezone is defined inVCDATA:
'096.FTSE': 'Europe/London','096.FTEU3': 'Europe/London','096.MIB30': 'Europe/Berlin','096.SSMI': 'Europe/Berlin','096.HSI': 'Asia/Hong_Kong','096.BVSP': 'America/Sao_Paulo','096.MERVAL': 'America/Argentina/Buenos_Aires','096.DJI': 'US/Eastern','096.IXIC': 'US/Eastern','096.NDX': 'US/Eastern',Small time problem
Passingfromdate ortodate with a giventime of day rather than thedefault00:00:00 seems to create a filter in theCOM API and bars for anydays will only be delivered after the given time.
As such:
Please pass onlyfull dates to
VCDataas in:data=vcstore.getdata(dataname='001ES',fromdate=datetime(2016,5,15))And not::
data = vcstore.getdata(dataname=‘001ES’, fromdate=datetime(2016, 5, 15, 8, 30))
Backfilling time lengths
If nofromdate is specified by the end user, the platform willautomatically try to backfill and the carry on with live data. The backfillingis timeframe dependent and is:
Ticks,MicroSeconds,Seconds:1 DayThe same for the 3 timeframes given thatSeconds andMicroSeconds arenot directly supported byVisual Chart and are done through resampling ofTicks
Minutes:2 DaysDays:1 yearWeeks:2 yearsMonths:5 yearsMonths:20 years
The defined backfilling periods are multiplied by the requestedcompression,that is: if thetimeframe isMinutes and thecompression is 5 the finalbackfilling period will be:2 days * 5 -> 10 days
Trading the data
Visual Chart offerscontinuous futures. No manual management is neededand the future of your choice can be tracked without interruption. This is anadvantage and presents a small challenge:
ES-Miniis001ES, but the actual trading asset (ex: Sep-2016) isESU16.
To overcome this and allow a strategy to track thecontinuous future andtrade on thereal asset the following can be specified during datainstantiation:
data=vcstore.getdata(dataname='001ES',tradename='ESU16')Trades will happen onESU16, but the data feed will be frm001ES (thedata is the same 3 months long)
Other parameters
qcheck(default:0.5seconds) controls the frequency to wake up to talk to the internal resampler/replayer to avoid late delivery of bars.The following logic will be applied to used this parameter:
If internalresampling/replaying is detected, the value will be used as it is.
If no internalresampling/replaying is detected, the data feed will not wake up, because there is nothing to report to.
The data feed will still wake up to check theVisual Chart built-inresampler, but this is automatically controlled.
Data Notifications
The data feed will report the current status via one or more of the following(check theCerebro andStrategy reference)
Cerebro.notify_data(if overriden)nA callback addded with
Cerebro.adddatacbStrategy.notify_data(if overriden)
An example inside thestrategy:
classVCStrategy(bt.Strategy):defnotify_data(self,data,status,*args,**kwargs):ifstatus==data.LIVE:# the data has switched to live data# do somethingpassThe following notifications will be sent following changes in the system:
CONNECTEDSent on successful initial connection
DISCONNECTEDIn this case retrieving the data is no longer possible and the data willindicate the system nothing can be done. Possible conditions:
Wrong contract specified
Interruption during historical download
Number of reconnection attempts to TWS exceeded
CONNBROKENConnectivity has been lost to either TWS or to the data farms. The datafeed will try (via the store) to reconnect and backfill, when needed, andresume operations
NOTSUBSCRIBEDContract and connection are ok, but the data cannot be retrieved due tolack of permissions.
The data will indicate to the system that it cannot retrieve the data
DELAYEDSignaled to indicate that ahistorical/backfilling operation are inprogress and the data being processed by the strategy is not real-time data
LIVESignaled to indicate that the data to be processed from this point onwardsby thestrategy is real-time data
Developers ofstrategies should consider which actions to undertake in caseslike when a disconnection takes place or when receivingdelayed data.
VCBroker - Trading Live
Using the broker
To use theVCBroker, the standard broker simulation instance created bycerebro has to be replaced.
Using theStore model (preferred):
importbacktraderasbtcerebro=bt.Cerebro()vcstore=bt.stores.VCStore()cerebro.broker=vcstore.getbroker()# or cerebro.setbroker(...)Broker Parameters
Be it directly or overgetbroker theVCBroker broker supports noparameters. This is because the broker is just a proxy to the a realBroker. And what the real broker gives, shall not be taken away.
Restrictions
Position
Visual Chart reportsopen positions. This could be used most of the timeto control the actual position, but a final event indicating aPosition hasbeen closed is missing.
That makes it compulsory forbacktrader to keep full accounting of thePosition and separate from any previous existing position in your account
Commission
TheCOM trading interface doesn’t report commissions. There is no chance forbacktrader to make and educated guess, unless:
- Thebroker is instantiated with aCommission instance indicating which commissions do actually take place.
Trading with it
Account
Visual Chart supports several accounts at the same time in one broker. Thechosen account can be controlled with the parameter:
account(default:None)VisualChart supports several accounts simultaneously on the broker. Ifthe default
Noneis in place the 1st account in the ComTraderAccountscollection will be used.If an account name is provided, the
Accountscollection will bechecked and used if present
Opperations
There is no change with regards to the standar usage. Just use the methodsavailable in the strategy (see theStrategy reference for a fullexplanation)
buysellclosecancel
Order objects returned
- Standardbacktrader
Orderobjects
Order Execution Types
Visual Chart supports the minimum order execution types needed bybacktrader and as such, anyhing which is backtested can go live.
As such the order execution types are limited to the ones available in thebroker simulation:
Order.MarketOrder.CloseOrder.LimitOrder.Stop(when theStop is triggered aMarket order follows)Order.StopLimit(when theStop is triggered aLimit order follows)
Order Validity
The same validity notion available during backtesting (withvalid tobuy andsell) is available and with the same meaning. As such, thevalid parameter is translated as follows forVisual Chart Orders for thefollowing values:
Nonetranslates toGood Til CancelledBecause no validity has been specified it is understood that the order mustbe valid until cancelled
datetime/datetranslates toGood Til DateNote
Beware:Visual Chart does only support “full dates” and thetime part is discarded.
timedelta(x)translates toGood Til Date (heretimedelta(x) != timedelta())Note
Beware:Visual Chart does only supportfull dates and thetime part is discarded.
This is interpreted as a signal to have an order be valid from
now+timedelta(x)timedelta() or 0translates toSessionA value has been passed (instead of
None) but isNull and isinterpreted as an order valid for the currentday (session)
Notifications
The standardOrder status will be notified to astrategy over the methodnotify_order (if overridden)
Submitted- the order has been sent to TWSAccepted- the order has been placedRejected- order placement failed or was cancelled by the system during its lifetimePartial- a partial execution has taken placeCompleted- the order has been fully executedCanceled(orCancelled)Expired- Not reported as of yet. An heuristic would be needed to distinguish this status fromCancelled
Reference
VCStore
class backtrader.stores.VCStore()
Singleton class wrapping an ibpy ibConnection instance.
The parameters can also be specified in the classes which use this store,likeVCData andVCBroker
VCBroker
class backtrader.brokers.VCBroker(**kwargs)
Broker implementation for VisualChart.
This class maps the orders/positions from VisualChart to theinternal API ofbacktrader.
Params:
account(default: None)VisualChart supports several accounts simultaneously on the broker. Ifthe default
Noneis in place the 1st account in the ComTraderAccountscollection will be used.If an account name is provided, the
Accountscollection will bechecked and used if presentcommission(default: None)An object will be autogenerated if no commission-scheme is passed asparameter
See the notes below for further explanations
Notes
- Position
VisualChart reports “OpenPositions” updates through the ComTrader interface but only when the position has a “size”. An update to indicate a position has moved to ZERO is reported by the absence of such position. This forces to keep accounting of the positions by looking at the execution events, just like the simulation broker does
- Commission
The ComTrader interface of VisualChart does not report commissions and as such the auto-generated CommissionInfo object cannot use non-existent commissions to properly account for them. In order to support commissions acommission parameter has to be passed with the appropriate commission schemes.
The documentation on Commission Schemes details how to do this
- Expiration Timing
The ComTrader interface (or is it the comtypes module?) discardstime information fromdatetime objects and expiration dates are always full dates.
- Expiration Reporting
At the moment no heuristic is in place to determine when a cancelled order has been cancelled due to expiration. And therefore expired orders are reported as cancelled.
VCData
class backtrader.feeds.VCData(**kwargs)
VisualChart Data Feed.
Params:
qcheck(default:0.5) Default timeout for waking up to let a resampler/replayer that the current bar can be check for due deliveryThe value is only used if a resampling/replaying filter has beeninserted in the data
historical(default:False) If notodateparameter is supplied (defined in the base class), this will force a historical only download if set toTrueIf
todateis supplied the same effect is achievedmilliseconds(default:True) The bars constructed byVisual Chart have this aspect: HH:MM:59.999000If this parameter is
Truea millisecond will be added to this timeto make it look like: HH::MM + 1:00.000000tradename(default:None) Continous futures cannot be traded but are ideal for data tracking. If this parameter is supplied it will be the name of the current future which will be the trading asset. Example:001ES -> ES-Mini continuous supplied as
datanameESU16 -> ES-Mini 2016-09. If this is supplied in
tradenameit will be the trading asset.
usetimezones(default:True) For most markets the time offset information provided byVisual Chart allows for datetime to be converted to market time (backtrader choice for representation)Some markets are special (
096) and need special internal coverageand timezone support to display in the user expected market time.If this parameter is set to
Trueimportingpytzwill beattempted to use timezones (default)Disabling it will remove timezone usage (may help if the load isexcesive)