Bitcoin Forum
April 24, 2024, 02:20:39 AM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 2 3 4 5 6 [7] 8 9 10 11 »  All
  Print  
Author Topic: ncurses based MtGox live monitor and trading-bot-framework  (Read 33817 times)
c0inbuster
Member
**
Offline Offline

Activity: 105
Merit: 10



View Profile WWW
April 27, 2013, 06:22:53 AM
 #121

Maybe price should be stored in Decimal http://docs.python.org/2/library/decimal.html

Download free softwares! - crypto mining profit calculator - crypto triangular arbitrage tools - crypto stocks tools...
https://sites.google.com/site/working4coins/
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction.
1713925239
Hero Member
*
Offline Offline

Posts: 1713925239

View Profile Personal Message (Offline)

Ignore
1713925239
Reply with quote  #2

1713925239
Report to moderator
1713925239
Hero Member
*
Offline Offline

Posts: 1713925239

View Profile Personal Message (Offline)

Ignore
1713925239
Reply with quote  #2

1713925239
Report to moderator
1713925239
Hero Member
*
Offline Offline

Posts: 1713925239

View Profile Personal Message (Offline)

Ignore
1713925239
Reply with quote  #2

1713925239
Report to moderator
Ban Curtain
Member
**
Offline Offline

Activity: 63
Merit: 10


View Profile
April 27, 2013, 12:46:14 PM
 #122

Id like to create hierarchy of strategies. The first strategy observes for a complex event and then emits signal which should be handled by slot of the second strategy. How is it better to implement?

As far as I understand to connect to a signal of a dummy emitter I must have access to instance of emitter, but while initializing strategies I have only instance of gox. Is it possible to get access to another strategies' instances?
prof7bit (OP)
Hero Member
*****
Offline Offline

Activity: 938
Merit: 500


https://youengine.io/


View Profile WWW
April 27, 2013, 01:03:50 PM
Last edit: April 27, 2013, 01:29:45 PM by prof7bit
 #123

Is it possible to get access to another strategies' instances?

Not in the current implementation, not when passing a list of strategies to the command line. But what you could do is to explicitly load a strategy from within another strategy. This "master strategy" could then load "slave strategies" in an exactly defined order and pass them references to itself or to each other in their constructors so they can refer to each other and then you could have your strategies communicate with custom signals or directly calling each other.

Edit: Another (maybe even better) solution would be that you pass the strategies to the command line in the right order so that the first strategy would be the one that wants to emit signals would simply create a new signal in the gox instance and all the other strategies that load after it would check if a member of that name exists in the gox instance and if it exists connect a slot to it.

Emitting Strategy:
In the constructor __init__ of the emitting strategy (that one should be loaded first) do the following to create the new the "signal_foo":
Code:
        gox.signal_foo = goxapi.Signal()

and to emit the signal you do something like this:
Code:
        self.gox.signal_foo(self, (42, 23))

Receiving Strategy:
in the constructor __init__ of the receiving strategies (these must appear *after* the above one on the command line) you add the following to detect the existence of the signal and connect a slot to it to it:
Code:
        if hasattr(gox, 'signal_foo'):
            gox.signal_foo.connect(self.slot_foo)

and a slot:
Code:
    def slot_foo(self, sender, data):
        """slot for custom foo signal"""
        (a, b) = data
        self.debug("foo signal detected: %g %g" %  (a, b))

That should do the trick, I just tested it and it works very well. If the emitter was not loaded then the slot will just never be called but it won't crash (you can add an else to the if to print a debug warning if that happens)

Ban Curtain
Member
**
Offline Offline

Activity: 63
Merit: 10


View Profile
April 27, 2013, 01:52:18 PM
 #124

Is it possible to get access to another strategies' instances?

Not in the current implementation, not when passing a list of strategies to the command line. But what you could do is to explicitly load a strategy from within another strategy. This "master strategy" could then load "slave strategies" in an exactly defined order and pass them references to itself or to each other in their constructors so they can refer to each other and then you could have your strategies communicate with custom signals or directly calling each other.

Edit: Another (maybe even better) solution would be that you pass the strategies to the command line in the right order so that the first strategy would be the one that wants to emit signals would simply create a new signal in the gox instance and all the other strategies that load after it would check if a member of that name exists in the gox instance and if it exists connect a slot to it.

