def logDayDetails(self): """ Write Information about the Current Trading Day to the Console/Log """ console().info("Today is {}.".format(self.today.strftime(DATE_FMT))) hours = self.contractDetails.tradingHours.split(";")[0].split(":")[1] console().info("Today's Trading Hours Are: {}".format(hours)) if self.normalDay: console().info("Today is a Valid Day for Trading") else: console().info( "Today is not a Valid Trading Day. Sleeping Until Tomorrow")
def getCurrentFuturesContract(contractDetails): """ Select the Most Current Symbol """ soonest = None for _, data in contractDetails.items(): expireString = data.summary.lastTradeDateOrContractMonth expireYear = int(expireString[:4]) expireMonth = int(expireString[4:6]) expireDay = int(expireString[6:8]) expireDate = datetime(year=expireYear, month=expireMonth, day=expireDay) if soonest is None or (expireDate < soonest[0]): # pylint: disable=unsubscriptable-object soonest = [expireDate, data] contract = soonest[1] console().info("Picked Current FUT Contract: {}".format( contract.summary.localSymbol)) return contract
def main(): logger.info("### running python job submitter ###") logger.console("logging to: '{}'".format(logger.log_file_path)) # get command line arguments args = _parse_runner_arguments() # load the auth, settings, jobs and pool from the JSON manifest file auth_settings, template_settings, jobs, pool = _load_job_manifest(args) auth_provider = AuthenticationProvider(auth_settings) # load job and parameters templates job_template = file_utils.load_json_template( template_settings.job_template_file_path) job_parameters = file_utils.load_json_template( template_settings.job_parameter_file_path) job_config = JobConfiguration( batch_client=auth_provider.create_batch_client(), storage_client=auth_provider.create_storage_client(), extensions_client=auth_provider.create_batch_extensions_client(), job_template=job_template, job_parameters=job_parameters, pool_name=pool, storage_acc_url=auth_settings.storage_acc_url, template_settings=template_settings) if args.operation.lower() == "test": logger.info( "### operating in 'TEST' mode, no jobs will be submitted ###") for job in jobs: _test_job(job, job_config) elif args.operation.lower() == "run": logger.info("### operating in 'RUN' mode ###") _run_manifest(jobs, job_config) else: logger.warn("unrecognised run operation: '{0}', exiting".format( args.operation)) logger.debug("exiting application normally")
def cancelUnusedBracket(client, state, openOrders): """ Remove Other Bracket if it Exists """ highBracket, lowBracket = state["highBracket"], state["lowBracket"] if highBracket is None and lowBracket is None: return state highOrderId = highBracket.entryOrder.orderId lowOrderId = lowBracket.entryOrder.orderId if highOrderId not in openOrders.keys(): client.cancelOrder(lowOrderId) console().info("Cancelling the Lower Bracket") state["lowBracket"] = None state["highBracket"] = None elif lowOrderId not in openOrders.keys(): client.cancelOrder(highOrderId) console().info("Cancelling The Upper Bracket") state["lowBracket"] = None state["highBracket"] = None return state
def isNormalTradingDay(self): """ Check if Date has Normal Trading Hours. Needs config var""" def ignoreDate(): """ Ignore Bad Days of Malformed Date Strings """ ignore = input("Continue Anyway? (y/n) > ") return True if ignore.lower() == 'y' else False try: days = self.contractDetails.tradingHours.split(";") today = [ x for x in days if x.split(":")[0] == self.today.strftime("%Y%m%d") ] if not today: console().error("Missing Contract Market Hours for Today.") return ignoreDate() hours = today[0].split(":")[1] # Trading Hours Cross Mutliple Dates if hours != "CLOSED" and len(hours.split('-')[1]) == 8: hours = parseMultiDayHours(self.contractDetails.tradingHours) console().info("Today's Trading Hours Are: {}".format(hours)) if hours == "CLOSED" or hours != config.NORMAL_TRADING_HOURS: return ignoreDate() return True except (IndexError, AttributeError): console().warning("Unable to Calculate Trading Hours.") return ignoreDate()
def logDayDetails(self): """ Write Information about the Current Trading Day to the Console/Log """ console().info("Today is {}.".format(self.today.strftime(DATE_FMT))) if self.normalDay: console().info("Today is a Valid Day for Trading") else: console().info( "Today is not a Valid Trading Day. Sleeping Until Tomorrow")
def stopSubscription(self, reqId): """ Stop a Single Subscription and notify IBAPI """ try: name, stopFunc, stopArgs = self.data[reqId]["subscription"] console().info("Stopping Subscription: {}".format(name)) except KeyError: console().error("Failed to Stop Subscription: {}.".format(name)) console().error(self.data) return self.data.pop(reqId, None) stopFunc(*stopArgs)
def install_jenkins(ip, keyfile): """ Install Jenkins on an instance given it's ip address and key""" copy_install_script_cmd = "scp -i " + keyfile + " ./install-jenkins.sh ubuntu@" + ip + ":." logger.console("Copying installation script to server") run_command(copy_install_script_cmd) grant_permission_cmd = "ssh -t -i " + keyfile + " ubuntu@" + ip + " 'chmod +x ./install-jenkins.sh'" logger.console("Granting execute permissions to installtion script") run_command(grant_permission_cmd) run_script_cmd = "ssh -t -i " + keyfile + " ubuntu@" + ip + " 'sudo ./install-jenkins.sh'" logger.console("Installing Jenkins") run_command(run_script_cmd)
def main(): """ Setup Logging and Intialize Algo Trader """ setupLogger() console().info("Started Second30 Trader v{}".format(config.VERSION)) app = Second30Trader() try: console().info("Connecting to TWS API at {}:{}. Client ID: {}".format( config.HOST, config.PORT, config.CLIENTID)) app.connect(config.HOST, config.PORT, clientId=config.CLIENTID) if app.isConnected(): console().info("Connection Successful. Server Version: {}".format( app.serverVersion())) app.run() else: console().info("Connection Failed") except: raise
def create_security_group(ec2): """Checks if the security group (httpssh) exists given a connection. Creates it if it does not exist. """ logger.console('Checking for security group: httpssh') groups = ec2.meta.client.describe_security_groups( Filters=[{ 'Name': 'group-name', 'Values': ['httpssh'] }])['SecurityGroups'] if len(groups) == 0: security_group = ec2.create_security_group( GroupName='httpssh', Description='Only HTTP and SSH') ip_ranges = [{'CidrIp': '0.0.0.0/0'}] ip_v6_ranges = [{'CidrIpv6': '::/0'}] permissions = [{ 'IpProtocol': 'TCP', 'FromPort': 80, 'ToPort': 80, 'IpRanges': ip_ranges, 'Ipv6Ranges': ip_v6_ranges }, { 'IpProtocol': 'TCP', 'FromPort': 443, 'ToPort': 443, 'IpRanges': ip_ranges, 'Ipv6Ranges': ip_v6_ranges }, { 'IpProtocol': 'TCP', 'FromPort': 22, 'ToPort': 22, 'IpRanges': ip_ranges, 'Ipv6Ranges': ip_v6_ranges }] security_group.authorize_ingress(IpPermissions=permissions) logger.console('Created security group: httpssh') else: logger.console('Found Security Group: httpssh')
def run(self): client = self.client console().info("Staring Second30 App Logic...") console().info("Setting Market Data Type : {}".format(config.DATATYPE)) client.reqMarketDataType(MARKET_DATA_TYPES[config.DATATYPE]) quantity = config.NUM_CONTRACTS if config.ENABLE_MANAGED: xml = requests.getAdvisorConfig(client) quantity = parseAdvisorConfig(xml) if not quantity: console().error("Failed to Parse Advisor Profiles") client.interruptHandler() console().info( "Set Advisor Total Quantity to : {}".format(quantity)) client.reqOpenOrders() getContractDetails(client) waitForProp(self, "future") today = TradingDay(self.future) state = getNewState() #Already After 10. Check if Still Valid if today.isMarketOpen() and today.is30AfterOpen(): state = checkMissedExecution(client, self.future, today.normalDay, state) while True: sleep(.05) # Reduce Processor Load. updateFuture(client, self.future) newDay = updateToday(today) if newDay != today: state = getNewState() today = newDay #Sleep on Non-Trading Days if not today.normalDay: continue #Wait for Market Open while not today.isMarketOpen(): continue #Wait for 30 after Open while not today.is30AfterOpen(): continue #Cancel Unused Bracket if the Other Fired if state["executedToday"]: state = cancelUnusedBracket(client, state, self.account.openOrders) continue #Pull HighLow if not state["highLow"]: console().info("Getting High/Low Data For First 30.") state["highLow"] = requests.getFirst30HighLow( client, self.future) high, low = state["highLow"]["high"], state["highLow"]["low"] #pylint: disable=unsubscriptable-object #Check HiLo Spread spread = float("{:.4f}".format( (float(high) - float(low)) / float(low))) if spread > config.HIGH_LOW_SPREAD_RATIO: today.normalDay = False console().info( "Spread Ratio: {:.4f} above threshold: {}. Invalid Day". format(spread, config.HIGH_LOW_SPREAD_RATIO)) continue else: console().info( "Spread Ratio: {:.4f} below threshold: {}. Valid Day". format(spread, config.HIGH_LOW_SPREAD_RATIO)) #Calculate Stop spreadDiff = round( float("{:.2f}".format( (float(high) - float(low)) / 2.0)) * 4) / 4 stop = spreadDiff if spreadDiff > config.STOP_SPREAD else config.STOP_SPREAD console().info("Calculated Stop Spread: ${}".format(stop)) #Submit Orders for the Day contract = self.future.contract state["highBracket"] = BracketOrder(client, contract, quantity, "BUY", self.account, high, stop) state["lowBracket"] = BracketOrder(client, contract, quantity, "SELL", self.account, low, stop) state["executedToday"] = True
def historicalDataEnd(self, reqId, start, end): super().historicalDataEnd(reqId, start, end) console().info("Got CCI Historical Data") self.client.finishRequest(reqId)
def stopAllSubscriptions(self): """ Stop all Current Subscriptions and notify IBAPI """ console().info("Stopping All Active Subscriptions...") subs = [x for x, keys in self.data.items() if "subscription" in keys] for sub in subs: self.stopSubscription(sub)
def receiveFA(self, dataType, profile): console().info("Got the Advisor Profile Data") reqId = self.client.getRequestID("ADVISOR CONFIG") self.client.pushRequestData(reqId, {"xml": profile}) self.client.finishRequest(reqId)
def __init__(self): self.nextRequestId = 100 self.data = {} console().info("Initialized The Request Manager")
def buildOrders(self, action, price, quantity): """ Create Bracket Order with Entry/Profit/Loss """ console().info("Creating a Bracket Order to {} {}".format( action, self.contract.localSymbol)) if action == "BUY": entryPrice = price + config.ENTRY_SPREAD profitPrice = entryPrice + config.PROFIT_SPREAD lossPrice = entryPrice - self.stopPrice bracketAction = "SELL" else: entryPrice = price - config.ENTRY_SPREAD profitPrice = entryPrice - config.PROFIT_SPREAD lossPrice = entryPrice + self.stopPrice bracketAction = "BUY" #Entry Order for High/Low Crossover entryOrder = Order() entryOrder.orderId = self.account.getOrderId() entryOrder.account = self.account.account entryOrder.action = action entryOrder.orderType = "STP" entryOrder.auxPrice = entryPrice entryOrder.lmtPrice = 0 if config.ENABLE_MANAGED: entryOrder.faProfile = config.ALLOCATION_PROFILE entryOrder.totalQuantity = quantity entryOrder.transmit = False #Profit Limit profitOrder = Order() profitOrder.orderId = self.account.getOrderId() profitOrder.action = bracketAction profitOrder.orderType = "LMT" profitOrder.totalQuantity = config.NUM_CONTRACTS profitOrder.lmtPrice = profitPrice profitOrder.auxPrice = 0 profitOrder.parentId = entryOrder.orderId if config.ENABLE_MANAGED: profitOrder.faProfile = config.ALLOCATION_PROFILE profitOrder.totalQuantity = quantity profitOrder.transmit = False #Loss Limit lossOrder = Order() lossOrder.orderId = self.account.getOrderId() lossOrder.action = bracketAction lossOrder.orderType = "STP" lossOrder.totalQuantity = config.NUM_CONTRACTS lossOrder.auxPrice = lossPrice lossOrder.lmtPrice = 0 lossOrder.parentId = entryOrder.orderId if config.ENABLE_MANAGED: lossOrder.faProfile = config.ALLOCATION_PROFILE lossOrder.totalQuantity = quantity lossOrder.transmit = True return [entryOrder, profitOrder, lossOrder]
def setAccount(self, accountString): """ Parse Comma Separated Account List from IB """ accounts = accountString.split(",") if len(accounts) > 1: console().error("Received More than One Account. Not Implemented.") self.account = accounts[0]
def apiMessage(msg): """ Print API Messages """ msg = msg.replace("\n", ". ") console().info("API: {}".format(msg))
def managedAccounts(self, accountsList): self.logic.account.setAccount(accountsList) console().info("Received Account: {}".format(self.logic.account)) subscribeAccountPositions(self.client)
def nextValidId(self, orderId): self.logic.account.setNextOrderId(orderId) console().info("Next Order ID: {}".format(orderId)) if not self.startedLogic: self.logic.start() self.startedLogic = True