Join us at the Oolite Anniversary Party -- London, 7th July 2024, 1pm
More details in this thread.

AI Trading Assistant

Discussion and information relevant to creating special missions, new ships, skins etc.

Moderators: another_commander, winston

User avatar
Wildeblood
---- E L I T E ----
---- E L I T E ----
Posts: 2290
Joined: Sat Jun 11, 2011 6:07 am
Location: Western Australia

Re: AI Trading Assistant OXP ver 1.8

Post by Wildeblood »

READ ME wrote:
Change Log:

1.8 (September 19th, 2012) New market screen HUD(s).

1.7 (September 17th, 2012) New congratulations for extremely good trades. (Visit a rock hermit.)
See the first post for an image of the new look and the download link.
User avatar
Wildeblood
---- E L I T E ----
---- E L I T E ----
Posts: 2290
Joined: Sat Jun 11, 2011 6:07 am
Location: Western Australia

Re: AI Trading Assistant OXP

Post by Wildeblood »

Wildeblood wrote:
Cpt wrote:
It also perpetually warns me that I buy Gems and precious metals over their average price, I know I do but I sell even higher. Perhaps I could interact with the AI to set my buy/sell fixed price boundary of 41 credits for gold, 75c for Platinum and 22c for Gems so it knows my strategy?
That's why it remembers what you actually paid, and reminds you when you sell. If you sell a commodity one unit at a time, and see those average price reminders trending higher, it means you're losing money with every unit you sell. If they trend downwards, then you're making a profit, regardless of average prices.
Apparently this is a thing some players do: just hoard the precious commodities, even buying at above-average prices, until the opportunity to sell at a very high price comes along.

I'll probably implement something more sophisticated the next time I return to this OXP, but in the mean time... I've added in a second warning level, paidFarTooMuch, as well as paidTooMuch, but only for gold, platinum and gems. That means if you're a hoarder you can ignore the "You're paying above average prices" messages and watch for a "Now you're just being silly" message if you buy in the top quartile of possible prices. I've just done that, I have to attend to Real Life now, I'll test it and upload it tonight.
Switeck
---- E L I T E ----
---- E L I T E ----
Posts: 2412
Joined: Mon May 31, 2010 11:11 pm

Re: AI Trading Assistant OXP ver 1.8

Post by Switeck »

Platinum accumulates semi-quickly, so much so that on something smaller than a Cobra 3 you could in theory run out of cargo space. I visit lots of Rock Hermits and other secondary stations that have Platinum at lower-than-normal prices.