Emitting Strategy:
In the constructor __init__ of the emitting strategy (that one should be loaded first) do the following to create the new the "signal_foo":
Code:
        gox.signal_foo = goxapi.Signal()

and to emit the signal you do something like this:
Code:
        self.gox.signal_foo(self, (42, 23))

Receiving Strategy:
in the constructor __init__ of the receiving strategies (these must appear *after* the above one on the command line) you add the following to detect the existence of the signal and connect a slot to it to it:
Code:
        if hasattr(gox, 'signal_foo'):
            gox.signal_foo.connect(self.slot_foo)

and a slot:
Code:
    def slot_foo(self, sender, data):
        """slot for custom foo signal"""
        (a, b) = data
        self.debug("foo signal detected: %g %g" %  (a, b))

That should do the trick, I just tested it and it works very well. If the emitter was not loaded then the slot will just never be called but it won't crash (you can add an else to the if to print a debug warning if that happens)


Thank you, I gonna try the solution you recommend.
prof7bit (OP)
Hero Member
*****
Offline Offline

Activity: 938
Merit: 500


https://youengine.io/


View Profile WWW
April 29, 2013, 03:09:44 PM
 #125

goxtool.py can now display a depth chart. Also it has grouping in the orderbook and optionally adding up the totals:

git pull

there are a lot of new keyboad shortcuts to control all this,
I have added them to the manual: http://prof7bit.github.io/goxtool/

Screenshot:

ErebusBat
Hero Member
*****
Offline Offline

Activity: 560
Merit: 500

I am the one who knocks


View Profile
April 29, 2013, 03:26:35 PM
 #126

Thanks prof7bit!

Question:  what do the yellow Os indicate?


░▒▓█ Coinroll.it - 1% House Edge Dice Game █▓▒░ • Coinroll Thread • *FREE* 100 BTC Raffle

Signup for CEX.io BitFury exchange and get GHS Instantly!  Don't wait for shipping, mine NOW!
prof7bit (OP)
Hero Member
*****
Offline Offline

Activity: 938
Merit: 500


https://youengine.io/


View Profile WWW
April 29, 2013, 03:29:07 PM
 #127

Thanks prof7bit!

Question:  what do the yellow Os indicate?


They are your own orders. If you zoom out the orderbook (- key) you will see them there too

ErebusBat
Hero Member
*****
Offline Offline

Activity: 560
Merit: 500

I am the one who knocks


View Profile
April 29, 2013, 03:32:59 PM
 #128

They are your own orders. If you zoom out the orderbook (- key) you will see them there too
Oh, awesome!  Thanks!

░▒▓█ Coinroll.it - 1% House Edge Dice Game █▓▒░ • Coinroll Thread • *FREE* 100 BTC Raffle

Signup for CEX.io BitFury exchange and get GHS Instantly!  Don't wait for shipping, mine NOW!
MtQuid
Newbie
*
Offline Offline

Activity: 24
Merit: 0



View Profile
April 29, 2013, 06:59:32 PM
Last edit: April 29, 2013, 11:13:53 PM by MtQuid
 #129

I'm not very interested by you "speaker" strategy ... for now... but maybe one day it could be useful...

I tried to play with a Python wrapper for TA-Lib
http://ta-lib.org/
http://mrjbq7.github.io/ta-lib/
this wrapper is total...
you just need to install cython, TA-Lib, and this wrapper


I just tried this out and wanted to plot the results so I dumped the data to some files and used Highstock.js to render the view.

Code:
import goxapi
from goxapi import OHLCV
import datetime
import numpy as np
import talib
import json

class OHLCV_Encoder(json.JSONEncoder):
    """JSONEncoder for class OHLCV()"""
    def default(self, obj):
        if isinstance(obj, OHLCV):
            return [obj.tim, obj.opn, obj.hig, obj.low, obj.cls, obj.vol]
        else:
            return json.JSONEncoder.default(self, obj)

