def checkAndUnderBid(itemhandler, goodprices): prices = goodprices #manage buyorder if itemhandler.buyorder is not None and itemhandler.buyorder.finished == False: highestBidder = prices[2] curPrice = prices[0] if (curPrice == -1): print("Warning, not adjusting item: " + api.getNameFromID(itemhandler.typeid) + " because there is no good price.") else: print("curprice of item called \"" + api.getNameFromID(itemhandler.typeid) + "\" is: " + str(curPrice)) if (curPrice > float(itemhandler.buyorder.price) and not highestBidder): if itemhandler.buyorder.canChange(): itemhandler.buyorder.hasbeenoverbid = False print("Adjusting buyorder!") newprice = round(curPrice + random.random() / 15 + 0.02, 2) print("Bidding for newprice: " + str(newprice)) changeOrder(itemhandler.buyorder, newprice) else: itemhandler.buyorder.hasbeenoverbid = True print("overbid, but we cant change order yet") #manage sellorders #this makes all of your sellorders have the same price if itemhandler.sellorderlist: curPrice = prices[1] targetnewprice = round(curPrice - random.random() / 15 - 0.02, 2) highestBidder = prices[3] if (curPrice == -1): print("Warning, not adjusting item: " + api.getNameFromID(itemhandler.typeid) + " because there is no good price.") else: if highestBidder: print("we are highestbidder, equalizing orders") targetnewprice = curPrice for sellorder in itemhandler.sellorderlist: if sellorder.finished == False: print("curprice of item called \"" + api.getNameFromID(itemhandler.typeid) + "\" is: " + str(curPrice)) if (curPrice < float(sellorder.price)): if sellorder.canChange(): sellorder.hasbeenoverbid = False print("Adjusting sellorder!") #this may type in the same price an order already has if we are highestbidder, but eve will just not change the order print("Bidding for newprice: " + str(targetnewprice)) changeOrder(sellorder, targetnewprice) else: sellorder.hasbeenoverbid = True print("overbid, but we cant change order yet")
def openItem(typeid): show() for idx, item in enumerate(itemlist): if api.getNameFromID(typeid) == item: print("found typeid: " + str(typeid) + " in quickbar at index: " + str(idx)) print("all items in quickbar:") print(itemlist) cm.clickPointPNG('imgs/regionalmarkettopleft.png', 35, 81 + idx * 20, cache=True) return print("couldn't find item in quickbar: " + api.getNameFromID(typeid))
def sellItem(itemhandler, goodprices): if (len(getOrderCache()) > 16): print( "will exceeded max orders, cancelling a leftoveritemhandler's cheapest sellorder" ) cancelOrder(getWorthlessLOIHSellorder()) return sellItem(itemhandler, goodprices) sellprice = goodprices[1] if (sellprice == -1): print("Warning, not selling item: " + api.getNameFromID(itemhandler.typeid) + " because there is no good price.") return sellprice = round(sellprice - random.random() / 7 - 0.01, 2) flag = sellitemininventory(itemhandler.typeid, sellprice) if (flag == 0): print("couldnt sell item from inventory, doesnt exist") return quantity = 0 if itemhandler.buyorder is None or itemhandler.buyorder.finished: #adjust the quantity if there are previous sellorders quantity = itemhandler.volume for sellorder in itemhandler.sellorderlist: quantity -= sellorder.volentered else: #we only get here once, because we check if sellorderlist has no #elements in the ifstatement in the selling part in itemhandler's handle() quantity = itemhandler.buyorder.volentered - itemhandler.buyorder.volremaining itemhandler.sellorderlist.append( cm.Order(itemhandler.typeid, -1, False, sellprice, quantity, quantity, cm.getEVETimestamp())) #this line sets the orderid from -1 to something else refreshAllOrders()
def buyItem(itemhandler, goodprices): if (len(getOrderCache()) > 16): print( "will exceeded max orders, cancelling a leftoveritemhandler's cheapest sellorder" ) cancelOrder(getWorthlessLOIHSellorder()) return buyItem(itemhandler, goodprices) quantity = itemhandler.volume buyprice = goodprices[0] if (buyprice == -1): print("Warning, not buying item: " + api.getNameFromID(itemhandler.typeid) + " because there is no good price.") return buyprice = round(buyprice + random.random() / 7 + 0.01, 2) print("itemhandler called: " + api.getNameFromID(itemhandler.typeid) + " is initiating buyorder. price:" + str(buyprice) + ", quantity:" + str(quantity)) buyorder(itemhandler.typeid, buyprice, quantity) itemhandler.buyorder = cm.Order(itemhandler.typeid, -1, True, buyprice, quantity, quantity, cm.getEVETimestamp()) #this line sets the orderid from -1 to something else refreshAllOrders()
def addItemToQuickbar(typeid): dontShow() itemname = api.getNameFromID(typeid) pyautogui.moveTo(200, 10) pyautogui.sleep(0.3) thing = pyautogui.locateOnScreen('imgs/regionalmarkettopleft.png', confidence=0.9) thing2 = pyautogui.locateOnScreen('imgs/search.png', confidence=0.9) if thing is None or thing2 is None: print("im blind") return addItemToQuickbar(typeid) search_market(itemname) cm.sleep(4) searchareacapturepos = cm.Area(thing.left, thing.top + 100, thing2.left - thing.left + 50, 400) for loopidx in range(20): ocr = cm.grabandocr(searchareacapturepos) ocrlines = ocr.splitlines() if loopidx == 10: search_market(itemname) cm.sleep(0.5) stringdict = {} curstring = "" for idx, s in enumerate(ocrlines): s = s.lower() if (len(s.split()) <= 11 or len(s.split()[-1]) < 2): if curstring: stringdict[curstring.strip()] = idx - 1 curstring = "" else: curstring += s.split()[-1] + " " if (idx == len(ocrlines) - 1): stringdict[curstring.strip()] = idx - 1 highestsim = -1 bestidx = 0 for s in stringdict: cursim = cm.similar(itemname.lower(), s) if cursim > highestsim: highestsim = cursim bestidx = stringdict[s] if (highestsim > 0.8): s = ocrlines[bestidx] print("found item in search results: " + s) offsetpos = searchareacapturepos mousex = offsetpos.x + int(s.split()[6]) / 4 + 5 mousey = offsetpos.y + int(s.split()[7]) / 4 + 5 cm.clickxy(mousex, mousey) cm.sleep(1.5) thing = pyautogui.locateOnScreen('imgs/search.png', confidence=0.9) marketnamearea = cm.Area(thing.left + 158, thing.top + 14, 375, 30) ocr = cm.grabandocr(marketnamearea) marketname = "" for line in ocr.splitlines(): if len(line.split()) > 11: marketname += line.split()[-1] + ' ' #strips marketname of whitespace and the list 4 characters, which should be: " i ©" marketname = marketname.strip()[:-4] print("read marketname while adding item: " + marketname) #marketname is the ocr result, itemname is the actual item were trying to add if (cm.similar(marketname.lower(), itemname.lower()) < 0.75): print("clicked wrong item while adding, retrying") return addItemToQuickbar(typeid) cm.clickxy(mousex, mousey, right=True) cm.sleep(0.2) cm.clickxy(mousex + 52, mousey + 29) print("old itemlist:") print(itemlist) if itemname not in itemlist: itemlist.append(itemname) itemlist.sort(key=str.lower) print("new itemlist:") print(itemlist) return if loopidx > 12: #we only get here if it didnt find an item: the item must have been in a collapsed category for s in ocr.splitlines(): if (len(s.split()) > 11 and len(s.split()[-1]) > 3): #we do NOT want to open the blueprint category if not "prints" in s and not "react" in s: offsetpos = searchareacapturepos mousex = offsetpos.x + int(s.split()[6]) / 4 + 5 mousey = offsetpos.y + int(s.split()[7]) / 4 + 5 cm.clickxy(mousex, mousey) break cm.sleep(0.5) print("looped through item adding a lot without success, aborting") sys.exit()
def handle(self, nomorebuy=False): orderstuff.refreshAllOrders() if (nomorebuy and not self.sellorderlist and not self.buyorder): return goodprices = orderstuff.getGoodPrices(self.typeid) #check unprofitable, cancel buyorder if it is orderstuff.refreshUnprofitable(self, goodprices) if self.unprofitable: if self.unprofitabledate == -1: self.unprofitabledate = getEVETimestamp() else: self.unprofitabledate = -1 #we can only cancel if it has been unprofitable for 20 minutes if (self.unprofitable and self.buyorder is not None and (getEVETimestamp() - self.unprofitabledate > 1200)): print("cancelling itemhandler: " + api.getNameFromID(self.typeid) + "'s buyorder due to unprofitability") orderstuff.cancelOrder(self.buyorder) print("trying to sell itemhandler: " + api.getNameFromID(self.typeid) + "'s purchases") orderstuff.sellItem(self, goodprices) #we only replace the handler when the sellorder is gone #todo implement function that converts an unprofitable itemhandler to an leftoveritemhandler, so there's space for a normal itemhandler if len(self.sellorderlist) == 0: print( "didn't have any purchases, fetching new itemhandlers from api..." ) api.fetchItemHandlers() return #we only sell half of bought once per item cycle if self.buyorder is not None and not self.unprofitable: if (self.buyorder.volremaining < (self.buyorder.volentered / 2) and not self.sellorderlist) or self.buyorder.finished: orderstuff.sellItem(self, goodprices) if self.buyorder.finished: self.buyorder = None #we place buyorder when there are no orders if not nomorebuy: if not self.buyorder and not self.sellorderlist and not self.unprofitable: orderstuff.buyItem(self, goodprices) return #check if all sellorders are done #finished is false if its not finished if len(self.sellorderlist) > 0 and all( order.finished == True for order in self.sellorderlist) and self.buyorder is None: self.sellorderlist = [] print("itemhandler went through full trade cycle") if self.unprofitable and (getEVETimestamp() - self.unprofitabledate > 3600): print("fetching new itemhandlers from api...") api.fetchItemHandlers() return else: print("increasing volume by 5%...") self.volume = math.ceil(self.volume * 1.05) #update prices orderstuff.checkAndUnderBid(self, goodprices)
def doTradeBot(tradedaystart): logging.basicConfig(level=logging.DEBUG, filename="logfile.txt", filemode="a+", format="%(asctime)-15s %(levelname)-8s %(message)s") variables.init() pyautogui.sleep(5) #todo implement check to look if "expires in" is sorted in the correct direction (lowest timestamp first) """ stuff = (a for a in pyautogui.locateAllOnScreen('imgs/expiresin.png') if a.left < 500) for a in stuff: print(a)""" quickbar.dontShow() pyautogui.sleep(1) guiinit() api.fetchItemHandlers() loadOrders() for ih in variables.itemhandlerlist: print(ih.__dict__) #underbid order loop logic print("handling leftoveritemhandlers once") for ih in variables.itemhandlerlist: if isinstance(ih, cm.LeftoverItemHandler): ih.handle() #bot runs 10 hours total, 7 hours normally and 3 hours trying to sell everything while cm.getEVETimestamp() - tradedaystart < 3600 * 7: for ih in variables.itemhandlerlist: priorlist = getPriorityItemhandlers() if priorlist: print("handling prioritised itemhandler: " + api.getNameFromID(priorlist[0].typeid)) priorlist[0].handle() print("handling itemhandler: " + api.getNameFromID(ih.typeid)) ih.handle() #tries selling all items that were bought print("selling all bought items") for ih in variables.itemhandlerlist: if ih.buyorder is not None: goodprices = getGoodPrices(ih.typeid) sellItem(ih, goodprices) while cm.getEVETimestamp() - tradedaystart < 3600 * 10: for ih in variables.itemhandlerlist: priorlist = getPriorityItemhandlers() if priorlist: print("handling prioritised itemhandler: " + api.getNameFromID(priorlist[0].typeid)) priorlist[0].handle() print("handling itemhandler: " + api.getNameFromID(ih.typeid)) if ih.sellorderlist: ih.handle(nomorebuy=True) print("listung all unfinished sellorders") for idx, ih in enumerate(variables.itemhandlerlist): for so in ih.sellorderlist: print("Couldn't finish selling item called: " + api.getNameFromID(so.typeid)) print("ended trading day")
def sellitemininventory(typeid, price): item = api.getNameFromID(typeid) cm.clickPointPNG('imgs/inventorytopright.png', 0, 25, 2, cache=True) cm.sleep(0.2) cm.safetypewrite(item) stackitems(item) cm.sleep(0.5) thing = pyautogui.locateOnScreen('imgs/inventoryitemhangar.png') inventorylist = cm.Area(thing.left + 25, thing.top + 70, 500, 250) cm.sleep(1) box = inventorylist.toAbsTuple() ocr = cm.grabandocr(box) #todo implement ocr with highestsim check for s in ocr.splitlines(): if (s.split()[-1][:5] in item.lower()): offsetpos = inventorylist mousex = offsetpos.x + int(s.split()[6]) / 4 + 5 mousey = offsetpos.y + int(s.split()[7]) / 4 + 5 cm.clickxy(mousex, mousey, clicks=1, right=True) cm.sleep(0.2) box = (mousex + 15, mousey + 2, mousex + 15 + 135, mousey + 3 + 200) ocr = cm.grabandocr(box) for s in ocr.splitlines(): if (s.split()[-1] == "sell"): mousex = mousex + 18 + int(s.split()[6]) / 4 + 5 mousey = mousey + 3 + int(s.split()[7]) / 4 + 5 cm.clickxy(mousex, mousey) cm.sleep(5) #todo replace this with clickpointpng thing = pyautogui.locateOnScreen('imgs/sellitems.png') pricefield = cm.Point(thing.left + thing.width / 2, thing.top + 80) thing = pyautogui.locateOnScreen( 'imgs/sellitemsellcancel.png') sellbutton = cm.Point(thing.left + 25, thing.top + 12) thing = pyautogui.locateOnScreen( 'imgs/sellitemduration.png') duration = cm.Point(thing.left - 50, thing.top + 28) #set duration to 3 months cm.clickPoint(duration) for _ in range(10): pyautogui.press('down') cm.clickPoint(duration) #set price pyautogui.moveTo(pricefield.x, pricefield.y) cm.sleep(0.3) pyautogui.doubleClick(pricefield.x, pricefield.y) cm.safetypewrite(price) cm.clickPoint(sellbutton) cm.sleep(0.5) thing = pyautogui.locateOnScreen( 'imgs/sellitemconfirm.png') confirmbutton = cm.Point(thing.left + 145, thing.top + 193) cm.clickPoint(confirmbutton) thing = pyautogui.locateOnScreen("imgs/warning.png", confidence=0.9) if thing is not None: cm.clickPointPNG("imgs/yesno.png", 20, 10) return 1 return 0
def changeOrder(order, newprice): refreshOrderList() position, itemsinlist = getOrderPosition(order) itemname = api.getNameFromID(order.typeid) print("changing order of item: " + itemname + " in position: " + str(position)) if order.bid: actingPoint, listheight = variables.bidaplh else: actingPoint, listheight = variables.sellaplh pyautogui.moveTo(actingPoint.x, actingPoint.y) cm.sleep(0.2) #this scrolls so the order is visible, and adjusts the position itemsfitinlist = math.ceil(listheight / 20) if (position >= itemsfitinlist): pagescrollcount = math.floor(position / itemsfitinlist) position -= (itemsinlist % itemsfitinlist) pyautogui.scroll(int(-130 * itemsfitinlist * pagescrollcount)) pyautogui.move(0, 20 * position) pyautogui.click(button='right', clicks=1) cm.sleep(0.5) pyautogui.move(35, 10) cm.sleep(0.5) pyautogui.click() thing = pyautogui.locateOnScreen("imgs/modifyorder.png", confidence=0.9) for a in range(100): if thing is None: thing = pyautogui.locateOnScreen("imgs/modifyorder.png", confidence=0.9) cm.sleep(0.2) else: break if thing is None: refreshAllOrders() return changeOrder(order, newprice) box = cm.Area(thing.left + 100, thing.top + 21, 300, 19) ocr = cm.grabandocr(box).splitlines() ocrname = "" for line in ocr: if (len(line.split()) > 11): ocrname += line.split()[-1] + " " print("checking if we clicked the right order...") print("itemname: " + itemname.lower() + ", ocrname: " + ocrname) if cm.similar(ocrname.lower(), itemname.lower()) < 0.5: print("failed similar check") cm.clickxy(thing.left + 265, thing.top + 192) cm.sleep(0.5) refreshAllOrders() return changeOrder(order, newprice) cm.sleep(0.2) pyautogui.keyDown('ctrl') pyautogui.keyDown('c') cm.sleep(0.2) pyautogui.keyUp('c') pyautogui.keyUp('ctrl') realprice = pyperclip.paste() cm.safetypewrite(newprice) cm.sleep(0.2) pyautogui.typewrite(['enter']) cm.sleep(0.5) thing = pyautogui.locateOnScreen("imgs/warning.png", confidence=0.9) if thing is not None: cm.clickPointPNG("imgs/yesno.png", 20, 10) #reset scroll pyautogui.moveTo(actingPoint.x + 10, actingPoint.y + 10) pyautogui.scroll(100000) order.price = float(newprice) order.issuedate = cm.getEVETimestamp()
def loadOrders(): itemhandlerlist = variables.itemhandlerlist marketlogsfolder = os.path.expanduser( '~\\Documents\\EVE\\logs\\Marketlogs') deleteMarketLogs() cm.exportMyOrders() loopidx = 0 while True: if (len(os.listdir(marketlogsfolder)) > 0): break thing = pyautogui.locateOnScreen("imgs/nobuyorsell.png", confidence=0.9) if thing is not None: okbutton = cm.Point(thing.left + 169, thing.top + 194) cm.clickPoint(okbutton) return if loopidx % 5 == 0: cm.exportMyOrders() else: cm.sleep(0.5) loopidx += 1 if not os.listdir(marketlogsfolder)[-1].startswith('My Orders'): return loadOrders() logfile = marketlogsfolder + "\\" + os.listdir(marketlogsfolder)[-1] neworders = [] try: with open(logfile) as export: reader = csv.DictReader(export) for l in reader: neworders.append( cm.Order(int(l['typeID']), int(l['orderID']), str(l['bid']) == "True", float(l['price']), int(float(l['volEntered'])), int(float(l['volRemaining'])), DateUtilParser(l['issueDate']).timestamp())) os.remove(logfile) except: cm.sleep(5) return loadOrders() for no in neworders: if not any(no.typeid == ih.typeid for ih in itemhandlerlist): print("initiating leftoveritemhandler for order:" + api.getNameFromID(no.typeid)) itemhandlerlist.append(cm.LeftoverItemHandler(no.typeid, [], None)) quickbar.addItemToQuickbar(no.typeid) #sort each neworder back into the itemhandlers for itemhandler in itemhandlerlist: itemhandler.sellorderlist = [] itemhandler.buyorder = None for no in neworders: if (itemhandler.typeid == no.typeid): if no.bid: itemhandler.buyorder = no else: itemhandler.sellorderlist.append(no)
def cancelOrder(order): if (order is None or order.finished or not order.canChange()): print("Invalid cancel, ignoring") return refreshOrderList() refreshAllOrders() position, itemsinlist = getOrderPosition(order) print("cancelling buyorder: " + api.getNameFromID(order.typeid)) if order.bid: actingPoint, listheight = variables.bidaplh else: actingPoint, listheight = variables.sellaplh pyautogui.moveTo(actingPoint.x, actingPoint.y) cm.sleep(0.2) #this scrolls so the order is visible, and adjusts the position itemsfitinlist = math.ceil(listheight / 20) if (position >= itemsfitinlist): pagescrollcount = math.floor(position / itemsfitinlist) position -= (itemsinlist % itemsfitinlist) pyautogui.scroll(int(-130 * itemsfitinlist * pagescrollcount)) pyautogui.move(0, 20 * position) pyautogui.click(button='right', clicks=1) cm.sleep(0.2) #clicking market details on order and checking if we clicked the right order pyautogui.move(40, 68) pyautogui.click() cm.sleep(0.5) quickbar.dontShow() cm.sleep(0.2) thing = pyautogui.locateOnScreen('imgs/search.png', confidence=0.9) marketnamearea = cm.Area(thing.left + 158, thing.top + 14, 375, 30) ocr = cm.grabandocr(marketnamearea) marketname = "" for line in ocr.splitlines(): if len(line.split()) > 11: marketname += line.split()[-1] + ' ' marketname = marketname.strip() print("read marketname while cancelling order: " + marketname) if (cm.similar(marketname.lower(), api.getNameFromID(order.typeid).lower()) < 0.5): print("clicked wrong order while cancelling, retrying") return cancelOrder(order) pyautogui.moveTo(actingPoint.x, actingPoint.y) cm.sleep(0.2) if (position >= itemsfitinlist): pagescrollcount = math.floor(position / itemsfitinlist) position -= (itemsinlist % itemsfitinlist) pyautogui.scroll(int(-130 * itemsfitinlist * pagescrollcount)) pyautogui.move(0, 20 * position) pyautogui.click(button='right', clicks=1) cm.sleep(0.2) pyautogui.move(40, 115) pyautogui.click() for ih in variables.itemhandlerlist: if order.bid: if areOrdersTheSame(ih.buyorder, order): ih.buyorder = None else: for so in ih.sellorderlist: if areOrdersTheSame(so, order): so = None print("successfully cancelled order")