Gold would also accumulate semi-quickly if the value in commodities.plist actually worked in a sensible way. (66 kg base amount at each station's main system, increased further by a random amount and in lower economy systems.)

Gemstones are too rare, but even if they weren't...you'd need over 500,000 grams just to have to worry about them taking up 1 TC of cargo space. Most I've ever had of them was ~45,000 grams when I went nuts with cargo contracts. I know how to game the system to get predominately gold/plat/gem cargo contracts once my reputation is high enough.
User avatar
Wildeblood
---- E L I T E ----
---- E L I T E ----
Posts: 2290
Joined: Sat Jun 11, 2011 6:07 am
Location: Western Australia

Re: AI Trading Assistant OXP ver 1.8

Post by Wildeblood »

Switeck wrote:
Gemstones are too rare, but even if they weren't...you'd need over 500,000 grams just to have to worry about them taking up 1 TC of cargo space.
Yeah, I don't really understand the hoarding thing. The constraint on how much you should buy isn't the amount you can carry, it's the amount you can sell. And you can never sell more than 127g of gems at once, so what's the point of paying high prices to amass a lot, eventually finding a station that will offer very high prices, but then not being able to sell all that you've amassed?

Maybe this change is best forgotten: the purpose of trading assistant is to offer positive reinforcement when the player trades correctly - giving encouraging remarks when buying low and selling high. But this change would actually be reinforcing an irrational trading strategy.
User avatar
Wildeblood
---- E L I T E ----
---- E L I T E ----
Posts: 2290
Joined: Sat Jun 11, 2011 6:07 am
Location: Western Australia

Re: AI Trading Assistant OXP ver 1.9

Post by Wildeblood »

Nevertheless, I did it anyway. Version 1.9 is now uploaded.
READ ME wrote:
Change Log:

1.9 (September 20th, 2012) New warning for very high purchase prices, and more new market screen HUD files.
The new warning applies to all commodities, though, not just the precious metals and gems as I originally planned. That's it. It's safe to download: I'll stop messing about with it, and leave it alone for a while now. :D
DeathKnyte
Dangerous
Dangerous
Posts: 95
Joined: Fri Aug 31, 2012 7:31 pm

Re: AI Trading Assistant OXP

Post by DeathKnyte »

Commander McLane wrote:
DeathKnyte wrote:
What I like about that picture, is that you have somehow modified the settings so that it detects the commodities in cim's New Cargos oxp.
"Modifying the settings" means "installing New Cargoes OXP". Different OXPs play along with each other. There's no need to modify one OXP in order to install another OXP.
Wildeblood wrote:
DeathKnyte wrote:
What I like about that picture, is that you have somehow modified the settings so that it detects the commodities in cim's New Cargos oxp.
No, that's just what my market screen always looks like. It's nothing to do with cim's New Cargoes:-
I wrote that because, my own commodity screen (F8) does not list things like, "Edible Arts Graduates", "Evil Juice", "Thargoid Robo-Brains", etc. But in your picture it does.
That reminded me of some of the terms in cim's New Cargoes. oxp.
I thought that you had somehow changed the programing for it to recognize some of them. Nothing more than that.

Please excuse my perception of things.
DeathKnyte
Dangerous
Dangerous
Posts: 95
Joined: Fri Aug 31, 2012 7:31 pm

Re: AI Trading Assistant OXP

Post by DeathKnyte »

Wildeblood wrote:
Apparently this is a thing some players do: just hoard the precious commodities, even buying at above-average prices, until the opportunity to sell at a very high price comes along.
I look at it as simply being shrewd with extra credits.
There is no bank to deposit these extra credits, so they can earn interest.
There is no way of investing - other than your ship, and into the commodities it can carry - in order for those credits to work for you.
So players are finding whichever (other) way works in the game, like the hoarding practice you described above.


*** SPOILER ALERT ***

(Rot13)

Gurer'f nabgure (naq fvzcyre) jnl gb trg n ybg:

Ybbx ng nyy gur pnetb pbagenpgf bssrerq vaibyivat gubhfnaqf bs rvgure; tbyq, cyngvahz, be trz fgbarf.

Irevsl gung gur cevpr vf n tbbq (ybj) bar, ol ersrerapvat va gur pbzzbqvgl fperra.

Nterr gb juvpurire barf (pnetb pbagenpgf) fngvfsl gur nobir.

Qrsnhyg ba (gurve) qryvirel gvzr. Gurer vf ab cranygl, bgure guna n fznyy uvg va lbhe fgnaqvat - juvpu vf znqr hc ol gur arkg fhpprffshy qryvirel.

Abj lbh unir gubhfnaqf bs cerpvbhf vgrzf, sbe n tbbq cevpr.

Fryy ng lbhe yrvfher, jurarire lbh'er va n flfgrz jvgu n cevpr nobir jung lbh cnvq sbe.

:)
Rocketman
Poor
Poor
Posts: 5
Joined: Wed Sep 19, 2012 11:28 am

Re: AI Trading Assistant OXP ver 1.9

Post by Rocketman »

Hello!

I'am examining OXP you are working on (AITrader). And I could not understand one place quite enough. Could you please give me some explanation?

It is about defining of callback handler:

Code: Select all

this.guiScreenChanged = function()
	{
	if (guiScreen === "GUI_SCREEN_MARKET" && player.ship.docked && player.ship.equipmentStatus("EQ_AI_TRADING_ASSISTANT") === "EQUIPMENT_OK")
		{
		this.originalManifest = this.$getManifest();
		this.originalCredits = player.credits;
		this.$monitorManifestCallBack = addFrameCallback(this.$monitorManifest.bind(this));

		this.$originalHUD = player.ship.hud;
		if(player.ship.dockedStation.isMainStation) this.$tradingHUD = "trading-assistant-galcop-hud.plist";
		else this.$tradingHUD = "trading-assistant-hud.plist";
		player.ship.hud = this.$tradingHUD;
		}
	}