class Strategy(goxapi.BaseObject):
    ........
    ........

    def slot_keypress(self, gox, (key)):
        if key == ord("t"):
            """testing talib"""       
            candles = []

            for c in reversed(self.gox.history.candles):
                candles.append(
                    OHLCV(
                        # fix time for HighStock.js JSON import
                        c.tim * 1000,
                        # adjust values to be human readable
                        goxapi.int2float(c.opn, self.gox.currency),
                        goxapi.int2float(c.hig, self.gox.currency),
                        goxapi.int2float(c.low, self.gox.currency),
                        goxapi.int2float(c.cls, self.gox.currency),
                        goxapi.int2float(c.vol, "BTC")
                    )
                ) 

            self.debug("Test history with %d candles" % len(candles))               

            rng = range(len(candles))
            iterable = (candles[i].cls for i in rng)
            a_cls = np.fromiter(iterable, np.float)
                                 
            iterable = (candles[i].tim for i in rng)
            a_tim = np.fromiter(iterable, np.int64)


            a_sma = talib.SMA(a_cls, 10)
            a_wma = talib.WMA(a_cls, 25)

            # create json compatible with HighStock.js
            with open("talib_ohlcv.json", 'w') as outfile:                   
                json.dump(candles, outfile, cls = OHLCV_Encoder)
            with open("talib_sma.json", 'w') as outfile:
                # first 10 elements contain Nan
                json.dump(np.dstack((a_tim[10:], a_sma[10:])).tolist()[0], outfile)
            with open("talib_wma.json", 'w') as outfile:
                # first 25 elements contain Nan
                json.dump(np.dstack((a_tim[25:], a_wma[25:])).tolist()[0], outfile)

with

Code:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>BTC Highstock - Goxtool/TA-Lib</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="http://code.highcharts.com/stock/highstock.js"></script>
<script type="text/javascript" src="http://code.highcharts.com/modules/exporting.js"></script>
<script type="text/javascript">
$(function () {
    var seriesOptions = [],
        ohlc = [],
        volume = []
        yAxisOptions = [],
        seriesCounter = 0,
        names = ['OHLCV', 'SMA', 'WMA'],
        colors = Highcharts.getOptions().colors,
        groupingUnits = [
            ['week', [1]],
            ['month', [1, 2, 3, 4, 6]]
        ];

    $.each(names, function (i, name) {
        $.getJSON('/talib_' + name.toLowerCase() + '.json', function (data) {
            console.log("Loading " + name);
            if (name == 'OHLCV') {
                // split the data set into ohlc and volume        
                var dataLength = data.length;
                for (i = 0; i < dataLength; i++) {
                    ohlc.push([
                        data[i][0], // the date
                        data[i][1], // open
                        data[i][2], // high
                        data[i][3], // low
                        data[i][4] // close
                    ]);

                    volume.push([
                        data[i][0], // the date
                        data[i][5] // the volume
                    ])
                }
            } else {
                seriesOptions[i] = {
                    name: name,
                    data: data
                };
            }

            // As we're loading the data asynchronously, we don't know what order it will arrive. So
            // we keep a counter and create the chart when all the data is loaded.
            seriesCounter++;

            if (seriesCounter == names.length) {
                createChart();
            }
        });
    });

    // create the chart when all data is loaded

    function createChart() {
        console.log("Creating chart");

        $('#container').highcharts('StockChart', {
            credits: {
                enabled: false
            },
            chart: {
                renderTo: container,
                backgroundColor: {
                    linearGradient: [0, 0, 0, 500],
                    stops: [
                        [0, 'rgb(255, 255, 255)'],
                        [1, 'rgb(215, 229, 240)']
                    ]
                }
            },
            rangeSelector: {
                buttons: [{
                        type: 'day',
                        count: 1,
                        text: '1d'
                    }, {
                        type: 'week',
                        count: 1,
                        text: '1w'
                    }, {
                        type: 'month',
                        count: 1,
                        text: '1m'
                    }
                ],
                selected: 0,
                inputEnabled: false
            },

            title: {
                text: 'BTC Historical - Goxtool/TA-Lib'
            },

            yAxis: [{
                    title: {
                        text: 'OHLC'
                    },
                    type: 'logarithmic',
                    height: 200,
                    lineWidth: 2
                }, {
                    title: {
                        text: 'Volume'
                    },
                    type: 'linear',
                    top: 300,
                    height: 100,
                    offset: 0,
                    lineWidth: 2
                }
            ],

            plotOptions: {
                candlestick: {
                    color: '#DD2F29',
                    upColor: '#87DA3B',
                    lineColor: '#666'
                }
            },

            tooltip: {
                pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
                valueDecimals: 2
            },

            series: [{
                    type: 'candlestick',
                    name: 'BTC',
                    data: ohlc,
                    dataGrouping: {
                        units: groupingUnits
                    }
                }, {
                    type: 'column',
                    name: 'Volume',
                    data: volume,
                    yAxis: 1,
                    dataGrouping: {
                        units: groupingUnits
                    }
                },
                seriesOptions[1], seriesOptions[2]
            ]
        });

    }

});
</script>
</head>
<body>
<div id="container" style="height: 500px; min-width: 600px"></div>
</body>
</html>

