Trading bot construction (IB)

Discussion in 'Automated Trading' started by doli, Jan 9, 2007.

  1. doli

    doli

    retrying the attachment ...

    It made it, and reading it, I realized that
    the assertions about the
    'hours', 'minutes' and 'seconds' of 'open' and
    'close' should occur before
    RandomTime(open, close) is ever called.

    edit: the assertions are OK where they are, too
     
    #61     Feb 1, 2007
  2. doli

    doli

    After some more testing, I found that
    a trade at the very start of trading hours,
    09:30:00 for example, can't be generated. The fix is:
    Code:
        RandomTime(RandomTime open, RandomTime close) {
    
            calls++;
    
            while (true) {
    
                hours = nextInt(close.hours);
                minutes = nextInt(close.minutes);
                seconds = nextInt(close.seconds);
    
                // Does the time fall within exchange hours?
                if (
                    (isGreaterThan(this, open) || isEqualTo(this, open)) &&
                    isLessThan(this, close)
                   )
                    break;
                else
                    continue;
            }
        }
    
    That is in randTime.java
     
    #62     Feb 1, 2007
  3. doli

    doli

    re: "After thinking some more about extending Random,
    it occurred to me that an extension of Random,
    in order to fit with what Random offers, should
    offer a nextRandomTime method, but the bot
    doesn't need that functionality." Yet it could be done
    with such a method: the bot would need to constrain a
    value generated by nextRandomTime, assuming that
    nextRandomTime() generated a time from 00:00:00
    to 23:59:59, inclusive. Constraining the time would
    involve throwing away generated values until
    one that fell within trading hours was obtained.

    The current RandomTime(t0, t1), with the latest
    fix, appears to generate a time such that
    t0 <= time < t1. It might be easier to write trading hour
    constraints if RandomTime(t0, t1) generated a time such that
    t0 <= time <= t1. So that a constraint that the bot only
    trades the first 15 minutes of the market could be written
    09:30:00 to 09:45:00 instead of 09:30:00 to 10:46:01. That
    strange use of t1 is due to the direct use of the
    closing-time-constraint's hour, minute and second values as
    arguments to Random.nextInt(). It looks as though an easier
    way to write a closing time constraint would be possible if
    RandomTime(t0, t1) simply passed to nextInt() t1's hour, minute
    and second values incremented by 1: if it gets a constraint of
    09:45:00, it could simply use 10, 46 and 1 as arguments to nextInt().
    Is it that easy?

    By the way, I have been using Java SE 6. (1.6?)
    It's the latest and was recently released.
    A lot of Java class/method documentation can be found at
    http://java.sun.com/javase/6/docs/api/
     
    #63     Feb 1, 2007
  4. doli

    doli

    chameleontrader: thanks for the link.
    I looked through the code and will download and
    try it. Some interesting things were in
    places like chart, strategy, virtual tws -- a great
    idea -- Trader.java and TradingSchedule.java.
    It may be that random trading could be plugged
    into it as a strategy.

    In thinking about main's loop in randTime.java,
    particularly how to incorporate that into RandomBot,
    I looked into a problem. I may have mentioned
    that RandomBot has to start before the time
    specified by 'open' in Main.java. The reason is
    that if it runs at a later time, 'now' in the 'run'
    method occurs after main's 'open', which is
    run's 'start'. When that happens, the arguments
    to Thread.sleep may be less than zero, which
    will cause an exception. The reason is that 'run'
    may get an 'entry' time before 'now'. The solution
    may be to have 'main' determine 'now' and
    provide it to 'RandomBot' via its 'setStart' method,
    eliminating the computation of 'now' in 'RandomBot'.
    With that done, it appears that 'RandomBot'
    would trade at a time relative, positive, to the
    time that 'main' finds for 'now'. Another thing
    that main's loop might need to do is determine
    whether there is enough time betwen 'now' and
    'close' to do a trade.

    Yet another problem with looping over the
    'RandomBot' constructor in 'main' is that,
    as is, the bot to tws connecion won't persist.
    If that is a problem, then a possible solution
    may be to have 'main' set-up the connection.

    Another thing: Is it alright if the bot's entry and
    exit times are the same? There is now a requirement
    that they be different. Would the bot's 'run' method break
    if entry and exit were the same time?

    Added: It should be possible to get the bot
    to trade at a random time in a random interval.
    Would that be useful? The random interval
    could be found by 'main', which would set
    the bot's stop time as well as its start time.
     
    #65     Feb 2, 2007
  5. doli

    doli

    I've attached a new randTime.java, in randtime.txt.
    It appears that trade entry and exit times are computed correctly,
    so I think that the bot's random-trading strategy is ready.
    The random number generator hasn't been evaluated; however, it is
    one that generates a long sequence and doesn't appear to begin at
    the same point in its sequence (Is the Java runtime seeding it?).

    What has changed:

    1. A logger has been added.

    2. The entry time is permitted to be the same as the exit time.

    3. It is easier to write the 'close' portion of market hours.

    4. Time comparisons have been simplified.

    5. Some names have been changed, e.g., isLessThan became isEarlierThan.

    6. main's loop now trades as much as possible between 'open' and 'close'.

    7. Recognized bugs/oversights were corrected. Some may remain.


    Notes:

    1. It is set up to "trade" the first 15 minutes after it starts.
    It can also trade some other session if the 'open' and 'close'
    in main are set-up for that session.

    2. I'll need to retrofit what is in the attachment into RandomTime.java,
    RandomBot.java and Main.java. I'll also need to create a new file, Logger.java.

    3. Once the bot is working with tws again, there may be an issue with
    main's looping over the RandomBot constructor.

    3. After no. 2 & 3, above, some code will be needed to submit an order.

    4. The bot will need to know whether its orders get filled.

    5. Once the bot can place an order, there will be additional considerations:
    The bot is allowed to enter and exit at the same time -- enter,
    then immediately exit. Should the bot wait for order status/confirmation?
    How long does that take? Is there a worst-case status/confirmation time?
    One second, two seconds, five minutes? What can go wrong here? Note:
    the bot will use market orders, but these things will still need to be
    considered. The point is that requiring some time between the entry and
    exit orders won't eliminate the potential problems -- although it could
    reduce the number of times they occur -- unless brokers/exchanges guarantee
    worst-case trading times.

    6. Once the bot can submit orders, it is important to have the machine
    sync'd up with broker/exchange time.

    7. Another thing that will have to be done is a consideration of what
    exceptions can occur. Which can occur? For each: How does the exception
    flow through the bot? Can it be prevented from occurring? What must the bot do
    if the exception occurs? Is "catch (Exception e)" too broad? Also, the bot may
    intentionally generate exceptions; if it does so, does it handle them correctly?
    This will require considerable effort; reading through the JSystemtrader code
    may provide some insights.

    8. There may be a synchronization issue (jumbled output) with the logger,
    if its methods can be invoked by more than one thread.

    9. The strategy deals in one second increments. Does a trade always occur
    at the scheduled second? Could it occur a second -- maybe more -- later?
    Could this be a problem? Can we guarantee any sort of worst-case delay?
    If not, and if a delay is a problem, how could the risk of this occurring be
    reduced?

    10. Note that if the 'seconds' part of 'close' (in main's preliminaries) is 'n',
    then the 'seconds' part of every exit/entry time will be <= 'n'. A 'close' of
    XX:XX:59 may be best. Is this a bug or a feature?
     
    #66     Feb 3, 2007
  6. doli

    doli

    attachment retry ...
     
    #67     Feb 3, 2007
  7. doli

    doli

    re: "Note that if the 'seconds' part of 'close' (in main's preliminaries) is 'n',
    then the 'seconds' part of every exit/entry time will be <= 'n'. A 'close' of
    XX:XX:59 may be best. Is this a bug or a feature?"
    One implication of this may be that if XX:XX:00 is
    specified, then the RandomTime(t0,t1) constructor
    will only generate times on the minute, i.e., the
    'seconds' part of every generated time will always
    be zero. Wouldn't, given XX:00:00, the constructor
    always generate times on the hour? I think that is
    the case and will test it. If this is happening, it probably
    isn't what someone would expect -- if someone
    wanted to random-trade the 1st half hour, then
    they might reasonably ask for a time from
    09:30:00 to 10:00:00, which may only generate
    10:00:00. I just tried and believe that this is
    happening, and while trying found a bug in the commented-out
    code, early in 'main', that trades the day session.
    It should read:
    Code:
            // Trade the day session (MST)
            RandomTime open = new RandomTime(3, 30, 0);
            RandomTime close = new RandomTime(4, 0, 0);
    
    (It contained 'RandomTime.open' and didn't ask
    for a "new" one).
    I do see it only trading at 04:00:00. This can be
    fixed: in RandomTime(t0,t1),
    ask for a 'nextRandomTime', which should
    provide a time from 00:00:00 and 23:59:59,
    inclusive, repeatedly until it does provide
    a time from t0 to t1, inclusive. Shorter periods
    may require more trips to 'nextRandomTIme', in
    order to find a suitable value, than longer periods require.
    As is, it can be
    used to trade between [09:30:00 and 10:00:00) by
    initializing 'close' with 09:59:59. Is there a better
    fix than 'nextRandomTime'?

    That's the second problem that using the
    'close' values as arguments to 'nextInt' has
    created. It was too easy: a no brainer. It may
    have been used that way because I was thinking
    about running the bot over the full day session,
    until XX:XX:59, which would permit every random
    second before the close at XX:XX:00 to be generated.
     
    #68     Feb 4, 2007
  8. doli

    doli

    I've attached a new randTime.java, in randtime.txt,
    which fixes the problem mentioned last.
    Here is the log output for a session between 05:30:00 and 06:00:00, started about 05:35:
    Code:
    05:34:04 Bot.run: round-trip interval begins at 05:34:04, ends at 06:00:00
    05:34:04 Bot.run: scheduling entry/exit for 05:34:40/05:42:12
    05:34:40 Bot.run: entering market (buying)
    05:42:12 Bot.run: exiting market (selling)
    05:42:12 DEBUG: main: 108 calls of nextRandomTime()
    05:42:12 Bot.run: round-trip interval begins at 05:42:12, ends at 06:00:00
    05:42:12 Bot.run: scheduling entry/exit for 05:55:20/05:59:47
    05:55:20 Bot.run: entering market (buying)
    05:59:47 Bot.run: exiting market (selling)
    05:59:47 DEBUG: main: 523 calls of nextRandomTime()
    05:59:47 Bot.run: round-trip interval begins at 05:59:47, ends at 06:00:00
    05:59:47 Bot.run: scheduling entry/exit for 05:59:48/05:59:57
    05:59:48 Bot.run: entering market (selling)
    05:59:57 Bot.run: exiting market (buying)
    05:59:57 DEBUG: main: 25739 calls of nextRandomTime()
    
    Notice that the no. of calls to nextRandomTime()
    is increasing as the round-trip interval gets
    shorter. In the last interval, 9 seconds, there were
    25739 calls. Could nextRandomTime be optimized?

    In this fix, RandomTime no longer extends Random,
    so there is a "static rand = new Random()".
    I think that means that there will just be one
    Random -- is that so? I am a real Java newb,
    and this change is a consequence of the compiler
    refusing to let me call "non-static" methods from
    a "static" context. This may have started occurring
    when a lot of things began to be called from 'main', which is "static".
    Would I be better off if 'main' started a thread
    that did what 'main' now does? Would a new
    thread be a "non-static" context?
     
    #69     Feb 4, 2007
  9. doli

    doli

    I've retrofitted that last randTime.java into a bot and ended up
    with additional files: X.java, Logger.java and RandomBotMgr.java.
    It traded last night, several times, for 5 minute sessions and made
    a little money. I lost track of how many times it traded, so did the bot.
    Early on, I had to bail it out by manually trading after a session ended.
    Its not ready for prime time. Initially, it had a severe problem: it didn't
    wait for order status from TWS. I instrumented the code to get some kind of idea
    about how long it might take to get order status: 675 ms. is the worst-case,
    so far. A side-effect of instrumenting it was that it began to wait for
    order confirmation; however, it doesn't handle the case where confirmation
    doesn't arrive before the "timeout" occurs -- I think it looks for confirmation
    for as long as one second. Considering what can go wrong might suggest that the
    bot shouldn't trade too close to the end of a session, but what is "too close"
    to the session's end? The bot trades at times that are relative to the
    computed entry time -- how relative those times are depends on whatever
    delay may occur, whether in the bot, on the bot <-> TWS link, on the
    TWS <-> IB link or on the IB <-> exchange link.

    Logger.java contains things like 'timestamp', 'log', 'error', 'fatal', etc.,
    and it does "synchronized (Object) { }"; whether it needs to do so should be
    considered. Code in X.java can place an order, but just a canned buy or sell
    order for an ES contract that expires next month. RandomBot schedules the orders
    computed by RandomBotMgr. RandomBotMgr.java is essentially the code that is in
    randTime.java's 'main' method; it could be considered to be RandomBot's manager.
    RandomBot and RandomBotMgr are able to keep the order IDs straight, but there
    are additional considerations, which are concerned with how RandomBot and
    RandomBotMgr exchange information.

    How the bot flows: 'main' starts a RandomBotMgr thread, which decides whether
    the exchange is open and, if so, computes an exit and entry time, which are
    then handed off to a RandomBot thread, created by RandomBotMgr. RandomBotMgr
    opens and closes the connection between the bot and TWS for each session.
    RandomBot calls into EClientSocket to place an order, i.e., to send
    a message to TWS; EReader calls into RandomBotMgr when a message from TWS
    arrives, i.e., RandomBotMgr extends the "wrapper." I see that RandomBotMgr's
    code that handles EReader's calls should be placed into yet another file.

    These things aren't ready to be posted yet. It seems that as more gets done,
    more things that must be done are discovered.
     
    #70     Feb 5, 2007