This part:

Code: Select all

this.$monitorManifestCallBack = addFrameCallback(this.$monitorManifest.bind(this));
As far as I understand:
$monitorManifestCallBack - callback function handler (needed to remove callback later, when player leaves market);
addFrameCallback - basic metod to add 'new frame' event handler;
.bind() - CCL method which combines two entities.

I can not get why to combine $monitorManifest entity with 'this' entity. 'this' in that case - is some object or function which calls $monitorManifest() at each frame, right?

Thank you!
User avatar
Wildeblood
---- E L I T E ----
---- E L I T E ----
Posts: 2290
Joined: Sat Jun 11, 2011 6:07 am
Location: Western Australia

Re: AI Trading Assistant OXP ver 1.9

Post by Wildeblood »

Firstly, Capt. Murphy seems to like long variable names. I would have called this.$monitorManifestCallBack something like this.mmfcb, or maybe this.$monitorManifestFrameCallbackTrackingID. In any case it's a variable or pointer that holds a reference to the frame callback, so you can later tell Oolite which frame callback to remove.

As far as I know, this means worldScripts["Trading Assistant"], so this.$monitorManifest means worldScripts["Trading Assistant"].$monitorManifest, and this.$getManifest means worldScripts["Trading Assistant"].$getManifest.

addFrameCallback() is an Oolite global method that copies a function to over there somewhere -->, then calls it every frame. bind() is a javascript method which sets the scope of another function/method.

You're asking, why write addFrameCallback(this.$monitorManifest[b].bind(this)[/b]), and not simply addFrameCallback(this.$monitorManifest).

addFrameCallback(this.$monitorManifest[b].bind(this)[/b]) means addFrameCallback(worldScripts["Trading Assistant"].$monitorManifest[b].bind(worldScripts["Trading Assistant"])[/b]), that is when copying $monitorManifest for the frame callback, its execution scope is set to worldScripts["Trading Assistant"].

worldScripts["Trading Assistant"].$monitorManifest calls another function, this.$getManifest, intending to mean worldScripts["Trading Assistant"].$getManifest, which exists.

Let's say the frame callback's ID is abc123. When $monitorManifest is copied over there, it would become abc123.$monitorManifest. When it called this.$getManifest - without the binding - it would be calling abc123.$getManifest, which does not exist.

That's my understanding of the situation. If one of the developers - or someone else cluey - happens by, maybe they'll say whether I'm right, sort of on the right track, or not even close.
User avatar
Tricky
---- E L I T E ----
---- E L I T E ----
Posts: 821
Joined: Sun May 13, 2012 11:12 pm
Location: Bradford, UK. (Anarchic)

Re: AI Trading Assistant OXP ver 1.9

Post by Tricky »

Wildeblood wrote:
Firstly, Capt. Murphy seems to like long variable names. I would have called this.$monitorManifestCallBack something like this.mmfcb, or maybe this.$monitorManifestFrameCallbackTrackingID.
Long variable names makes the code easier to read an debug. Especially if the name is meaningful.
Wildeblood wrote:
As far as I know, this means worldScripts["Trading Assistant"], so this.$monitorManifest means worldScripts["Trading Assistant"].$monitorManifest, and this.$getManifest means worldScripts["Trading Assistant"].$getManifest.
Yes. this refers to the owner of the script. Also known as scope and context. More on this from MDN.
Wildeblood wrote:
addFrameCallback() is an Oolite global method that copies a function to over there somewhere -->, then calls it every frame. bind() is a javascript method which sets the scope of another function/method.

You're asking, why write addFrameCallback(this.$monitorManifest[b].bind(this)[/b]), and not simply addFrameCallback(this.$monitorManifest).