Serve index.html up with
Code:
python -m SimpleHTTPServer 8080

EDIT:  Using close instead of open for EMAs and added python server example
ErebusBat
Hero Member
*****
Offline Offline

Activity: 560
Merit: 500

I am the one who knocks


View Profile
April 29, 2013, 07:09:20 PM
 #130

@MtQuid

How far back does that 'historical' day pull from?  Since GoxTool started?

░▒▓█ Coinroll.it - 1% House Edge Dice Game █▓▒░ • Coinroll Thread • *FREE* 100 BTC Raffle

Signup for CEX.io BitFury exchange and get GHS Instantly!  Don't wait for shipping, mine NOW!
MtQuid
Newbie
*
Offline Offline

Activity: 24
Merit: 0



View Profile
April 29, 2013, 07:30:14 PM
 #131

@MtQuid

How far back does that 'historical' day pull from?  Since GoxTool started?

It's using the same history candles that prof7bit uses for the trade graph.  So it goes back a day in 15 minute blocks.
Though you can change the history_timeframe value in goxtool.ini to change the block size.
c0inbuster
Member
**
Offline Offline

Activity: 105
Merit: 10



View Profile WWW
April 30, 2013, 05:38:06 AM
 #132

I had some problems to see HTML file
so I contacted MtQuid using PM
I post here for other members

in fact you have to run a webserver (and not directly open HTML file with a browser)

Quote
python -m SimpleHTTPServer 8080

Open index.htm in your web browser using this url http://127.0.0.1:8080/index.hml


You will get a beautiful chart



It will be nice to also make orderbook depth chart with a JS lib

Maybe adding this feature to goxgui (goxtool GUI) will be fine
https://bitcointalk.org/index.php?topic=176489.80

Thnaks MtQuid for your code

Download free softwares! - crypto mining profit calculator - crypto triangular arbitrage tools - crypto stocks tools...
https://sites.google.com/site/working4coins/
MtQuid
Newbie
*
Offline Offline

Activity: 24
Merit: 0



View Profile
April 30, 2013, 08:58:48 AM
Last edit: April 30, 2013, 09:12:18 AM by MtQuid
 #133

Yep they do look good.  I robbed some of the colour styling straight from MtGox.com

I only wanted the graph output to make sure the ta-lib functions were returning the correct values so I could use them to control my bot.  I don't think this functionality needs to be part of the main goxtool branch but a good strategy plugin using ta-lib would be handy.  Like providing values and firing signals that can be caught.

And because the data sets are small (1 days worth of trade) you could write the whole index.html file to include the data and then there would be no need for the .json files or a web server.  Just pops out a stand alone html page every now and again if that's what you require.

I've also moved my function so it automatically gets called when new history arrives.

Code:
    def slot_history_changed(self, history, _dummy):
        """History has changed so recalculate EMAs"""

Now to try and find the best usage for the ta-lib functions and make some coins..  Grin
hugolp
Legendary
*
Offline Offline

Activity: 1148
Merit: 1001


Radix-The Decentralized Finance Protocol


View Profile
April 30, 2013, 12:23:56 PM
 #134

I only wanted the graph output to make sure the ta-lib functions were returning the correct values so I could use them to control my bot.

And how are the results?.

I manually created a ema function, basically following the formula you see everywhere in the Internet (f.e. http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages) but Im getting results quite different from bitcoincharts.com, specially for the hourly ema's but almost identical for the 1minute ema's. Because of this my guess was: the formula calculates the sma with the first periods and then starts adding the data as a exponential. I assumed this means that over time with enough data it would converge and that is why the 1minute ema's were almost identical while the hourly ema's were not, since Im getting data of two days and there is only 48 hours while there is 48 * 60 minutes. Does ta-lib get better results with data from one day only?

Quote
I don't think this functionality needs to be part of the main goxtool branch but a good strategy plugin using ta-lib would be handy.  Like providing values and firing signals that can be caught.

I actually would love to have the the web part in goxtool, maybe just as a plugin or something.

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.


               ▄████████▄
               ██▀▀▀▀▀▀▀▀
              ██▀
             ███
