def Close(self): Trace("Logoff from GW") self.eventGatewayIsDown.clear() self.celEnvironment.cqgCEL.GWLogoff() AssertMessage(self.eventGatewayIsDown.wait(GATEWAYDOWN_TIMEOUT), "GW disconnection timeout!") Trace("Done!")
def OnOrderChanged(self, changeType, cqgOrder, oldProperties, cqgFill, cqgError): if cqgError is not None: error = win32com.client.Dispatch(cqgError) Trace("OnOrderChanged error: Code: {} Description: {}".format( error.Code, error.Description)) return dispatchedOrder = win32com.client.Dispatch(cqgOrder) properties = win32com.client.Dispatch(dispatchedOrder.Properties) gwStatus = properties(constants.opGWStatus) quantity = properties(constants.opQuantity) instrument = properties(constants.opInstrumentName) speculationType = properties(constants.opSpeculationType) limitPrice = properties(constants.opLimitPrice) Trace( "OnOrderChanged: change type: {}; GW status: {}; Quantity: {}; Instrument: {}; Price: {}; Speculation " "type: {}".format(changeType, gwStatus, quantity, instrument, limitPrice, speculationType)) if changeType != constants.ctChanged: return if gwStatus.Value == constants.osInOrderBook: Trace("Order is placed!") self.eventOrderPlaced.set()
def Start(self, param_dict): self.symbols = param_dict['symbols'] self.handle_new_bars = HandleData(param_dict) for symbol in self.symbols: Trace("Create timed bars request") request = win32com.client.Dispatch( self.celEnvironment.cqgCEL.CreateTimedBarsRequest()) request.Symbol = symbol request.RangeStart = 0 request.RangeEnd = param_dict['hist_bars_returned'] request.IntradayPeriod = param_dict['intraday_period'] request.Continuation = 4 if symbol in param_dict[ 'continuation'] else 3 request.UpdatesEnabled = True request.EqualizeCloses = True request.SessionsFilter = 31 Trace("Starting the request...") bars = self.celEnvironment.cqgCEL.RequestTimedBars(request) self.id_dict[bars.Id] = symbol self.eventDone.wait(5) Trace("Done!")
def OnGWConnectionStatusChanged(self, connectionStatus): if connectionStatus == constants.csConnectionUp: Trace("GW connection is UP!") self.eventGatewayIsUp.set() if connectionStatus == constants.csConnectionDown: Trace("GW connection is DOWN!") self.eventGatewayIsDown.set()
def OnOrderChanged(self, changeType, cqgOrder, oldProperties, cqgFill, cqgError): if cqgError is not None: error = win32com.client.Dispatch(cqgError) Trace("OnOrderChanged error: Code: {} Description: {}".format( error.Code, error.Description)) return dispatchedOrder = win32com.client.Dispatch(cqgOrder) properties = win32com.client.Dispatch(dispatchedOrder.Properties) gwStatus = properties(constants.opGWStatus) quantity = properties(constants.opQuantity) instrument = properties(constants.opInstrumentName) mifidId = properties(constants.opMiFIDAlgorithmID) isManual = properties(constants.opManual) Trace( "OnOrderChanged: change type: {}; GW status: {}; Quantity: {}; Instrument: {}; MiFID Algo ID: {}; Is " "manual: {}".format(changeType, gwStatus, quantity, instrument, mifidId, isManual)) if changeType != constants.ctChanged: return if gwStatus.Value == constants.osInOrderBook: Trace("Order is placed!") self.eventOrderPlaced.set()
def OnManualFillUpdateResolved(self, cqgManualFillRequest, cqgError): if cqgError is not None: error = win32com.client.Dispatch(cqgError) Trace("OnManualFillUpdateResolved error: Code: {} Description: {}". format(error.Code, error.Description)) return Trace("Manual fill is added!") self.eventManualFillUpdateResolved.set()
def OnConstantVolumeBarsResolved(self, cqgConstantVolumeBars, cqgError): if cqgError is not None: error = win32com.client.Dispatch(cqgError) Trace("OnConstantVolumeBarsResolved: Code: {} Description: {}".format(error.Code, error.Description)) self.eventDone.set() else: bars = win32com.client.Dispatch(cqgConstantVolumeBars) Trace("OnConstantVolumeBarsResolved: Bars count: {} Bars:".format(bars.Count)) for i in range(0, bars.Count): self.dumpBar(win32com.client.Dispatch(bars.Item(i)), i)
def TraceBars(self, cqgRenkoBars, index, methodName): renkoBars = win32com.client.Dispatch(cqgRenkoBars) Trace("{}: Bars count: {} index {}".format(methodName, renkoBars.Count, index)) for renkoBar in renkoBars: Trace( " Bar: Timestamp {} RenkoHigh {} RenkoLow {} RenkoUp {} Open {} High {} Low {} Close {}" .format(renkoBar.Timestamp, renkoBar.RenkoHigh, renkoBar.RenkoLow, renkoBar.RenkoUp, renkoBar.Open, renkoBar.High, renkoBar.Low, renkoBar.Close))
def OnInstrumentDOMChanged(self, cqgInstrument, cqgPrevAsks, cqgPrevBids): instrument = win32com.client.Dispatch(cqgInstrument) for ask in instrument.DOMAsks: if ask.IsValid: Trace("{} Price: {} Volume {}".format("ASK", ask.Price, ask.Volume)) for bid in instrument.DOMBids: if bid.IsValid: Trace(" {} Price: {} Volume {}".format( "BID", bid.Price, bid.Volume))
def OnInstrumentChanged(self, cqgInstrument, cqgQuotes, cqgInstrumentProperties): instrument = win32com.client.Dispatch(cqgInstrument) quotes = win32com.client.Dispatch(cqgQuotes) Trace("New quotes for {}".format(instrument.FullName)) for quote in quotes: if (quote.IsValid): Trace(" Type: {} Price: {} Volume: {} Time: {}".format( QuoteType2String(quote.Type), quote.Price, quote.Volume, quote.Timestamp))
def OnInstrumentResolved(self, symbol, instrument, cqgError): if cqgError: dispatchedCQGError = win32com.client.Dispatch(cqgError) Trace("OnInstrumentResolved error: Error code: {} Description: {}".format(dispatchedCQGError.Code, dispatchedCQGError.Description)) return self.instrument = instrument Trace("Instrument {} is resolved!".format(symbol)) self.eventInstrumentIsReady.set()
def OnTicksAdded(self, cqgTicks, addedTicksCount): dispatchedCQGTicks = win32com.client.Dispatch(cqgTicks) Trace("OnTicksAdded: Ticks added count: {}".format(addedTicksCount)) Trace("OnTicksAdded: Total ticks count: {}".format( dispatchedCQGTicks.Count)) for i in range(dispatchedCQGTicks.Count - addedTicksCount, dispatchedCQGTicks.Count): tick = dispatchedCQGTicks.Item(i) Trace("OnTicksAdded: Timestamp {} Volume {} Price {} PriceType {}". format(tick.Timestamp, tick.Volume, tick.Price, tick.PriceType))
def TraceBars(self, cqgRangeBars, methodName): rangeBars = win32com.client.Dispatch(cqgRangeBars) Trace("{}: Bars count: {}".format(methodName, rangeBars.Count)) for rangeBar in rangeBars: Trace( " Bar: Timestamp {} Open {} High {} Low {} Close {} Mid {} HLC3 {} Avg {} Range {} ActualVolume {} " "TickVolume {}".format(rangeBar.Timestamp, rangeBar.Open, rangeBar.High, rangeBar.Low, rangeBar.Close, rangeBar.Mid, rangeBar.HLC3, rangeBar.Avg, rangeBar.Range, rangeBar.ActualVolume, rangeBar.TickVolume))
def OnTicksResolved(self, cqgTicks, cqgError): if cqgError is not None: error = win32com.client.Dispatch(cqgError) Trace("OnTicksResolved: Code: {} Description: {}".format( error.Code, error.Description)) self.eventDone.set() else: ticks = win32com.client.Dispatch(cqgTicks) Trace("OnTicksResolved: Ticks count: {}".format(ticks.Count)) for tick in ticks: Trace(" Timestamp {} Volume {} Price {} PriceType {}".format( tick.Timestamp, tick.Volume, tick.Price, tick.PriceType))
def OnPointAndFigureBarsResolved(self, cqgPointAndFigureBars, cqgError): if (cqgError is not None): dispatchedCQGError = win32com.client.Dispatch(cqgError) Trace("OnPointAndFigureBarsResolved: Code: {} Description: {}". format(dispatchedCQGError.Code, dispatchedCQGError.Description)) self.eventDone.set() else: bars = win32com.client.Dispatch(cqgPointAndFigureBars) Trace("OnPointAndFigureBarsResolved: Bars count: {} Bars:".format( bars.Count)) for i in range(0, bars.Count): self.dumpBar(win32com.client.Dispatch(bars.Item(i)), i)
def OnStrategyDefinitionProgress(self, cqgDefinition, cqgError): if cqgError is not None: error = win32com.client.Dispatch(cqgError) Trace( "OnStrategyDefinitionProgress error: Code: {} Description: {}". format(error.Code, error.Description)) return dispatchedDefinition = win32com.client.Dispatch(cqgDefinition) Trace( "OnStrategyDefinitionProgress: requested symbol: {} GW symbol: {} status: {}" .format(dispatchedDefinition.RequestString, dispatchedDefinition.Symbol, dispatchedDefinition.Status)) if (dispatchedDefinition.Status == constants.srsSuccess): self.eventUDSIsReady.set()
def OnInstrumentResolved(self, symbol, cqgInstrument, cqgError): if cqgError is not None: dispatchedCQGError = win32com.client.Dispatch(cqgError) Trace("OnInstrumentResolved error: Error code: {} Description: {}". format(dispatchedCQGError.Code, dispatchedCQGError.Description)) self.eventDone.set() return instrument = win32com.client.Dispatch(cqgInstrument) Trace( "OnInstrumentResolved: Symbol: {} Instrument full name: {}".format( symbol, instrument.FullName)) instrument.DataSubscriptionLevel = win32com.client.constants.dsQuotesAndBBA Trace("OnInstrumentResolved: DataSubscriptionLevel is changed")
def createOrder(self, quantity, price): Trace("Creating a default execution pattern for limit orders...") executionPattern = win32com.client.Dispatch( self.celEnvironment.cqgCEL.CreateExecutionPattern( self.dispatchedStrategy, constants.otLimit)) Trace("Creating a strategy order...") order = win32com.client.Dispatch( self.celEnvironment.cqgCEL.CreateStrategyOrder( constants.otLimit, self.dispatchedStrategy, self.account, None, quantity, constants.osdUndefined, price)) Trace("Set an execution pattern order property...") properties = win32com.client.Dispatch(order.Properties) execPatternProperty = properties(constants.opExecutionPattern) execPatternProperty.Value = executionPattern.PatternString return order
def Start(self): request = win32com.client.Dispatch( self.celEnvironment.cqgCEL.CreateTicksRequest()) request.Symbol = SYMBOL request.Type = constants.trtCurrentNotify request.TickFilter = constants.tfAll request.SessionsFilter = 31 request.Limit = 10 Trace("Limit: {}".format(request.Limit)) self.ticks = self.celEnvironment.cqgCEL.RequestTicks(request) self.eventDone.wait(20) Trace("Done!")
def Start(self): Trace("Connecting to GW ({})".format(LOGIN)) self.celEnvironment.cqgCEL.GWLogon(LOGIN, PASSWORD) Trace("Waiting for GW connection...") AssertMessage(self.eventGatewayIsUp.wait(TIMEOUT), "GW connection timeout!") input("press Enter to Logoff..") Trace("Logoff from GW") self.eventGatewayIsDown.clear() self.celEnvironment.cqgCEL.GWLogoff() AssertMessage(self.eventGatewayIsDown.wait(TIMEOUT), "GW disconnection timeout!") Trace("Done!")
def dumpBar(self, bar, index): Trace( " Bar index: {} Timestamp {} Open {} High {} Low {} Close {} " "ActualVolume {} CommodityVolume {} ContractVolume {} TickVolume {}" .format(index, bar.Timestamp, bar.Open, bar.High, bar.Low, bar.Close, bar.ActualVolume, bar.CommodityVolume, bar.ContractVolume, bar.TickVolume))
def Start(self): for i in range(1, 4): symbol = "CLE?{}".format(i) Trace("Request realtime market data for {}".format(symbol)) self.celEnvironment.cqgCEL.NewInstrument(symbol) self.eventDone.wait(100)
def OnInstrumentResolved(self, symbol, cqgInstrument, cqgError): if cqgError is not None: dispatchedCQGError = win32com.client.Dispatch(cqgError) Trace("OnInstrumentResolved error: Error code: {} Description: {}". format(dispatchedCQGError.Code, dispatchedCQGError.Description)) self.eventDone.set() return instrument = win32com.client.Dispatch(cqgInstrument) Trace("OnInstrumentResolved: Symbol: {}".format(symbol)) properties = win32com.client.Dispatch(instrument.Properties) for property in properties: Trace(" Property name: {} Value: {}".format( property.Name, property.Value)) self.eventDone.set()
def CustomAPIConfiguration(APIConfiguration): Trace( "Set UTC time zone. All time values passed to (received from) CQG API should correspond to this setting. " ) APIConfiguration.TimeZoneCode = constants.tzUTC # If you do not want to see positions change on each price change then comment the row below APIConfiguration.FireEventOnChangedPrices = True
def OnTimedBarsRemoved(self, cqgTimedBars, index): bars = win32com.client.Dispatch(cqgTimedBars) Trace( "OnTimedBarsRemoved: Bars count: {} : Removed bar index {}".format( bars.Count, index)) for i in range(0, bars.Count): self.dumpBar(win32com.client.Dispatch(bars.Item(i)), i)
def OnRangeBarsResolved(self, cqgRangeBars, cqgError): if (cqgError is not None): dispatchedCQGError = win32com.client.Dispatch(cqgError) Trace("OnRangeBarsResolved: Code: {} Description: {}".format( dispatchedCQGError.Code, dispatchedCQGError.Description)) self.eventDone.set() else: self.TraceBars(cqgRangeBars, "OnRangeBarsResolved")
def Open(self): Trace("Connecting to GW") self.celEnvironment.cqgCEL.GWLogon(self.username, self.password) Trace("Waiting for GW connection...") AssertMessage(self.eventGatewayIsUp.wait(GATEWAYUP_TIMEOUT), "GW connection timeout!") self.celEnvironment.cqgCEL.AccountSubscriptionLevel = constants.aslAccountUpdatesAndOrders Trace("Waiting for accounts coming...") AssertMessage(self.eventAccountIsReady.wait(ACCOUNT_LOGIN_TIMEOUT), "Accounts coming timeout!") Trace("Select the first account") accounts = win32com.client.Dispatch( self.celEnvironment.cqgCEL.Accounts) self.account = win32com.client.Dispatch(accounts.ItemByIndex(0)) return self.account
def Start(self): Trace("{} instrument requesting...".format(self.symbol)) self.celEnvironment.cqgCEL.NewInstrument(self.symbol) Trace("{} instrument waiting...".format(self.symbol)) AssertMessage(self.eventInstrumentIsReady.wait(INSTRUMENT_SETUP_TIMEOUT), f"{self.symbol} Instrument resolution timeout!") dispatchedInstrument = win32com.client.Dispatch(self.instrument) if self.tradeTrigger == 1: bestTrade = dispatchedInstrument.Ask elif self.tradeTrigger == -1: bestTrade = dispatchedInstrument.Bid AssertMessage(bestTrade.IsValid, f"Error! Can't set {self.symbol}'s order price due to invalid BBA") Trace("{}'s best price is {}".format(self.symbol, bestTrade.Price)) if self.tradeTrigger != 0 and self.SignalOperationCalc(bestTrade.Price, self.signalDirection): return True, bestTrade.Price return False, bestTrade.Price
def OnManualFillsResolved(self, cqgManualFills, cqgError): if cqgError is not None: error = win32com.client.Dispatch(cqgError) Trace( "OnManualFillsResolved error: Code: {} Description: {}".format( error.Code, error.Description)) return Trace("Manual fills are received!") manualFills = win32com.client.Dispatch(cqgManualFills) for manualFill in manualFills: Trace( "Manual fill: instrument: {} GW account id: {} trade id: {} note: {} display price: {}" .format(manualFill.InstrumentName, manualFill.GWAccountID, manualFill.TradeId, manualFill.Note, manualFill.DisplayPrice)) self.eventManualFillsResolved.set()
def Start(self): Trace("Create range bars request") request = win32com.client.Dispatch( self.celEnvironment.cqgCEL.CreateRangeBarsRequest()) request.Symbol = SYMBOL request.RangeStart = datetime.now(timezone.utc) - timedelta(hours=2) request.RangeEnd = datetime.now(timezone.utc) - timedelta(hours=1) request.RangeUnit = win32com.client.constants.ruTick request.Range = 5 request.SessionsFilter = 31 Trace("Request range bars ({} - {})".format(request.RangeStart, request.RangeEnd)) self.RangeBars = self.celEnvironment.cqgCEL.RequestRangeBars(request) Trace("Waiting results for 20 seconds...") self.eventDone.wait(20) Trace("Done!")