addFrameCallback(this.$monitorManifest[b].bind(this)[/b]) means addFrameCallback(worldScripts["Trading Assistant"].$monitorManifest[b].bind(worldScripts["Trading Assistant"])[/b]), that is when copying $monitorManifest for the frame callback, its execution scope is set to worldScripts["Trading Assistant"].

worldScripts["Trading Assistant"].$monitorManifest calls another function, this.$getManifest, intending to mean worldScripts["Trading Assistant"].$getManifest, which exists.

Let's say the frame callback's ID is abc123. When $monitorManifest is copied over there, it would become abc123.$monitorManifest. When it called this.$getManifest - without the binding - it would be calling abc123.$getManifest, which does not exist.

That's my understanding of the situation. If one of the developers - or someone else cluey - happens by, maybe they'll say whether I'm right, sort of on the right track, or not even close.
From the Mozilla Developer Network - bind
Mozilla Developer Network wrote:
The bind() function creates a new function (a bound function) with the same function body (internal Call attribute in ECMAScript 5 terms) as the function it is being called on (the bound function's target function) with the this value bound to the first argument of bind(), which cannot be overridden. bind() also accepts leading default arguments to provide to the target function when the bound function is called. A bound function may also be constructed using the new operator: doing so acts as though the target function had instead been constructed. The provided this value is ignored, while prepended arguments are provided to the emulated function.
So basically it is binding the frame callback to that function using the owner of this, this is so the frame callback knows who the owner is. So yes, you were spot on.
User avatar
Wildeblood
---- E L I T E ----
---- E L I T E ----
Posts: 2290
Joined: Sat Jun 11, 2011 6:07 am
Location: Western Australia

Re: AI Trading Assistant OXP ver 1.9

Post by Wildeblood »

Tricky wrote:
Wildeblood wrote:
Firstly, Capt. Murphy seems to like long variable names. I would have called this.$monitorManifestCallBack something like this.mmfcb, or maybe this.$monitorManifestFrameCallbackTrackingID.
Long variable names makes the code easier to read an debug. Especially if the name is meaningful.
Up to a point. this.$thisVariableHoldsTheFrameCallbackTrackingIdentificationNumber seems excessive to me. :)
Rocketman wrote:
I am examining OXP you are working on (AITrader).
Why? I cringe at the thought someone might "examine" it. It's a very bad example, or a good example of what not to do under normal circumstances. It's all upside-down and inside-out, to make it easy for people with no interest in javascript to make changes without fear of breaking it.
User avatar
Tricky
---- E L I T E ----
---- E L I T E ----
Posts: 821
Joined: Sun May 13, 2012 11:12 pm
Location: Bradford, UK. (Anarchic)

Re: AI Trading Assistant OXP ver 1.9

Post by Tricky »

Wildeblood wrote:
Tricky wrote:
Wildeblood wrote:
Firstly, Capt. Murphy seems to like long variable names. I would have called this.$monitorManifestCallBack something like this.mmfcb, or maybe this.$monitorManifestFrameCallbackTrackingID.
Long variable names makes the code easier to read an debug. Especially if the name is meaningful.
Up to a point. this.$thisVariableHoldsTheFrameCallbackTrackingIdentificationNumber seems excessive to me. :)
Well yeah! :lol: That is a bit excessive.

BTW - Thanks for pointing out the non-existant world script event handler shipAttackedOther in the Scripters Cove. It was perfect for what I wanted. I say non-existant because I rely too much on the wiki for reference and that isn't listed. I keep meaning to add it.

EDIT - shipAttackedOther added to the wiki in the Image world script event handlers section.
Rocketman
Poor
Poor
Posts: 5
Joined: Wed Sep 19, 2012 11:28 am

Re: AI Trading Assistant OXP ver 1.9

Post by Rocketman »