▄▄▄▄▄       ███
██████     ███
    ▀██▄  ▄██
     ▀██▄▄██▀
       ████▀
        ▀█▀
The Radix DeFi Protocol is
R A D I X

███████████████████████████████████

The Decentralized

Finance Protocol
Scalable
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀██
██                   ██
██                   ██
████████████████     ██
██            ██     ██
██            ██     ██
██▄▄▄▄▄▄      ██     ██
██▀▀▀▀██      ██     ██
██    ██      ██     
██    ██      ██
███████████████████████

███
Secure
      ▄▄▄▄▄
    █████████
   ██▀     ▀██
  ███       ███

▄▄███▄▄▄▄▄▄▄███▄▄
██▀▀▀▀▀▀▀▀▀▀▀▀▀██
██             ██
██             ██
██             ██
██             ██
██             ██
██    ███████████

███
Community Driven
      ▄█   ▄▄
      ██ ██████▄▄
      ▀▀▄█▀   ▀▀██▄
     ▄▄ ██       ▀███▄▄██
    ██ ██▀          ▀▀██▀
    ██ ██▄            ██
   ██ ██████▄▄       ██▀
  ▄██       ▀██▄     ██
  ██▀         ▀███▄▄██▀
 ▄██             ▀▀▀▀
 ██▀
▄██
▄▄
██
███▄
▀███▄
 ▀███▄
  ▀████
    ████
     ████▄
      ▀███▄
       ▀███▄
        ▀████
          ███
           ██
           ▀▀

███
Radix is using our significant technology
innovations to be the first layer 1 protocol
specifically built to serve the rapidly growing DeFi.
Radix is the future of DeFi
█████████████████████████████████████

   ▄▄█████
  ▄████▀▀▀
  █████
█████████▀
▀▀█████▀▀
  ████
  ████
  ████

Facebook

███

             ▄▄
       ▄▄▄█████
  ▄▄▄███▀▀▄███
▀▀███▀ ▄██████
    █ ███████
     ██▀▀▀███
           ▀▀

Telegram

███

▄      ▄███▄▄
██▄▄▄ ██████▀
████████████
 ██████████▀
   ███████▀
 ▄█████▀▀

Twitter

██████

...Get Tokens...
ErebusBat
Hero Member
*****
Offline Offline

Activity: 560
Merit: 500

I am the one who knocks


View Profile
April 30, 2013, 12:32:50 PM
 #135

MtQuid...
Would you be willing to share a basic demo of the Ta-lib integration?  I do not live in python so it would be very helpful for me, and I am sure others. 

░▒▓█ Coinroll.it - 1% House Edge Dice Game █▓▒░ • Coinroll Thread • *FREE* 100 BTC Raffle

Signup for CEX.io BitFury exchange and get GHS Instantly!  Don't wait for shipping, mine NOW!
MtQuid
Newbie
*
Offline Offline

Activity: 24
Merit: 0



View Profile
April 30, 2013, 02:06:09 PM
 #136

MtQuid...
Would you be willing to share a basic demo of the Ta-lib integration?  I do not live in python so it would be very helpful for me, and I am sure others. 

Ok.

We will use TA-Lib for bython from these lovely chaps
http://mrjbq7.github.io/ta-lib/index.html

Assuming you are working on a debian system you will need to do the following to install ta-lib for python
If on windows or mac then check http://mrjbq7.github.io/ta-lib/install.html

Code:
sudo apt-get install python-dev 
sudo easy_install cython

wget http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-src.tar.gz
tar -xvf ta-lib-0.4.0-src.tar.gz
cd ta-lib
./configure --prefix=/usr
make

#can use make install here if you want
sudo checkinstall

sudo easy_install TA-Lib

Once you have TA-Lib installed this is your strategy
Code:
"""
_talib.py

This example strategy will produce some HighStock.js compatible JSON files
"""

import numpy as np
import talib
import datetime
import json
import strategy
import goxapi
from goxapi import OHLCV

class OHLCV_Encoder(json.JSONEncoder):
    """JSONEncoder for class OHLCV()"""
    def default(self, obj):
        if isinstance(obj, OHLCV):
            return [obj.tim, obj.opn, obj.hig, obj.low, obj.cls, obj.vol]
        else:
            return json.JSONEncoder.default(self, obj)

