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
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.
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-minI 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

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.
"""
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
formatter = logging.Formatter('%(asctime)s:%(levelname)s:%(message)s')
EDIT2: Changed call to base debug to use *arg instead of arg so is now
goxapi.BaseObject.debug(self, *args)
No more edits. Code is flawless

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
Price is also going down.... Time for tea