Wow! I did not expect such extensive and detailed answer. Thank you very much!
Wildeblood wrote:
In any case it's a variable or pointer that holds a reference to the frame callback, so you can later tell Oolite which frame callback to remove.
So I did not err on that. Reference for further removal purposes. Ok.
Wildeblood wrote:
As far as I know, this means worldScripts["Trading Assistant"], so this.$monitorManifest means worldScripts["Trading Assistant"].$monitorManifest, and this.$getManifest means worldScripts["Trading Assistant"].$getManifest.
As a newbie I'am not yet familiar with project architecture. So it is difficult to figure out who is owner in this case. And to be honest, I have no much experience with JS scripting. Now things became much more clear. Thank you.
Wildeblood wrote:
addFrameCallback() is an Oolite global method that copies a function to over there somewhere
Oh, that a case! So it moves function to another entity, which means - to another scope. I thought it gives caller reference (or pointer - do not know exact term in english) to address specified procedure, which than acts in its native scope. Now I understend. Thanks again!
Wildeblood wrote:
bind() is a javascript method which sets the scope of another function/method.
Somehow I did not guess that .bind() is basic JS method and thought it refers to Oolite project. Thats why didn't try to find it in JS manuals. It was stupid, I'am sorry... :oops:
Wildeblood wrote:
You're asking, why write addFrameCallback(this.$monitorManifest.bind(this)), and not simply addFrameCallback(this.$monitorManifest).addFrameCallback(this.$monitorManifest.bind(this)) means addFrameCallback(worldScripts["Trading Assistant"].$monitorManifest.bind(worldScripts["Trading Assistant"])), that is when copying $monitorManifest for the frame callback, its execution scope is set to worldScripts["Trading Assistant"].worldScripts["Trading Assistant"].$monitorManifest calls another function, this.$getManifest, intending to mean worldScripts["Trading Assistant"].$getManifest, which exists.Let's say the frame callback's ID is abc123. When $monitorManifest is copied over there, it would become abc123.$monitorManifest. When it called this.$getManifest - without the binding - it would be calling abc123.$getManifest, which does not exist.
As a true teacher born youre were, master! Indeed, Ways of the Oolite Scripting know I will soon quitely! :mrgreen:
Tricky wrote:
Long variable names makes the code easier to read an debug. Especially if the name is meaningful.
Agree!
Wildeblood wrote:
this.$thisVariableHoldsTheFrameCallbackTrackingIdentificationNumber
It is more likely not about VarName.length. It is about semantic distance between entity name and its purpose. So, Purpose! You forget purpose! Must add ToRemoveItLaterWhenPlayerLeavesMarket :D
Wildeblood wrote:
Why? I cringe at the thought someone might "examine" it. It's a very bad example, or a good example of what not to do under normal circumstances. It's all upside-down and inside-out, to make it easy for people with no interest in javascript to make changes without fear of breaking it.
Because it was seem short and simple OXP. I don't know any of them, so decided to start from this. It is not important is this OXP smoothy or not. I wanted to acquaint myself with project, its architecture, basics and so on. I am Elite Commander since 5 e.o. age, like this poject and now have some ideas to implement... So I don't think that imperfect code will scare me :)

And again: thanks for help!
Greyth
---- E L I T E ----
---- E L I T E ----
Posts: 286
Joined: Wed Feb 08, 2012 1:57 am

Re: AI Trading Assistant OXP ver 1.9

Post by Greyth »

Heh, that's a nice touch. I don't need a trading assistant as I know the prices and I just scoop, scoop, scoop it up as I mosey into a well. If I don't sell it the I can't scoop, scoop, scoop up any more. I need a cargo compactor? I've got a witchspace cargo hold but sometimes it goes on the blink and I've usually got slaves in it when it does. Some rescuer! :cry:

Oh! The bells! They made me a hunchback you know! :?
Oolite 1.76
Debian 6 : Ubuntu 12.04
NVidia 6200 : Radeon/AMD thang
Abit AN7 : Packard Bell TJ74
User avatar
Cpt
Dangerous
Dangerous
Posts: 104
Joined: Mon Sep 17, 2012 12:18 am
Location: Europe
Contact:

Re: AI Trading Assistant OXP ver 1.9

Post by Cpt »

BTW: It seems not to account for Similar Items in Hypercargo, letting me know how unprofitable my selling 10 computers were, when I have another 35 out back that I am just about to bring forth and sell...
Oolite is Ooheavy... Cpt says "Write on Commander"
<<My other spaceship is a Thargoid Pathfinder, from the wrong side of Riedquat >>
Post Reply