class Strategy(strategy.Strategy):
    """a protfolio rebalancing bot"""
    def __init__(self, gox):       
        strategy.Strategy.__init__(self, gox)

    def slot_history_changed(self, history, _dummy):
        """History has changed so recalculate EMAs"""
        candles = []

        # read them all - don't wory about the history parameter
        for c in reversed(self.gox.history.candles):
            candles.append(
                OHLCV(
                    # fix time for HighStock.js JSON import
                    c.tim * 1000,
                    # adjust values to be human readable
                    goxapi.int2float(c.opn, self.gox.currency),
                    goxapi.int2float(c.hig, self.gox.currency),
                    goxapi.int2float(c.low, self.gox.currency),
                    goxapi.int2float(c.cls, self.gox.currency),
                    goxapi.int2float(c.vol, "BTC")
                )
            ) 

        self.debug("New EMAs from history with %d candles" % len(candles))               

        rng = range(len(candles))
        iterable = (candles[i].opn for i in rng)
        a_opn = np.fromiter(iterable, np.float)

        iterable = (candles[i].hig for i in rng)
        a_hig = np.fromiter(iterable, np.float)
       
        iterable = (candles[i].low for i in rng)
        a_low = np.fromiter(iterable, np.float)
       
        iterable = (candles[i].cls for i in rng)
        a_cls = np.fromiter(iterable, np.float)

        iterable = (candles[i].vol for i in rng)
        a_vol = np.fromiter(iterable, np.float)

        iterable = (candles[i].tim for i in rng)
        a_tim = np.fromiter(iterable, np.int64)


        a_sma = talib.SMA(a_cls, 10)
        a_wma = talib.WMA(a_cls, 25)
        a_chaikin = talib.AD(a_hig, a_low, a_cls, a_vol)
        a_cdlCounterAttack = talib.CDLCOUNTERATTACK(a_opn, a_hig, a_low, a_cls)

        # create json compatible with HighStock.js
        with open("talib_ohlcv.json", 'w') as outfile:                   
            json.dump(candles, outfile, cls = OHLCV_Encoder)
        with open("talib_sma.json", 'w') as outfile:
            # first 10 elements contain Nan
            json.dump(np.dstack((a_tim[10:], a_sma[10:])).tolist()[0], outfile)
        with open("talib_wma.json", 'w') as outfile:
            # first 25 elements contain Nan
            json.dump(np.dstack((a_tim[25:], a_wma[25:])).tolist()[0], outfile)
        with open("talib_chaikin.json", 'w') as outfile:
            json.dump(np.dstack((a_tim, a_chaikin)).tolist()[0], outfile)
        with open("talib_cdlCounterAttack.json", 'w') as outfile:
            json.dump(np.dstack((a_tim, a_cdlCounterAttack)).tolist()[0], outfile)

        # Current price in relation to EMA
        self.debug("SMA = %f" % a_sma[-1])
        self.debug("WMA = %f" % a_wma[-1])
        self.debug("CLS = %f" % a_cls[-1])

Run goxtool like so

Code:
python ./goxtool.py --protocol=websocket --strategy=_talib.py

Create index.html like this

