HOWTO: Market Interaction

Amadeus

The Maestro
Staff member
First, I want to state that I do not want to have any sort of "Market Tycoon" type scripts posted on the forums for public download. If anyone wants to make a script for the sole purpose of "playing the market", then it should be a private script.

Therefore, for the reason listed above, there are a lot of variables that I have left out of ISXEVE intentionally. Things such as "maximum orders you can have", etc, should be hardcoded into your personal scripts.

However, scripts that contain market interaction as a utility aspect are perfectly fine. For example, releasing a script that sells ore that you've mined, or determines the best station to sell ore, moves the ore to that station, and then sells it, is also ok. It is only scripts that have the sole function of "playing the market" that are not allowed to be posted publically.
----


Now, that being said, I have included a number of short snippets below that illustrate how to do a variety of things with ISXEVE. If you learn how those work, then you can do almost anything with the EVE market.

PATCH NOTES:
Code:
November 9, 2007 -- By Amadeus
[ISXEVE-20071106.0191]
* Added new DATATYPE: 'marketorder' (ie, "Market Order") with the following MEMBERS
  1.  Price                                             (double type)
  2.  InitialQuantity                                   (int type) 
  3.  QuantityRemaining                                 (double type)
  4.  MinQuantityToBuy                                  (int type)
  5.  ID                                                (int type)
  6.  TimeStampWhenIssued                               (uint64 type)
  7.  DateWhenIssued                                    (string type)
  8.  TimeWhenIssued                                    (string type)
  9.  Duration                                          (int type)     [The max length of the order, in days]
  10. StationID                                         (int type)     [Station where the order is located]
  11. Station                                           (string type)
  12. RegionID                                          (int type)     [Region where the order is located]
  13. Region                                            (string type)
  14. SolarSystemID                                     (int type)     [Solar System where the order is located]
  15. SolarSystem                                       (string type)
  16. Range                                             (int type)     [In Jumps, the range from which the item can be bought/sold]
  17. Jumps                                             (int type)     [Jumps to the station where the order is located]
  18. IsSellOrder                                       (bool type)
  19. IsBuyOrder                                        (bool type)
  20. TypeID                                            (int type)
  21. Name                                              (string type)
  (NOTE: The order's "Jumps" must be <= to the "Range" in order to buy/sell.)
* Added new DATATYPE: 'myorder' (ie, "My Orders" tab) with the following MEMBERS:
  1.  Price                                             (double type)
  2.  InitialQuantity                                   (int type) 
  3.  QuantityRemaining                                 (double type)
  4.  MinQuantityToBuy                                  (int type)
  5.  ID                                                (int type)
  6.  TimeStampWhenIssued                               (uint64 type)
  7.  DateWhenIssued                                    (string type)
  8.  TimeWhenIssued                                    (string type)
  9.  Duration                                          (int type)     [The max length of the order, in days]
  10. StationID                                         (int type)     [Station where the order is located]
  11. Station                                           (string type)
  12. RegionID                                          (int type)     [Region where the order is located]
  13. Region                                            (string type)
  14. SolarSystemID                                     (int type)     [Solar System where the order is located]
  15. SolarSystem                                       (string type)
  16. Range                                             (int type)    
  17. TypeID                                            (int type)
  18. Name                                              (string type)
  19. IsContraband                                      (bool type)
  20. IsCorp                                            (bool type)
  21. IsSellOrder                                       (bool type)
  22. IsBuyOrder                                        (bool type)  
* Added the following METHODS to the 'myorder' datatype:
  1. Cancel 
  2. Modify[#]                   {# = new price of the item in isk}
* Added the following METHODS to the 'EVE' datatype:
  1. UpdateMarketOrders_A[#]     {# = the TypeID of the item for which you're searching.}
  2. UpdateMarketOrders_B[#]     {# = the TypeID of the item for which you're searching.}
  *****    
  ***** NOTES:
  ***** 1. BOTH methods should *ALWAYS* be called before using "GetMarketOrders" (each time), because it will refresh the data in your client.
  ***** 2. You MUST place a wait of at least a couple of seconds in between UpdateMarketOrders_A and UpdateMarketOrders_B and then again after
  *****    UpdateMarketOrders_B.  I typically used 'wait 40' between, and then 'wait 10' afterwards, while testing.
  ***** 3. This should be considered sinonymous with "GetMarketOrders" (ie, "Refresh" will "Get" orders if you don't have them already.) 
  *****
  2. ClearMarketOrderCache     {This clears your market order cache.  It is useful if you're doing a lot of market transactions and want 
                                to keep things tidy.}
* Added the following MEMBER to the 'EVE' datatype:
  1. GetMarketOrders[<index:marketorder>]           (int type) {retrieves all buy/sell orders currently cached by your client}          
     GetMarketOrders[<index:marketorder>,#]         (int type) {retrieves all buy/sell orders currently cached by your client for the given TypeID#}
     GetMarketOrders[<index:marketorder>,"Buy"]     (int type) {retrieves all buy orders currently cached by your client}
     GetMarketOrders[<index:marketorder>,"Buy",#]   (int type) {retrieves all buy orders currently cached by your client for the given TypeID#}
     GetMarketOrders[<index:marketorder>,"Sell"]    (int type) {retrieves all sell orders currently cached by your client}
     GetMarketOrders[<index:marketorder>,"Sell",#]  (int type) {retrieves all sell orders currently cached by your client for the given TypeID#}
* Added the following METHODS to the 'EVE' datatype:
  1. DoGetMarketOrders[<index:marketorder>]                    {retrieves all buy/sell orders currently cached by your client}          
     DoGetMarketOrders[<index:marketorder>,#]                  {retrieves all buy/sell orders currently cached by your client for the given TypeID#}
     DoGetMarketOrders[<index:marketorder>,"Buy"]              {retrieves all buy orders currently cached by your client}
     DoGetMarketOrders[<index:marketorder>,"Buy",#]            {retrieves all buy orders currently cached by your client for the given TypeID#}
     DoGetMarketOrders[<index:marketorder>,"Sell"]             {retrieves all sell orders currently cached by your client}
     DoGetMarketOrders[<index:marketorder>,"Sell",#]           {retrieves all sell orders currently cached by your client for the given TypeID#}  
  2. PlaceBuyOrder[StationID#, TypeID#, Price#, Quantity#, <Range>, MinQuantity#, <Duration>]
     ~ <Range> can be: "Station", "System", "Region", 1, 2, 3, 4, 5, 10, 20, 30, 40
     ~ Duration is in DAYS
     ~ To get your current stationID# use ${Me.StationID}
     ~ Quantity# is the MAX quantity you will buy overall, while MinQuantity# is the minimum that you will buy in a single transaction
     ~ NOTE: If you place a buy order that already matches a sell order that's on market, it will act as an 'instant' buy order.
* Added new METHOD to the 'item' datatype:
  1. PlaceSellOrder[Price#, Quantity#, Duration]
     ~ Duration is in DAYS
     ~ NOTE: If you place a sell order that already matches a buy order that's on the market, it will act as an 'instant' sell order'
     ~ NOTE: As of now, you may only sell items within a station (and they will sell from THAT station) with ISXEVE.
     ~ NOTE: As of now, ISXEVE does not take into account your current/maximum number of sell orders.  Your script must handle that.
* Added the following MEMBERS to the 'character' datatype:
  1. GetMyOrders[<index:myorder>]           (int type) {retrieves all "My Orders" cached by your client}          
     GetMyOrders[<index:myorder>,#]         (int type) {retrieves all "My Orders" cached by your client for the given TypeID#}
     GetMyOrders[<index:myorder>,"Buy"]     (int type) {retrieves all *buy* "My Orders" cached by your client}
     GetMyOrders[<index:myorder>,"Buy",#]   (int type) {retrieves all *buy* "My Orders" cached by your client for the given TypeID#}
     GetMyOrders[<index:myorder>,"Sell"]    (int type) {retrieves all *sell* "My Orders" cached by your client}
     GetMyOrders[<index:myorder>,"Sell",#]  (int type) {retrieves all *sell* "My Orders" cached by your client for the given TypeID#}        
* Added the following METHODS to the 'character' datatype:
  1. DoGetMyOrders[<index:myorder>]                    {retrieves all "My Orders" cached by your client}          
     DoGetMyOrders[<index:myorder>,#]                  {retrieves all "My Orders" cached by your client for the given TypeID#}
     DoGetMyOrders[<index:myorder>,"Buy"]              {retrieves all *buy* "My Orders" cached by your client}
     DoGetMyOrders[<index:myorder>,"Buy",#]            {retrieves all *buy* "My Orders" cached by your client for the given TypeID#}
     DoGetMyOrders[<index:myorder>,"Sell"]             {retrieves all *sell* "My Orders" cached by your client}
     DoGetMyOrders[<index:myorder>,"Sell",#]           {retrieves all *sell* "My Orders" cached by your client for the given TypeID#}       
  2. UpdateMyOrders
Also....

To clarify:

  • UpdateMarketOrders_A -- Retrieves new data from the server in regards to the typeID that you give. It updates everything but the 'Jumps' MEMBER of the 'marketorder' datatype.
  • UpdateMarketOrders_B -- Updates the 'Jumps' MEMBER of the 'marketorder' datatype.
Therefore, if your script doesn't care about the number of jumps to an order's station (or doesn't care about it right then), you can leave out _B I suppose. You'll just get zero for all .Jump values until you use it.
 

Amadeus

The Maestro
Staff member
This is a script that gets market data about an item type (in this case, "Amarr Titan" skill books) and then displays information about those buy/sell orders.

Code:
function main()
{
	variable int i = 1
	variable index:marketorder Orders
	variable int OrdersCount
   	 		
	echo "Updating/Fetching Market Orders..."
	; 3347 = Amarr Titan (skill book)
	EVE:UpdateMarketOrders_A[3347]
	wait 40
	EVE:UpdateMarketOrders_B[3347]
	wait 10
		   	 		
	OrdersCount:Set[${EVE.GetMarketOrders[Orders]}]
	echo Populating Orders List:: ${OrdersCount} items total
    
	do
	{ 
		if (${Orders.Get[${i}].IsSellOrder})
		{
			echo === SELL Order ===
		}
		elseif (${Orders.Get[${i}].IsBuyOrder})
		{
			echo === BUY Order ===
		}
		echo Issued: ${Orders.Get[${i}].DateWhenIssued} at ${Orders.Get[${i}].TimeWhenIssued} (${Orders.Get[${i}].Duration}-day order)
		echo ID: ${Orders.Get[${i}].ID}
		echo TypeID: ${Orders.Get[${i}].TypeID} (${Orders.Get[${i}].Name})	 
		echo Price: ${Orders.Get[${i}].Price}
		echo InitialQty: ${Orders.Get[${i}].InitialQuantity} - QtyRemaining: ${Orders.Get[${i}].QuantityRemaining} - MinQtyToBuy: ${Orders.Get[${i}].MinQuantityToBuy}
		echo Station: ${Orders.Get[${i}].Station} (${Orders.Get[${i}].StationID})  [${Orders.Get[${i}].Jumps} jumps away]
		echo SolarSystem: ${Orders.Get[${i}].SolarSystem} (${Orders.Get[${i}].SolarSystemID})
		echo Region: ${Orders.Get[${i}].Region} (${Orders.Get[${i}].RegionID})
		echo Order Range: ${Orders.Get[${i}].Range} jumps
		echo ==================
	}
	while ${i:Inc} <= ${OrdersCount}    
    		
	echo "Script finished." 
}
 

Amadeus

The Maestro
Staff member
This script goes through your own "My Orders" and displays information about them

Code:
function main()
{
	variable int i = 1
	variable index:myorder Orders
	variable int OrdersCount
   	 		
	echo "Updating/Fetching My Orders..."
	Me:UpdateMyOrders
	wait 10
   	 		
	OrdersCount:Set[${Me.GetMyOrders[Orders]}]
	echo Populating Orders List:: ${OrdersCount} items total
    
	do
	{ 
		if (${Orders.Get[${i}].IsSellOrder})
		{
			echo === SELL Order ===
		}
		elseif (${Orders.Get[${i}].IsBuyOrder})
		{
			echo === BUY Order ===
		}
		echo Issued: ${Orders.Get[${i}].DateWhenIssued} at ${Orders.Get[${i}].TimeWhenIssued} (${Orders.Get[${i}].Duration}-day order)
		echo ID: ${Orders.Get[${i}].ID}
		echo TypeID: ${Orders.Get[${i}].TypeID} (${Orders.Get[${i}].Name})	 
		echo Price: ${Orders.Get[${i}].Price}
		echo InitialQty: ${Orders.Get[${i}].InitialQuantity} - QtyRemaining: ${Orders.Get[${i}].QuantityRemaining} - MinQtyToBuy: ${Orders.Get[${i}].MinQuantityToBuy}
		echo Station: ${Orders.Get[${i}].Station} (${Orders.Get[${i}].StationID})
		echo SolarSystem: ${Orders.Get[${i}].SolarSystem} (${Orders.Get[${i}].SolarSystemID})
		echo Region: ${Orders.Get[${i}].Region} (${Orders.Get[${i}].RegionID})
		echo Order Range: ${Orders.Get[${i}].Range} jumps
		echo IsCorp: ${Orders.Get[${i}].IsCorp}
		echo IsContraband: ${Orders.Get[${i}].IsContraband}
		echo ==================
	}
	while ${i:Inc} <= ${OrdersCount}     
    		
	echo "Script finished."
}
 

Amadeus

The Maestro
Staff member
This script illustrates how to "Cancel" one of your "My Orders". In this example, we are cancelling all orders that contain "Mining Laser Upgrade" in the name of the item.

Code:
function main()
{
	variable int i = 1
	variable index:myorder Orders
	variable int OrdersCount
   	 		
	echo "Updating/Fetching My Orders..."
	Me:UpdateMyOrders
	wait 10
   	 		
	OrdersCount:Set[${Me.GetMyOrders[Orders]}]
	echo Populating Orders List:: ${OrdersCount} items total
    
	do
	{ 
		if (${Orders.Get[${i}].Name.Find["Mining Laser Upgrade"]} > 0)
		{
			Orders.Get[${i}]:Cancel
		}
		wait 15
	}
	while ${i:Inc} <= ${OrdersCount}     
    		
	echo "Script finished."
}
 

Amadeus

The Maestro
Staff member
This snippet shows how you would 'modify' an existing "My Order". This example sets items that contain "Expanded Cargohold I" in their names to 30,000 ISK.

You'll notice that I put in some usage of a "collection:int" to keep tabs of when orders were modified. It doesn't really do anything in this snippet; however, you can use the CONCEPT of it in your larger scripts for keeping tabs on how often you're modifying a particular orderID#.

(NOTE: The Timestamp usage in this script is untested.)

Code:
variable(script) collection:int OrdersModified

function main()
{
	variable int i = 1
	variable index:myorder Orders
	variable int OrdersCount
   	 		
	echo "Updating/Fetching My Orders..."
	Me:UpdateMyOrders
 	wait 10
   	 		
	OrdersCount:Set[${Me.GetMyOrders[Orders]}]
	echo Populating Orders List:: ${OrdersCount} items total
    
	do
	{ 
		if (${Orders.Get[${i}].Name.Find["Expanded Cargohold I"]} > 0)
		{
			if (${OrdersModified.Element[${Orders.Get[${i}].OrderID}](exists)})
			{
				; only modify orders every 5 minutes
				if (${Time.Timestamp} >= ${Math.Calc[${OrdersModified.Element[${Orders.Get[${i}].OrderID}]} + 300]})
				{	
					Orders.Get[${i}]:Modify[30000]
					OrdersModified:Set[${Orders.Get[${i}].OrderID},${Time.Timestamp}]
				}
				else
				{
					echo "You may not modify this order for another ${Math.Calc[${Math.Calc[${OrdersModified.Element[${Orders.Get[${i}].OrderID}]} + 300]} - ${Time.Timestamp}]} seconds.
				}
			}
			else
			{
				Orders.Get[${i}]:Modify[30000]
				OrdersModified:Set[${Orders.Get[${i}].OrderID},${Time.Timestamp}]
			}    			 	 		
		}
		wait 15
	}
	while ${i:Inc} <= ${OrdersCount}     

	echo "Script finished."
}
 

Amadeus

The Maestro
Staff member
To place a "buy order" that is not 'instant' is very easy. Just follow the syntax given for EVE:placeBuyOrder in the patch notes.

This snippet illustrates how you would place a buy order for an item that is currently for sale on the market. In this example, we are buying the first "Expanded Cargohold I" that is available in our CURRENT STATION for less than 5000 isk.

Code:
function main()
{
	variable int i = 1
	variable int NumberToBuy = 1
	variable index:marketorder Orders
	variable int OrdersCount
   	 		
	echo "Updating/Fetching Market Orders..."
	; 1317 = Expanded Cargohold I
	EVE:UpdateMarketOrders_A[1317]
	wait 40
	EVE:UpdateMarketOrders_B[1317]
	wait 10
   	 		
	OrdersCount:Set[${EVE.GetMarketOrders[Orders]}]
	echo Populating Orders List:: ${OrdersCount} items total
    
	do
	{ 
		if (${Orders.Get[${i}].IsSellOrder})
		{
			if (${Orders.Get[${i}].Jumps} == 0)
			{
				if (${Orders.Get[${i}].Price} < 5500)
				{
					EVE:PlaceBuyOrder[${Orders.Get[${i}].StationID},${Orders.Get[${i}].TypeID},${Orders.Get[${i}].Price},1,"Station",1,1]
					wait 10
					NumberToBuy:Dec
				}
			}
		}
							
		if (${NumberToBuy} == 0)
		{
			break
		}
	}
	while ${i:Inc} <= ${OrdersCount}    
    		
	echo "Script finished." 
}
 

Amadeus

The Maestro
Staff member
This snippet illustrates how you can sell items on the market with ISXEVE. In this particular example, all we are doing is selling any "expanded cargohold I" in our hangar bay for 10,000 isk each (1 day auction.)

Sell orders are "instant" if it matches what is in the market already. Therefore, if there was a buy order already out there that had a range that included your station and for an amount of 10000 (or more), your item would sell instantly.

Code:
function main()
{
	if !${Me.InStation}
		return
  		
	; Open Hangar
	EVE:Execute[OpenHangarFloor]
	wait 15
    
	Me.Station:StackAllHangarItems
	wait 5
    
	variable int i = 1
	variable index:item HangarItems
	variable int HangarItemsCount
	HangarItemsCount:Set[${Me.Station.GetHangarItems[HangarItems]}]
	echo Populating HangarItems List:: ${HangarItemsCount} items total

	do
	{ 
		if (${HangarItems.Get[${i}].Name.Find[Expanded Cargohold I]} > 0)
		{
			HangarItems.Get[${i}]:PlaceSellOrder[10000,${HangarItems.Get[${i}].Quantity},1]
			wait 20
		}
	}
	while ${i:Inc} <= ${HangarItemsCount}  
		
	echo "Script finished." 
}
 

Amadeus

The Maestro
Staff member
To clarify:

  • UpdateMarketOrders_A -- Retrieves new data from the server in regards to the typeID that you give. It updates everything but the 'Jumps' MEMBER of the 'marketorder' datatype.
  • UpdateMarketOrders_B -- Updates the 'Jumps' MEMBER of the 'marketorder' datatype.
Therefore, if your script doesn't care about the number of jumps to an order's station (or doesn't care about it right then), you can leave out _B I suppose. You'll just get zero for all .Jump values until you use it.
 

oddjobmj

Active Member
The code snippets you have provided are very helpful.

I am trying to combine some of these functions and am having a little trouble. Though, I'm not going to post it here as to avoid breaking your rule.

I am using the snippet you provided described as "This script goes through your own "My Orders" and displays information about them"

Though, before the end of that loop I'd like it to take that TypeID and run another snippet; "This is a script that gets market data about an item type (in this case, "Amarr Titan" skill books) and then displays information about those buy/sell orders."

Problem being, I don't know what to place in here: [3347]

Code:
	EVE:UpdateMarketOrders_A[3347]
	wait 40
	EVE:UpdateMarketOrders_B[3347]
	wait 10
Of course, that's the TypeID for the Amarr Titan Skillbook. Although, I want it to call the ID from the first 'snippet'. I've tried creating a new int and storing the TypeID into that and then referencing it:
(x's signifying deleted code)
Code:
variable int TypeID
xxxxxxx
xxxxxxx
do
{
xxxxxxx
xxxxxxx
TypeID = ${Orders.Get[${i}].TypeID}
xxxxxxx
xxxxxxx
EVE:UpdateMarketOrders_A[TypeID]
xxxxxxx
xxxxxxx
}
while xxxxxxx
but that didn't work. I'm a new coder, so I've likely made atleast one syntax error. Though, I can usually debug these via console. No luck!

I also tried calling the TypeID in at that point:

Code:
EVE:UpdateMarketOrders_A[${Orders.Get[${i}].TypeID}]
Haha, no luck there, either.

Any suggestions?

Thank you for your time and please forgive me for my ignorance. I'm doing my best.
 

GliderPro

Active Member
You made one syntax error in your snippet. This is the right way to pass a variable in Lavishscript.

EVE:UpdateMarketOrders_A[${TypeID}]

Take a look at the market object in EveBot. I've released all the code from my market bot that I can without making Amadeus frown. :) Also, that object is used for trade missions to buy the crap you need to give your agent. It is not completely without bugs though.
 

oddjobmj

Active Member
Wow, thank you very much!

I'll definitely take a look at that code, too.

You'll likely see me posting a few more questions. Hopefully that's alright. I've got quite a bit more to add to this script.

Thanks again!

~Odd
 

Dim454

Member
EVE:UpdateMarketOrders_A[${TypeID}]

Cant get it to work, it says "no such eve method".

Tried bolth ways. Was there a patch to make this not work?
 

CyberTech

Second-in-Command
Staff member
EVE:UpdateMarketOrders_A[${TypeID}]

Cant get it to work, it says "no such eve method".

Tried bolth ways. Was there a patch to make this not work?
Read the changelog in your extensions dir for isxeve -- it is the authoritative source. That function was changed a while ago.
 

BaconLord

Member
I've been playing with .NET version of ISXEVE and I have a problem.
I want to read all my orders using this code and then do something with them:

EVE.ISXEVE.Me me = new Me();
me.UpdateMyOrders();
Thread.Sleep(10000);

private IList<MyOrder> _orders = new List<MyOrder>();
_orders = me.GetMyOrders();

But method UpdateMyOrders() doesnt seems to be working for me. Object _orders is always empty. What am i doing wrong?
 

chester

Member
have trouble with the following code
Code:
if (${Time.Timestamp} <= ${Math.Calc[${OrdersModified.Element[${Orders.Get[${i}].OrderID}]} + 300]})
seems like Time.Timestamp is giving a huge number and the ${Orders.Get[${i}].OrderID}]} gives NULL

any idea?
 
Top Bottom