In-Development TradeDangerous: power-user trade optimizer

It also seems like the station's paying price is almost always within 25% of the asking price.

Code:
C:\Dev\Trade> sqlite3 data\TradeDangerous.db
.mode col
.head on

-- Build a list of stations where the station charges
-- more for an item that it will pay to buy it back.
-- Also calculate the percentage of the asking price
-- (how much the station charges) of the diff.
DROP TABLE IF EXISTS t_differences;
CREATE TEMPORARY TABLE t_differences AS
SELECT	sys.name, stn.name, itm.name,
		sb.price as from_station,
		ss.price as to_station,
		ss.price - sb.price AS diff,
		(ss.price - sb.price) * 100 / ss.price AS pct
  FROM	Item as itm
  		INNER JOIN StationSelling AS ss
  			USING (item_id)
  		INNER JOIN StationBuying AS sb
  			USING (station_id, item_id)
  		INNER JOIN Station AS stn
  			USING (station_id)
  		INNER JOIN System AS sys
  			USING (system_id)
 WHERE  ss.price > sb.price
;

-- List the p99.9
DROP TABLE IF EXISTS t_p999;
CREATE TEMPORARY TABLE t_p999 AS
SELECT 'p99.9 of percentages is:', pct FROM t_differences ORDER BY pct LIMIT 1
OFFSET (SELECT COUNT(*) FROM t_differences) * 999 / 1000 - 1;
SELECT * FROM t_p999;

-- List the items > the 99.9
SELECT * FROM t_differences WHERE pct > (SELECT pct from t_p999) ORDER BY pct ASC;

produces:

Code:
p99.9 of percentages is:    25

name        name:1         name:2      from_station  to_station  diff        pct
----------  -------------  ----------  ------------  ----------  ----------  ----------
Breksta     Barcelos City  Scrap       23            33          10          30
Hahgwe      Skripochka Ho  Tantalum    4063          6108        2045        33
70 Ophiuch  Luk Station    Semiconduc  583           906         323         35
Gulngaba    Galindo Dock   Indite      1843          2883        1040        36
Lu Yupik    Bagian Survey  Supercondu  3761          6834        3073        44
Kivah       Sadi Carnot R  Uraninite   479           906         427         47
Mirdi       Mcdivitt Sett  Biowaste    15            50          35          70
HIP 72353   Caidin Statio  Beryllium   7677          76770       69093       90

So - the first one, well that seems feasible.

The one for Biowaste at Mirdi mcdivitt ... If someone can check that?

For now, I think I'll set a 25% threshold and if you type something over that I'll ask you to confirm.
 
Ok - if you try to enter a price with a >25% difference between "paying" and "asking", or the difference is more than 127 cr, it'll ask you for confirmation. Click OK and it'll let you proceed.

I make no assurances that the wording of the dialog boxes is not snarky :)
 
Dear friends,

I am having some issues trying to run the program.
Does anyone know what is happening ?