Code:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>BTC Highstock - Goxtool/TA-Lib</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="http://code.highcharts.com/stock/highstock.js"></script>
<script type="text/javascript" src="http://code.highcharts.com/modules/exporting.js"></script>
<script type="text/javascript">
$(function () {
    var seriesOptions = [],
        ohlc = [],
        volume = []
        yAxisOptions = [],
        seriesCounter = 0,
        names = ['OHLCV', 'SMA', 'WMA', 'chaikin'],
        colors = Highcharts.getOptions().colors,
        groupingUnits = [
            ['week', [1]],
            ['month', [1, 2, 3, 4, 6]]
        ];

    $.each(names, function (i, name) {
        $.getJSON('/talib_' + name.toLowerCase() + '.json', function (data) {
            console.log("Loading " + name);
            if (name == 'OHLCV') {
                // split the data set into ohlc and volume        
                var dataLength = data.length;
                for (i = 0; i < dataLength; i++) {
                    ohlc.push([
                        data[i][0], // the date
                        data[i][1], // open
                        data[i][2], // high
                        data[i][3], // low
                        data[i][4] // close
                    ]);

                    volume.push([
                        data[i][0], // the date
                        data[i][5] // the volume
                    ])
                }
            } else if (name == 'chaikin') {
                seriesOptions[i] = {

                    yAxis: 2,
                    name: name,
                    data: data
                };

            } else {
                seriesOptions[i] = {
                    name: name,
                    data: data
                };
            }

            // As we're loading the data asynchronously, we don't know what order it will arrive. So
            // we keep a counter and create the chart when all the data is loaded.
            seriesCounter++;

            if (seriesCounter == names.length) {
                createChart();
            }
        });
    });

    // create the chart when all data is loaded

    function createChart() {
        console.log("Creating chart");

        $('#container').highcharts('StockChart', {
            credits: {
                enabled: false
            },
            chart: {
                renderTo: container,
                backgroundColor: {
                    linearGradient: [0, 0, 0, 500],
                    stops: [
                        [0, 'rgb(255, 255, 255)'],
                        [1, 'rgb(215, 229, 240)']
                    ]
                }
            },
            rangeSelector: {
                buttons: [{
                        type: 'day',
                        count: 1,
                        text: '1d'
                    }, {
                        type: 'week',
                        count: 1,
                        text: '1w'
                    }, {
                        type: 'month',
                        count: 1,
                        text: '1m'
                    }
                ],
                selected: 0,
                inputEnabled: false
            },

            title: {
                text: 'BTC Historical - Goxtool/TA-Lib'
            },

            yAxis: [{
                    title: {
                        text: 'OHLC'
                    },
                    type: 'logarithmic',
                    height: 200,
                    lineWidth: 2
                }, {
                    title: {
                        text: 'Volume'
                    },
                    type: 'linear',
                    top: 300,
                    height: 100,
                    offset: 0,
                    lineWidth: 2
                }, {
                    title: {
                        text: 'Chakin'
                    },
                    type: 'linear',
                    top: 450,
                    height: 100,
                    offset: 0,
                    lineWidth: 2
                }
            ],

            plotOptions: {
                candlestick: {
                    color: '#DD2F29',
                    upColor: '#87DA3B',
                    lineColor: '#666'
                }
            },

            tooltip: {
                pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>',
                valueDecimals: 2
            },

            series: [{
                    type: 'candlestick',
                    name: 'BTC',
                    data: ohlc,
                    dataGrouping: {
                        units: groupingUnits
                    }
                }, {
                    type: 'column',
                    name: 'Volume',
                    data: volume,
                    yAxis: 1,
                    dataGrouping: {
                        units: groupingUnits
                    }
                },
                seriesOptions[1], seriesOptions[2], seriesOptions[3]
            ]
        });

    }

});
</script>
</head>
<body>
<div id="container" style="height: 1000px; min-width: 600px"></div>
</body>
</html>

And run a simple web server like this
Code:
python -m SimpleHTTPServer 8080

Then go to http://localhost:8080/index.html and see sunshine

You could have the index.html auto reload with simple script or refresh with your mouse Smiley


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]'



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.
hugolp
Legendary
*
Offline Offline

Activity: 1148
Merit: 1001


Radix-The Decentralized Finance Protocol


View Profile
April 30, 2013, 03:22:17 PM
 #137

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


               ▄████████▄
               ██▀▀▀▀▀▀▀▀
              ██▀
             ███
▄▄▄▄▄       ███
██████     ███
    ▀██▄  ▄██
     ▀██▄▄██▀
       ████▀
        ▀█▀
The Radix DeFi Protocol is
R A D I X

███████████████████████████████████

The Decentralized

Finance Protocol
Scalable
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀██
██                   ██
██                   ██
████████████████     ██
██            ██     ██
██            ██     ██
██▄▄▄▄▄▄      ██     ██
██▀▀▀▀██      ██     ██
██    ██      ██     
██    ██      ██
███████████████████████

███
Secure
      ▄▄▄▄▄
    █████████
   ██▀     ▀██
  ███       ███

▄▄███▄▄▄▄▄▄▄███▄▄
██▀▀▀▀▀▀▀▀▀▀▀▀▀██
██             ██
██             ██
██             ██
██             ██
██             ██
██    ███████████

███
Community Driven
      ▄█   ▄▄
      ██ ██████▄▄
      ▀▀▄█▀   ▀▀██▄
     ▄▄ ██       ▀███▄▄██
    ██ ██▀          ▀▀██▀
    ██ ██▄            ██
   ██ ██████▄▄       ██▀
  ▄██       ▀██▄     ██
  ██▀         ▀███▄▄██▀
 ▄██             ▀▀▀▀
 ██▀
