Post
Topic
Board Trading Discussion
Re: ncurses based MtGox live monitor and trading-bot-framework
by
MtQuid
on 30/04/2013, 17:24:31 UTC
EDIT: Also, can anyone give me a hint on how to create a separate debug file for my bot? The regular debug goxtool file gets too big and its very cumbersome to check.

To reduce debug clutter for writing strategies I use a crafty tail.  I did have a cut on the end but it lagged
Code:
tail -f goxtool.log| grep -E 'Strat|Trace|^[^0-9]'

Yeah, thats an option, but I still would preffer to have a different file so I can check it from time to time.

Quote
And how are the results?.

I just loaded the chart along with current data from bitcoin charts and they are pretty similar. 
http://bitcoincharts.com/charts/chart.json?m=mtgoxUSD&r=1&i=15-min
I don't know what weighted moving average function they are using but the data is close enough for my use though I probably should check it out on a few more days before I invest the yacht Cheesy
If you use this data you will need to alter the timestamp for HighStock.js  add on 000 (three zeros)

EDIT: I haven't checked for the 1 hour EMAs but will do some more testing and experimenting later.  Using the TA-Lib you can specify the timeperiod and then ignore those first timeperiod output values as the results settle down.  I've used the default values from bitcoincharts.  Simple at 10 and Weighted at 25.

Thanks for the direction, I will try using ta-lib between today and tomorrow, hopefully it gives better results that my manually created one (which its not difficult...).

I just put this together.
This will create a log file for each loaded strategy as well as sending log messages to the main log.
Maybe prof7bit could check it over and put it into the main source.
It's a quick hack but it works.
And you call self.debug() just like before and there is a new function self.info() for different log level.

Change Strategy.py to look like this.

Code:
"""
trading robot breadboard
"""

import goxapi
import logging


class Strategy(goxapi.BaseObject):
    # pylint: disable=C0111,W0613,R0201

    def __init__(self, gox):
        goxapi.BaseObject.__init__(self)
        self.signal_debug.connect(gox.signal_debug)
        gox.signal_keypress.connect(self.slot_keypress)
        gox.signal_strategy_unload.connect(self.slot_before_unload)
        gox.signal_ticker.connect(self.slot_tick)
        gox.signal_depth.connect(self.slot_depth)
        gox.signal_trade.connect(self.slot_trade)
        gox.signal_userorder.connect(self.slot_userorder)
        gox.orderbook.signal_owns_changed.connect(self.slot_owns_changed)
        gox.history.signal_changed.connect(self.slot_history_changed)
        gox.signal_wallet.connect(self.slot_wallet_changed)
        self.gox = gox
        self.name = "%s.%s" % \
            (self.__class__.__module__, self.__class__.__name__)

        self.logger = logging.getLogger(self.name)
        self.fh = logging.FileHandler(self.name + '.log')
        formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(message)s')
        self.fh.setFormatter(formatter)
        self.fh.setLevel(logging.DEBUG)
        self.logger.addHandler(self.fh)

        self.info("%s loaded" % self.name)

    def info(self, *args):
        """write info event to log.  use our logger then send to the base logger"""
        msg = " ".join([str(x) for x in args])
        self.logger.info(msg)
        goxapi.BaseObject.debug(self, *args)


    def debug(self, *args):
        """write debug event to log.  use our logger then send to the base logger"""
        msg = " ".join([str(x) for x in args])
        self.logger.debug(msg)
        goxapi.BaseObject.debug(self, *args)

    def __del__(self):
        """the strategy object will be garbage collected now, this mainly
        only exists to produce the log message, so you can make sure it
        really garbage collects and won't stay in memory on reload. If you
        don't see this log mesage on reload then you have circular references"""
        self.debug("%s unloaded" % self.name)
        self.logger.removeHandler(self.fh)

    def slot_before_unload(self, _sender, _data):
        """the strategy is about to be unloaded. Use this signal to persist
        any state and also use it to forcefully destroy any circular references
        to allow it to be properly garbage collected (you might need to do
        this if you instantiated linked lists or similar structures, the
        symptom would be that you don't see the 'unloaded' message above."""
        pass

    def slot_keypress(self, gox, (key)):
        """a key in has been pressed (only a..z without "q" and "l")"""
        self.debug("someone pressed the %s key" % chr(key))

    def slot_tick(self, gox, (bid, ask)):
        """a tick message has been received from the streaming API"""
        pass

    def slot_depth(self, gox, (typ, price, volume, total_volume)):
        """a depth message has been received. Use this only if you want to
        keep track of the depth and orderbook updates yourself or if you
        for example want to log all depth messages to a database. This
        signal comes directly from the streaming API and the gox.orderbook
        might not yet be updated at this time."""
        pass

    def slot_trade(self, gox, (date, price, volume, typ, own)):
        """a trade message has been received. Note that this signal comes
        directly from the streaming API, it might come before orderbook.owns
        list has been updated, don't rely on the own orders and wallet already
        having been updated when this is fired."""
        pass

    def slot_userorder(self, gox, (price, volume, typ, oid, status)):
        """this comes directly from the API and owns list might not yet be
        updated, if you need the new owns list then use slot_owns_changed"""
        pass

    def slot_owns_changed(self, orderbook, _dummy):
        """this comes *after* userorder and orderbook.owns is updated already.
        Also note that this signal is sent by the orderbook object, not by gox,
        so the sender argument is orderbook and not gox. This signal might be
        useful if you want to detect whether an order has been filled, you
        count open orders, count pending orders and compare with last count"""
        pass

    def slot_wallet_changed(self, gox, _dummy):
        """this comes after the wallet has been updated. You can access the
        new balance like so: gox.wallet["BTC"] or gox.wallet[gox.currency]"""
        pass

    def slot_history_changed(self, history, _dummy):
        """this is fired whenever a new trade is inserted into the history,
        you can also use this to query the close price of the most recent
        candle which is effectvely the price of the last trade message.
        Contrary to the slot_trade this also fires when streaming API
        reconnects and re-downloads the trade history, you can use this
        to implement a stoploss or you could also use it for example to detect
        when a new candle is opened"""
        pass

EDIT1: Changed formatter to
Code:
formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(message)s')
EDIT2: Changed call to base debug to use *arg instead of arg so is now
Code:
goxapi.BaseObject.debug(self, *args)
No more edits.  Code is flawless Cheesy
EDIT3: Need to remove file handler on strategy unload so that it is not reloaded twice or more during a strategy reload
I think that should do it now.  Code is never flawless Sad
Price is also going down.... Time for tea