Code:
C:\tradedangerous>[COLOR=#E4E4E4]trade.py run -vv --sh type6 --ho 5 --fr Dahan --cr 128871 --ins 20000[/COLOR]
Traceback (most recent call last):
  File "C:\tradedangerous\trade.py", line 72, in <module>main(sys.argv)
  File "C:\tradedangerous\trade.py", line 45, in maintdb = tradedb.TradeDB(cmdenv, load=cmdenv.wantsTradeDB)
  File "C:\tradedangerous\tradedb.py", line 321, in __init__self.reloadCache()
  File "C:\tradedangerous\tradedb.py", line 396, in reloadCachecache.buildCache(self, self.tdenv)
  File "C:\tradedangerous\cache.py", line 782, in buildCacheprocessImportFile(tdenv, tempDB, Path(importName), importTable)
  File "C:\tradedangerous\cache.py", line 666, in processImportFileif deprecationFn: deprecationFn(linein, tdenv.debug)
UnboundLocalError: local variable 'deprecationFn' referenced before assignment

Thanks for the help !!!
 
Last edited:
I've just added "--start-jumps" (-s) and "--empty-ly" to the "run" sub-command.

Think of start-jumps as a "yeah, and check places nearby before you tell me to take another load of 20 algae to the other side of the system"...

Code:
$ trade.py run --from beagle2 --start-jumps 2 ...

This is going to try runs that start at beagle2, any other station in the Asellus System, or any system that could be reached from Beagle 2 with 2 or less jumps.

--empty-ly is where the win kicks in

It's easy to get stuck in little stagnant pockets; TD keeps finding cargos for you to run but by loading up with cargo, you can't jump far enough to leave.

When you combine this with -s,

Code:
$ trade.py run --from beagle2 -s 2 --ly 8.56 --empty 15 ...

Now TD can break out of the backwater and get you back to high-profit trading.

Practical example:

Code:
$ trade.py run -vv --ly 8.92 --empty 15.55 --cap 20 --cr 184124 --from cenker --start-jumps 3 --jumps 4
MOKOSH/Bethe Station -> LTT 15449/Barry Terminal:
  Load from MOKOSH/Bethe Station:
       20 x Superconductors      6,277cr each,    125,540cr total
  Jump MOKOSH -> ROSS 709 -> V775 HERCULI => Gain 25,280cr (1,264cr/ton) => 209,404cr
  Load from V775 HERCULI/Beatty Port:
       16 x Palladium           12,784cr each,    204,544cr total
        4 x Cobalt                 557cr each,      2,228cr total
  Jump V775 HERCULI -> ROSS 709 -> LTT 15449 => Gain 24,384cr (1,219.2cr/ton) => 233,788cr
  ----------------------------------------------------------------------------
  Finish at LTT 15449/Barry Terminal gaining 49,664cr => est 233,788cr total

Because there's no profitable trade Halai/Canker<->Mokosh/Bethe, TD would normally be unable to hook me up with this lucrative little trade run just one hop away from where I logged in.

This is now checked in to the master branch.
 
Hi guys, I'm having issues trying to get this tool to run. I have Python 3.4 installed, C:\Python34\, C:\Python34\Scripts and C:\Python34\Lib are set in my %PATH%, and the tool throws this error when I try to run it:

Code:
Traceback (most recent call last):
  File "C:\Users\Goof\Desktop\Elite trading tools\TD\trade.py", line 34, in <module>
    from commands import * 
  File "C:\Users\Goof\Desktop\Elite trading tools\TD\commands\__init__.py", line 4, in <module>
    import pathlib
ImportError: No module named pathlib

If it helps, this is the TradeDangerous 'install' dir:


There is a pathlib.py file present in the C:\Python34\Lib directory. I know I've likely missed something obvious, but can anyone help me in fixing this issue?

EDIT: I ran the help command in python, and it spat this out:

Code:
To get a list of available modules, keywords, symbols, or topics, type
"modules", "keywords", "symbols", or "topics".  Each module also comes
with a one-line summary of what it does; to list the modules whose name
or summary contain a given string such as "spam", type "modules spam".

help> modules

Please wait a moment while I gather a list of all available modules...

__future__          antigravity         html                select
_ast                argparse            http                selectors
_bisect             array               idlelib             setuptools
_bootlocale         ast                 imaplib             shelve
_bz2                asynchat            imghdr              shlex
_codecs             asyncio             imp                 shutil
_codecs_cn          asyncore            importlib           signal
_codecs_hk          atexit              inspect             site
_codecs_iso2022     audioop             io                  smtpd
_codecs_jp          base64              ipaddress           smtplib
_codecs_kr          bdb                 itertools           sndhdr
_codecs_tw          binascii            json                socket
_collections        binhex              keyword             socketserver
_collections_abc    bisect              lib2to3             sqlite3
_compat_pickle      builtins            linecache           sre_compile
_csv                bz2                 locale              sre_constants
_ctypes             cProfile            logging             sre_parse
_ctypes_test        calendar            lzma                ssl
_datetime           cgi                 macpath             stat
_decimal            cgitb               macurl2path         statistics
_dummy_thread       chunk               mailbox             string
_elementtree        cmath               mailcap             stringprep
_functools          cmd                 marshal             struct
_hashlib            code                math                subprocess
_heapq              codecs              mimetypes           sunau
_imp                codeop              mmap                symbol
_io                 collections         modulefinder        symtable
_json               colorsys            msilib              sys
_locale             compileall          msvcrt              sysconfig
_lsprof             concurrent          multiprocessing     tabnanny
_lzma               configparser        netrc               tarfile
_markerlib          contextlib          nntplib             telnetlib
_markupbase         copy                nt                  tempfile
_md5                copyreg             ntpath              test
_msi                crypt               nturl2path          textwrap
_multibytecodec     csv                 numbers             this
_multiprocessing    ctypes              opcode              threading
_opcode             curses              operator            time
_operator           datetime            optparse            timeit
_osx_support        dbm                 os                  tkinter
_overlapped         decimal             parser              token
_pickle             difflib             pathlib             tokenize
_pyio               dis                 pdb                 trace
_random             distutils           pickle              traceback
_sha1               doctest             pickletools         tracemalloc
_sha256             dummy_threading     pip                 tty
_sha512             easy_install        pipes               turtle
_sitebuiltins       email               pkg_resources       turtledemo
_socket             encodings           pkgutil             types
_sqlite3            ensurepip           platform            unicodedata
_sre                enum                plistlib            unittest
_ssl                errno               poplib              urllib
_stat               faulthandler        posixpath           uu
_string             filecmp             pprint              uuid
_strptime           fileinput           profile             venv
_struct             fnmatch             pstats              warnings
_symtable           formatter           pty                 wave
_testbuffer         fractions           py_compile          weakref
_testcapi           ftplib              pyclbr              webbrowser
_testimportmultiple functools           pydoc               winreg
_thread             gc                  pydoc_data          winsound
_threading_local    genericpath         pyexpat             wsgiref
_tkinter            getopt              queue               xdrlib
_tracemalloc        getpass             quopri              xml
_warnings           gettext             random              xmlrpc
_weakref            glob                re                  xxsubtype
_weakrefset         gzip                reprlib             zipfile
_winapi             hashlib             rlcompleter         zipimport
abc                 heapq               runpy               zlib
aifc                hmac                sched

Enter any module name to get more help.  Or, type "modules spam" to search
for modules whose name or summary contain the string "spam".

help>

EDIT: I'm stupid, you need to type 'python trade.py' in the command line, not just 'trade.py' :p
 
Last edited:
On the latest e31b7eba3cf5 version GUI is broken :(
Code:
File commands/update_gui.py line 541 in createWidgets
cur.execute(stmt, [station.ID])
sqlite3.OperationalError: no such column: item.ui_order

Edit: Looks like the database format has changed. I needed to recreate the database via import.
 
Last edited:
I've just added "--start-jumps" (-s) and "--empty-ly" to the "run" sub-command.

Think of start-jumps as a "yeah, and check places nearby before you tell me to take another load of 20 algae to the other side of the system"...

Code:
$ trade.py run --from beagle2 --start-jumps 2 ...

This is going to try runs that start at beagle2, any other station in the Asellus System, or any system that could be reached from Beagle 2 with 2 or less jumps.

--empty-ly is where the win kicks in

It's easy to get stuck in little stagnant pockets; TD keeps finding cargos for you to run but by loading up with cargo, you can't jump far enough to leave.

When you combine this with -s,

Code:
$ trade.py run --from beagle2 -s 2 --ly 8.56 --empty 15 ...

Now TD can break out of the backwater and get you back to high-profit trading.

Practical example:

Code:
$ trade.py run -vv --ly 8.92 --empty 15.55 --cap 20 --cr 184124 --from cenker --start-jumps 3 --jumps 4
MOKOSH/Bethe Station -> LTT 15449/Barry Terminal:
  Load from MOKOSH/Bethe Station:
       20 x Superconductors      6,277cr each,    125,540cr total
  Jump MOKOSH -> ROSS 709 -> V775 HERCULI => Gain 25,280cr (1,264cr/ton) => 209,404cr
  Load from V775 HERCULI/Beatty Port:
       16 x Palladium           12,784cr each,    204,544cr total
        4 x Cobalt                 557cr each,      2,228cr total
  Jump V775 HERCULI -> ROSS 709 -> LTT 15449 => Gain 24,384cr (1,219.2cr/ton) => 233,788cr
  ----------------------------------------------------------------------------
  Finish at LTT 15449/Barry Terminal gaining 49,664cr => est 233,788cr total

Because there's no profitable trade Halai/Canker<->Mokosh/Bethe, TD would normally be unable to hook me up with this lucrative little trade run just one hop away from where I logged in.

This is now checked in to the master branch.

If I'm understanding this correctly, --empty-ly is only valid when --start-jumps also used? The switches are telling trade.py to find alternative starting points that are 'start-jumps' jumps away at 'empty-ly' maximum per jump?

It would be good if trade.py also told us how to get to the new starting point...
 
I think that has to do with how you installed it; it always works without the python prefix for me...

Ditto ^^^

You're right, I installed python and TD on my laptop (windows 8) and it works fine typing 'trade'...

Not sure what the issue on the win7 machine is, oh well, I'll likely only use it on the laptop anyway.

Great work on what really is a fantastic tool btw, plus it's fast as well ^_^
 
If I'm understanding this correctly, --empty-ly is only valid when --start-jumps also used? The switches are telling trade.py to find alternative starting points that are 'start-jumps' jumps away at 'empty-ly' maximum per jump?

*Currently* its the only thing using it, because I only just added it.

And -s will use empty if provided, otherwise fallback to --

It would be good if trade.py also told us how to get to the new starting point...

[tounge-in-cheek] that's what 'nav' is for :)

I didn't add this yet because the trade output has gotten a little noisy already.

It definitely needs adding to the --checklist output, but I'd like to do a pass on the presentation of the nav command before I add more output to it :)
 
You're right, I installed python and TD on my laptop (windows 8) and it works fine typing 'trade'...

Not sure what the issue on the win7 machine is, oh well, I'll likely only use it on the laptop anyway.

Great work on what really is a fantastic tool btw, plus it's fast as well ^_^

I think it has to do with whether you installed it for all users or not, but I don't recall.

I use a bunch of wrapper scripts around TD these days, but I don't share them because they are bash scripts (I install msysgit to get the bash shell instead of windows command line).

But they're simple enough that I can probably convert them to powershell commands which would probably make life a lot easier for some people.
 
Here's some output I wasn't expecting

Code:
>trade.py run -vvv --ship cobra --insurance 56500 --ly-per 9.18 --jumps-per 2 --hops 3 --capacity 29 --credits 363781 --to salgari --via Cormack,pord  --from "Al-Farabi"
MCC 858/Al-Farabi Port -> YARIGUI/Walker Ring:
Start CR:    307,281
Hops    :          3
Jumps   :          3
Gain CR :     32,973
Gain/Hop:     10,991
Final CR:    340,254


  Load from MCC 858/Al-Farabi Port:
       29 x Indium           5,476cr each,    158,804cr total
  Jump MCC 858 -> NLTT 53889 => Gain 13,282cr (458cr/ton) => 320,563cr
  Load from NLTT 53889/Pordenone Port:
       29 x Tea              1,508cr each,     43,732cr total
  Jump NLTT 53889 -> TRIPU => Gain 9,599cr (331cr/ton) => 330,162cr
  Load from TRIPU/Cormack Vision:
       29 x Bertrandite      2,572cr each,     74,588cr total
  Jump TRIPU -> YARIGUI => Gain 10,092cr (348cr/ton) => 340,254cr
  ----------------------------------------------------------------------------
  Finish at YARIGUI/Walker Ring gaining 32,973cr => est 340,254cr total

I asked it to end at Salgai, but it ended at Walker. They are in the same system however.

Is there a way to force TD to use the via order in sequence? I've been thinking it would be good to use it for 'go fetch' missions. For example, I'm at X, I've got missions that need me to take things to Y and Z, but I need to get the stuff for Y from A, and the stuff for Z from B. I'd like to be able to do something like

Code:
trade.py run --from X --to Z --via A,Y,B

and let TD decide what else would be profitable to carry. The risk at present is that TD may decide to visit Y before A.
 
On the latest e31b7eba3cf5 version GUI is broken :(
Code:
File commands/update_gui.py line 541 in createWidgets
cur.execute(stmt, [station.ID])
sqlite3.OperationalError: no such column: item.ui_order

Edit: Looks like the database format has changed. I needed to recreate the database via import.

Hmm - weird. It should have seen the .SQL file change and done it automatically.

You don't need an import, just "trade.py buildcache -f".

-Oliver

- - - - - Additional Content Posted / Auto Merge - - - - -

Here's some output I wasn't expecting

Code:
>trade.py run -vvv --ship cobra --insurance 56500 --ly-per 9.18 --jumps-per 2 --hops 3 --capacity 29 --credits 363781 --to salgari --via Cormack,pord  --from "Al-Farabi"
MCC 858/Al-Farabi Port -> YARIGUI/Walker Ring:
Start CR:    307,281
Hops    :          3
Jumps   :          3
Gain CR :     32,973
Gain/Hop:     10,991
Final CR:    340,254


  Load from MCC 858/Al-Farabi Port:
       29 x Indium           5,476cr each,    158,804cr total
  Jump MCC 858 -> NLTT 53889 => Gain 13,282cr (458cr/ton) => 320,563cr
  Load from NLTT 53889/Pordenone Port:
       29 x Tea              1,508cr each,     43,732cr total
  Jump NLTT 53889 -> TRIPU => Gain 9,599cr (331cr/ton) => 330,162cr
  Load from TRIPU/Cormack Vision:
       29 x Bertrandite      2,572cr each,     74,588cr total
  Jump TRIPU -> YARIGUI => Gain 10,092cr (348cr/ton) => 340,254cr
  ----------------------------------------------------------------------------
  Finish at YARIGUI/Walker Ring gaining 32,973cr => est 340,254cr total

I asked it to end at Salgai, but it ended at Walker. They are in the same system however.

Hrm. Can you post an issue with this info - that looks like I screwed the pooch on handling end systems.

Is there a way to force TD to use the via order in sequence? I've been thinking it would be good to use it for 'go fetch' missions. For example, I'm at X, I've got missions that need me to take things to Y and Z, but I need to get the stuff for Y from A, and the stuff for Z from B. I'd like to be able to do something like

Code:
trade.py run --from X --to Z --via A,Y,B

and let TD decide what else would be profitable to carry. The risk at present is that TD may decide to visit Y before A.

No, but that doesn't sound terribly difficult. Can you post a suggestion on the issues page? (http://kfs.org/td/issues)

(Sorry, I'd post the issues myself but I'm running out of time tonight :)
 
i was updating market for Ali Ring in Kokojina system and was asked by TradeDangerous to post screenshots for 4 itens.
Here they are:

Consumer Technology
View attachment 3731

Superconductors
View attachment 3732

Performance Enhancers and Progenitor Cells
View attachment 3733

Thanks! I've increased the margin a little for higher-priced items, please go ahead and grab the latest version.

- - - - - Additional Content Posted / Auto Merge - - - - -

v6.1.7 with scripts

Several people have asked if they can have the scripts I've been using to make TD easier to run myself.

Unfortunately, these are bash scripts which means they work on a Linux or Mac box but Windows users will need to install "bash" - the easiest way to do that is to install "msysgit". I refer to this as "git bash" because I hit the Windows key and type "git" to access it.

As of v6.1.7 you'll find a "scripts" directory, which includes a README.txt. These are my scripts.

They're nothing special, the only "magic" is that there's a "config.sh" which you copy into the same folder as "trade.py" and then edit with YOUR settings.

This saves me a TON of typing. I put my current ship setup into that file and then instead of

Code:
$ trade.py run --cap 20 --ly 12.6 --empty 20.4 --jumps 6 --cr 204293 --from halai --to ibootis

I can just type:

Code:
$ tdrun halai

WOOSH.

The scripts are: tdbuyfrom, tdimad, tdloc, tdnav, tdrun and tdupd.

Again, see the scripts/README.txt for more details.

Just remember: When you tweak your ship, edit your config.sh (not the one in the scripts dir, but the main dir)
 
Last edited:
Back
Top Bottom