▄██
▄▄
██
███▄
▀███▄
 ▀███▄
  ▀████
    ████
     ████▄
      ▀███▄
       ▀███▄
        ▀████
          ███
           ██
           ▀▀

███
Radix is using our significant technology
innovations to be the first layer 1 protocol
specifically built to serve the rapidly growing DeFi.
Radix is the future of DeFi
█████████████████████████████████████

   ▄▄█████
  ▄████▀▀▀
  █████
█████████▀
▀▀█████▀▀
  ████
  ████
  ████

Facebook

███

             ▄▄
       ▄▄▄█████
  ▄▄▄███▀▀▄███
▀▀███▀ ▄██████
    █ ███████
     ██▀▀▀███
           ▀▀

Telegram

███

▄      ▄███▄▄
██▄▄▄ ██████▀
████████████
 ██████████▀
   ███████▀
 ▄█████▀▀

Twitter

██████

...Get Tokens...
MtQuid
Newbie
*
Offline Offline

Activity: 24
Merit: 0



View Profile
April 30, 2013, 05:24:31 PM
Last edit: April 30, 2013, 06:44:12 PM by MtQuid
 #138

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
hugolp
Legendary
*
Offline Offline

Activity: 1148
Merit: 1001


Radix-The Decentralized Finance Protocol


View Profile
April 30, 2013, 08:17:34 PM
Last edit: April 30, 2013, 08:27:55 PM by hugolp
 #139

MtQuid that looks terrific. Hopefully prof7bit can include that or something similar in the source.

Another solution might be being able to select what goes into the debug at runtime, so one could select to only have in the debug file the messages from the modules s/he wants. Im fine with any of both solutions.

EDIT: MtQuid tried your code and its working perfectly. Im sending you a small tip.


               ▄████████▄
               ██▀▀▀▀▀▀▀▀
              ██▀
             ███
▄▄▄▄▄       ███
██████     ███
    ▀██▄  ▄██
     ▀██▄▄██▀
       ████▀
        ▀█▀
The Radix DeFi Protocol is
R A D I X

███████████████████████████████████

The Decentralized

Finance Protocol
Scalable
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀██
██                   ██
██                   ██
████████████████     ██
██            ██     ██
██            ██     ██
██▄▄▄▄▄▄      ██     ██
██▀▀▀▀██      ██     ██
██    ██      ██     
██    ██      ██
███████████████████████

███
Secure
      ▄▄▄▄▄
    █████████
   ██▀     ▀██
  ███       ███

▄▄███▄▄▄▄▄▄▄███▄▄
██▀▀▀▀▀▀▀▀▀▀▀▀▀██
██             ██
██             ██
██             ██
██             ██
██             ██
██    ███████████

███
Community Driven
      ▄█   ▄▄
      ██ ██████▄▄
      ▀▀▄█▀   ▀▀██▄
     ▄▄ ██       ▀███▄▄██
    ██ ██▀          ▀▀██▀
    ██ ██▄            ██
   ██ ██████▄▄       ██▀
  ▄██       ▀██▄     ██
  ██▀         ▀███▄▄██▀
 ▄██             ▀▀▀▀
 ██▀
▄██
▄▄
██
███▄
▀███▄
 ▀███▄
  ▀████
    ████
     ████▄
      ▀███▄
       ▀███▄
        ▀████
          ███
           ██
           ▀▀

███
Radix is using our significant technology
innovations to be the first layer 1 protocol
specifically built to serve the rapidly growing DeFi.
Radix is the future of DeFi
█████████████████████████████████████

   ▄▄█████
  ▄████▀▀▀
  █████
█████████▀
▀▀█████▀▀
  ████
  ████
  ████

Facebook

███

             ▄▄
       ▄▄▄█████
  ▄▄▄███▀▀▄███
▀▀███▀ ▄██████
    █ ███████
     ██▀▀▀███
           ▀▀

Telegram

███

▄      ▄███▄▄
██▄▄▄ ██████▀
████████████
 ██████████▀
   ███████▀
 ▄█████▀▀

Twitter

██████

...Get Tokens...
MtQuid
Newbie
*
Offline Offline

Activity: 24
Merit: 0



View Profile
April 30, 2013, 11:57:01 PM
 #140

EDIT: MtQuid tried your code and its working perfectly. Im sending you a small tip.

Tip recieved. 
Thanks hugolp Smiley
Pages: « 1 2 3 4 5 6 [7] 8 9 10 11 »  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!