Jump to content
Frequently Asked Questions
  • Are you not able to open the client? Try following our getting started guide
  • Still not working? Try downloading and running JarFix
  • Help! My bot doesn't do anything! Enable fresh start in client settings and restart the client
  • How to purchase with PayPal/OSRS/Crypto gold? You can purchase vouchers from other users
  • [Grand Exchange] Buying & Selling Tutorial


    Defiled

    Recommended Posts

    Hello Everyone!

    This is a simple but yet useful guide to Buying & Selling on the Grand Exchange!

     

    Why would you want to Buy & Sell on the Grand Exchange?

    You could add this functionality to your scripts allowing them to buy resources  &  sell end-products. More Automation = More Laziness on your end!

    __________

    Let's start with the methods that are of use to us.

    getGrandExchange() - Gets the GrandExchange File to allow you to use its methods in your script.
    
    getArea(BankLocation.GRANDEXCHANGE).contains(getLocalPlayer()) - Detects if the bot/player is in a certain radius of the GrandExchange.
    
    getGrandExchange().open() - Opens the GrandExchange interface
    
    getGrandExchange().openBuyScreen(int slot) - Opens Buy slot (Slot has to return slotContainsItem(int slot) == false )
    
    getGrandExchange().getFirstOpenSlot() - Checks for an open slot, and returns the first one it sees (Integer)
    
    getGrandExchange().getFirstOpenSlot() == -1 -  Can be used in an if statement/switch to detect if there are no open slots
    
    getGrandExchange().isBuyOpen() - A simple boolean that detects if the buy screen is open.
    
    getGrandExchange().isSellOpen() - A simple boolean that detects if the sell screen is open.
    
    getGrandExchange().buy(String itemName, int Quantity, int Price) - Does the whole buying process when getGrandExchange().isBuyOpen() == true
    
    getGrandExchange().sell(String itemName, int Quantity, int Price) - Does the whole selling process when getGrandExchange().isSellOpen() == true
    
    getGrandExchange().cancelOffer(int slot) - If slot contains item, then cancel the offer.
    
    getGrandExchange().cancelAll() - Newly added method by @Nuclear Nezz's DB Update which allows for cancellation of all offers.

     

    Example Case: If your bot is currently doing a task, and you want it to go sell the end products of the task after reaching a certain threshold.

    - Add this when the task script is checking the inventory and/or bank: (explanation in code)

    Inventory:
    
    if(getInventory().count(String itemName or int itemNumber) == int itemQuantityWanted) { //Check if the task item has reached its threshold, if true it executes the startGE(); method
    
    startGE(); //Don't worry, we're going to be creating this method below! - Starts the GE Buying/Selling process
    
    }
    
    Bank:
    
    if(getBank().contains(String itemName or int itemNumber, int Quantity)) { //Check if the task item has reached its threshold, if true it executes the startGE(); method
    
    startGE();  //Don't worry, we're going to be creating this method below! - Starts the GE Buying/Selling process
    
    }

     

     

    Making the startGE() method requires us to make a couple of methods to accomplish what we need (You can stuff it all in one method or you can do it in Nodes):

    We need these variables & methods:

    Variables:
    
    BankLocation GEBank = BankLocation.GRAND_EXCHANGE; //Assigns our GEBank variable the GE Location
    private static final itemToSell = 0000;  //Item ID
    
    //OR
    
    private static final itemToBuy = 0000; //Item ID
    
    private static final COINS = 995; //gets COINS Item ID
    
    int state; //We're going to be using this to set the state to Buying or Selling.
    
    int currentOpenBuySlot; //This variable will contain the slot that will be opened
    
    int currentOpenSellSlot; //This variable will contain the slot that will be opened

    Now some methods:

    Methods:
    
    private void walkToGE() { //Check if the player is at the GE (if false - walks there)
    
    if(!GEBank.getArea(5).contains(getLocalPlayer()) { // Checks if the player is in GE spreading 5 tiles
    
    getWalking().walk(GEBank.getCenter()); //walks to the center point of the GEBank
    
    //OR
    
    getWalking().walk(GEBank.getRandomTile()); //Randomizes point of arrival at the GEBank
    
    }
    
    
    
    private void fetchFunds() { //Only regarding the Buying state
    
    if(!getInventory().contains(COINS)) { //checks if the inventory contains COINS
    
    getBank().openClosest(); //Opens closest bank, you can set it to open(GEBank) if you want.
    
    getBank().withdrawAll(COINS); // withdraws all coins, you can set it to withdraw(COINS, int quantity) if you want.
    
    getBank().close(); //closes bank interface
    
    }
    
    }
    
    
    
    private void fetchItemsToSell() {
    
    if(!getInventory().count(itemToSell) == int itemQuantity) {
    getBank().openClosest(); //Opens closest bank, you can set it to open(GEBank) if you want.
    
    getBank().withdraw(itemToSell, itemQuantity); 
    
    getBank().close(); //closes bank interface
    
    }
    
    }
       
    private void openBuyScreen() {
      
    if(!getGrandExchange().isBuyOpen()) { //check if buy isn't open
      
    currentOpenSlot = getGrandExchange().getFirstOpenSlot(); //set currentOpenSlot to a random non-occupied slot
      
    getGrandExchange().openBuyScreen(currentOpenBuySlot); //opens the slot
      
    sleep(1000); //sleeps for a sec
      
    }
    }
       
    private void openSellScreen() {
      
    if(!getGrandExchange().isSellOpen()) { //check if sell isn't open
      
    currentOpenSlot = getGrandExchange().getFirstOpenSlot(); //set currentOpenSlot to a random non-occupied slot
      
    getGrandExchange().openSellScreen(currentOpenSellSlot); //opens the slot
      
    sleep(1000); //sleeps for a sec
      
    }
    }
       
    private void collectAll() {
      
    if(getGrandExchange().isReadyToCollect()) { //check if there are bought/sold items
      
    getGrandExchange().collect(); //clicks the collect button on the ge interface
      
    sleep(2000); //sleeps 2 secs - calculated
      
    }
    }

     

    Now lets start with identifying what state of GE Trade you want:

    We'll set it to : If state = 1 then Buying is the state, if state = 2 then Selling is the state

    You can implement the states in your script GUI OR edit it manually!

    startGE() method will do the detection then execute the suitable method that we'll create after it!

    private void startGE() { 
    
    switch(state) { // read what value state is set to
    
    case 1: //Buying state
    
    executeBuyer(): //method to start the buying process
    
    break;
    
    case 2: //Selling state
    
    executeSeller(); //method to start the selling process
    
    break;
    
    }
    
    }

    You can set the state using a setter:

        public void setState(String state) {
            this.state= state;
        }

     

    Let's start with the execution methods:

     

    ExecuteBuyer:

    private void executeBuyer()   {
    
    walkToGE(); //if you're already at the GE, the script will ignore this line
    
    fetchFunds(); //if you already have coins in your inventory, the script will ignore this line
    
    collectAll(); //if there are successfully bought items, this will collect the items
    
    openBuyScreen(); //Detects if a buy screen isnt open and opens it
    
    getGrandExchange().buy(itemToBuy, int quantity, int price); //Buys the item
    
    /** This part is for canceling the order if the item isn't bought **/
    
    sleep(2000); //sleeps for 2 secs because, it takes around 1.5 seconds for the item to return (Bought successfully or Still in the process)
    
    if(getGrandExchange().slotContainsItem(currentOpenSlot)) { //checks if the slot that we currently occupied contains an item/didn't sell
    getGrandExchange().cancelOffer(currentOpenSlot); //cancel the offer
    sleep(1000); //sleeps for 1 sec
    getGrandExchange().goBack();
    }
    
    /** This part is stop the script from looping the buying process during the buying process. **/
    if(getGrandExchange().isBuyOpen()) { // checks if buy screen is open
    sleepUntil(()-> getGrandExchange().isBuyOpen() == false, 2000); //sleeps/doesn't loop till the item is successfully bought and we're back to the main GE interface 
    } 
    
    } 

     

    ExecuteSeller:

    private void executeSeller()   {
    
    walkToGE(); //if you're already at the GE, the script will ignore this line
    
    fetchItemsToSell(); //if you already have the item(s) in your inventory, the script will ignore this line
    
    collectAll(); //if there are successfully sold items, this will collect the items
    
    openSellScreen(); //Detects if a sell screen isnt open and opens it
    
    getGrandExchange().sell(itemToSell, int quantity, int price); //sells the item
    
    /** This part is for canceling the order if the item isn't sold **/
    
    sleep(2000); //sleeps for 2 secs because, it takes around 1.5 seconds for the item to return (Bought successfully or Still in the process)
    
    if(getGrandExchange().slotContainsItem(currentOpenSellSlot)) { //checks if the slot that we currently occupied contains an item/didn't sell
    getGrandExchange().cancelOffer(currentOpenSellSlot); //cancel the offer
    sleep(1000); //sleeps for 1 sec
    getGrandExchange().goBack();
    }
    
    /** This part is stop the script from looping the selling process during the selling process. **/
    if(getGrandExchange().isSellOpen()) { // checks if sell screen is open
    sleepUntil(()-> getGrandExchange().isSellOpen() == false, 2000); //sleeps/doesn't loop till the item is successfully sold and we're back to the main GE interface 
    } 
    
    } 

     

    and There you go! 

    The script will detect if the state is "Selling" or "Buying" then walks there, gets the coins/items, sells/buys, collects/cancels!

     

    Note: this guide is for single item buy/sell handling, although it does work for mass items, you just have to make a reader class, then read the items from a txt file.. then make a foreach loop/iterator to get the items then replace itemToSell/itemToBuy with the looped string ..

    EXTRA!! :D 

    Example:

    ReadFile Methods:
     

        List<String> allItems = new ArrayList<String>(); 
        List<String> item = new ArrayList<String>();
        List<String> price = new ArrayList<String>();
        List<String> quantity = new ArrayList<String>();
        
        public BuyerReader(String path) {
            readFile(path);
        }
    
        public void readFile(String path) {
    
            File file = new File(path);
            if(file.exists()){
                try { 
                    allItems = Files.readAllLines(file.toPath(),Charset.defaultCharset());
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
              if(allItems.isEmpty())
                  return;
            }
            for(String line : allItems){
                String [] res = line.split(";");
                item.add(res[0]);
                price.add(res[1]);
                quantity.add(res[2]);
                
            }
        }
        
        
        
        public List<String> getAllItems() {
            return allItems;
        }
    
    
        public List<String> getItem() {
            return item;
        }
    
    
        public List<String> getPrice() {
            return price;
        }
    
    
        public List<String> getQuantity() {
            return quantity;
        }
    

    GetValues Iterator Variable:

    itemNames = Reader.getItem().iterator();
    

    ReadReader Method:

        private String getItemName() { //This is for the itemname, you can do the same for quantity/price just parse it to int.
            String itemn = null;
            if(itemNames.hasNext()) {
                String in = itemNames.next();
                itemn = in;
            } else {
                stop();
                log("No more items to read!");
            }
            return itemn;
        }

     

     

    If I have written something wrong, please tell me! I'm a human, and humans make mistakes :D That's what we do best! 🖖

    Peace!

    Edited by ItsDefiled
    Edited code based on FeedBack, Still more to edit.
    Link to comment
    Share on other sites

    29 minutes ago, Nex said:

    Seems like u put alot of work into this but isnt most of this guide just shows in the docs?
    https://dreambot.org/javadocs/org/dreambot/api/methods/grandexchange/GrandExchange.html

    This tutorial shows people how to use the methods declared in the GE API, and have most the methods they need ready and explained.

    API = building blocks,

    Java = Equipment,

    This tutorial = the actual construction

     

    Link to comment
    Share on other sites

    You should probably look more into how switch statements work.

    switch(getBank().contains(String itemName or int itemNumber, int Quantity)) { //check the contains() boolean method
    
    case true: //if true
    
         startGE(); //start GE Process
    
    break;
    
    case false: //if false
    
         continueScript(); //continue the task
    
    break;
    
    }

    Error: You can't switch a boolean

    Also, looking at your use of switch statements, you say that it's better for readability, but in the instances you show it seems much harder to read. 

    switch(state) { // read what value state is set to
    
    case 1: //Buying state
    
    executeBuyer(): //method to start the buying process
    
    break;
    
    case 2: //Selling state
    
    executeSeller(); //method to start the selling process
    
    break;
    
    }
    
    In this usage a simple if-else would be more readable or at least an enum with a BUY and SELL case. 

     

    For the executeSeller/executeBuyer method, just have some if elses for the method for readability sake and overall logic of the script.

    As with the current logic you're ignoring whether one is not true and going onto the next. 

    So you know that the character is not at the Grand Exchange and are currently walking towards it and you're going to ask: "do you have coins?", "even though the Grand Exchange is not open and you're not near it, is the buy screen open?", "Going to attempt to buy items and will return false as the bank is not open", etc. So pretty much just use if-else and else-ifs for some of the logic. 

    Link to comment
    Share on other sites

    2 minutes ago, Koschei said:

    You should probably look more into how switch statements work.

    
    switch(getBank().contains(String itemName or int itemNumber, int Quantity)) { //check the contains() boolean method
    
    case true: //if true
    
         startGE(); //start GE Process
    
    break;
    
    case false: //if false
    
         continueScript(); //continue the task
    
    break;
    
    }

    Error: You can't switch a boolean

    Also, looking at your use of switch statements, you say that it's better for readability, but in the instances you show it seems much harder to read. 

    
    switch(state) { // read what value state is set to
    
    case 1: //Buying state
    
    executeBuyer(): //method to start the buying process
    
    break;
    
    case 2: //Selling state
    
    executeSeller(); //method to start the selling process
    
    break;
    
    }
    
    In this usage a simple if-else would be more readable or at least an enum with a BUY and SELL case. 

     

    For the executeSeller/executeBuyer method, just have some if elses for the method for readability sake and overall logic of the script.

    As with the current logic you're ignoring whether one is not true and going onto the next. 

    So you know that the character is not at the Grand Exchange and are currently walking towards it and you're going to ask: "do you have coins?", "even though the Grand Exchange is not open and you're not near it, is the buy screen open?", "Going to attempt to buy items and will return false as the bank is not open", etc. So pretty much just use if-else and else-ifs for some of the logic. 

    Thank you for the feedback!

    I did infact make a mistake with switching a boolean, which is an idiotic mistake I confess. 

    Yes, if/else statements would be more suitable for state declaration.

    I have written this guide in a bit of hurry, and I apologize for the mistake, I'll be sure to fix the code in the thread as soon as I reach my PC.

    Thanks again!

    Link to comment
    Share on other sites

    Forgive me If I'm wrong, I'm still very new here. But I think there's a problem with walkToGE()

    getWalking().walk(GEBank.getRandomTile()); //Randomizes point of arrival at the GEBank

    Shouldn't it be this?:

    // Cannot call getRandomTile() on GEBank
    getWalking().walk(GEBank.getArea().getRandomTile()); //Randomizes point of arrival at the GEBank

    I think you're also missing a closing paren in the if condition.

    Edited by FooBar
    Link to comment
    Share on other sites

    8 hours ago, FooBar said:

    Forgive me If I'm wrong, I'm still very new here. But I think there's a problem with walkToGE()

    
    getWalking().walk(GEBank.getRandomTile()); //Randomizes point of arrival at the GEBank

    Shouldn't it be this?:

    
    // Cannot call getRandomTile() on GEBank
    getWalking().walk(GEBank.getArea().getRandomTile()); //Randomizes point of arrival at the GEBank

    I think you're also missing a closing paren in the if condition.

    Hi,

    No, because getRandomTile returns random coords from the original coordinates. 

    So OriginalCoords.getRandomTile().

    You can also calculate the center tile by adding .getCenter() ..

    But if you wanted to get a certain radius of the area to perhaps detect if the player is in the area.. you can do getArea() in an if statement.

    Link to comment
    Share on other sites

    4 hours ago, ItsDefiled said:

    Hi,

    No, because getRandomTile returns random coords from the original coordinates. 

    So OriginalCoords.getRandomTile().

    You can also calculate the center tile by adding .getCenter() ..

    But if you wanted to get a certain radius of the area to perhaps detect if the player is in the area.. you can do getArea() in an if statement.

    Hmm, that's strange. I was getting an error calling getRandomTile() on GEBank and had to add the getArea() to it

    Link to comment
    Share on other sites

    6 minutes ago, FooBar said:

    Hmm, that's strange. I was getting an error calling getRandomTile() on GEBank and had to add the getArea() to it

    My bad, now that i see it.. you have to put the GEBank into an Area class call.

    ex. Area ge = new Area(BankLocation.GEBank);

    then call it in the walk method.

    You can also just use getArea for that.

    Ill edit your feedback into the thread as soon as i reach my PC.

     

    Link to comment
    Share on other sites

    • 3 years later...

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now
    ×
    ×
    • Create New...

    Important Information

    We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.