473,545 Members | 721 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Connecting an agent and its strategy

I am trying to find a solution to the following design problem
(code at the bottom):

We are implementing a trader agent that can trade with other traders
on an electronical trading platform. To make the trader more
extensible, we have defined a strategy interface and implemented this
interface for different trading strategies. The problem relates to how
to connect the trader and the strategy.

The problem is tricky because the strategy has to call back the
trader, for instance to get information about orders (i.e. prices) on
the trading platform, and to initiate own orders. Technically, the
strategy constructor takes an argument of type StrategyCallbac k. The
latter is an interface which is implemented by the trader class.
The quick and dirty approach would be the following:

The user (1) instantiates the trader and then (2) uses the reference
to the trader to instantiate the strategy. After that (3), the user
calls a method of the trader that initializes the trader's strategy,
passing it the reference to the strategy.

The problem is that the initialization takes place outside of, and
after the constructor. Also, the user has to worry about internals of
the trader.
A bit more elegant is the following approach:

The strategy cannot be instantiated before the trader. It would be
nice to let the trader instantiate it. But the trader doesn't know the
exact type of the strategy. So let's make the trader a template. Like
this, the initialization can take place in the trader's constructor
and is hidden from the user.

We have implemented this approach, and it works. However, it doesn't
really solve the design problem. Every instantiation of the trader
template has a different type. The trader class has to be recompiled
whenever we write a new strategy for it. For the same reason, it is
awkward to manage a collection of traders with different strategies.
Is there another way?
struct Strategy;
struct StrategyCallbac k;

/// trader class aggregating a strategy
class Trader
: public StrategyCallbac k
{
public:
//construction
Trader(trading: :Strategy*);
~Trader();
private:
Trader(const& Trader);
Trader& operator=(const Trader&);

//private data
Strategy* m_pStrategy;
};

/// interface representing a trader's strategy.
struct Strategy
{
virtual ~Strategy() { /*cleanup*/ }

/// reevaluate situation.
virtual void evaluate() = 0;

/// the strategy has reached the goal.
virtual bool succeeded() = 0;

/// the strategy has failed.
virtual bool failed() = 0;

/// perform the strategy.
virtual void trade() = 0;
};

/// callback interface for strategy.
struct StrategyCallbac k
{
/// access orders.
virtual OrderIseq getOrders() = 0;

/// create an order.
virtual trading::Order* createOrder(
double dPrice,
double dVolume) = 0;
};

--
Claudio Jolowicz

Department of Computing
180 Queen's Gate
South Kensington campus
Imperial College
LONDON SW7 2AZ

31 Humbolt Road
Fulham
LONDON W6 8QH

mobile: +44(0)7963 892810
mail to: cj***@doc.ic.ac .uk
webpage: www.doc.ic.ac.uk/~cj603

Jul 22 '05 #1
4 1969
On Thu, 8 Apr 2004 07:15:32 +0100, Claudio Jolowicz
<cj***@doc.ic.a c.uk> wrote:
We are implementing a trader agent that can trade with other traders
on an electronical trading platform. To make the trader more
extensible, we have defined a strategy interface and implemented this
interface for different trading strategies. The problem relates to how
to connect the trader and the strategy.

The problem is tricky because the strategy has to call back the
trader, for instance to get information about orders (i.e. prices) on
the trading platform, and to initiate own orders. Technically, the
strategy constructor takes an argument of type StrategyCallbac k. The
latter is an interface which is implemented by the trader class. [snip]A bit more elegant is the following approach:

The strategy cannot be instantiated before the trader. It would be
nice to let the trader instantiate it. But the trader doesn't know the
exact type of the strategy. So let's make the trader a template. Like
this, the initialization can take place in the trader's constructor
and is hidden from the user.

We have implemented this approach, and it works. However, it doesn't
really solve the design problem. Every instantiation of the trader
template has a different type. The trader class has to be recompiled
whenever we write a new strategy for it. For the same reason, it is
awkward to manage a collection of traders with different strategies.

Is there another way?
You could change the Strategy interface to take a StrategyCallbac k in
the relevent method calls (such as evaluate and trade). That way there
is no direct composition relationship between a Strategy and the
"callback", which might better decouple them (and remove the circular
reference).
struct Strategy;
struct StrategyCallbac k;
It might be better to call that OrderHandler, or similar, to better
express its purpose.

/// trader class aggregating a strategy
class Trader
: public StrategyCallbac k
{
public:
//construction
Trader(trading: :Strategy*);
~Trader();
private:
Trader(const& Trader);
Trader& operator=(const Trader&);

//private data
Strategy* m_pStrategy;


Obviously a smart pointer would be appropriate here (and in the
constructor).

Another solution would be to use a StrategyFactory . e.g.

class StrategyFactory
{
public:
virtual ~StrategyFactor y(){};

typedef shared_ptr<Stra tegy> StrategyPtr;

virtual StrategyPtr createStrategy( OrderHandler& handler) = 0;
};

template <class Strat>
class ConcreteStrateg yFactory: public StrategyFactory
{
public:
virtual StrategyPtr createStrategy( OrderHandler& handler)
{
return StrategyPtr(new Strat(handler)) ;
}
};

and pass that into the Trader constructor (note that the handler must
outlive the Strategy - avoid circular smart pointer references by
using a weak_ptr or a reference to the handler as above).

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #2
On Thu, 8 Apr 2004 07:15:32 +0100, Claudio Jolowicz
<cj***@doc.ic.a c.uk> wrote:
We are implementing a trader agent that can trade with other traders
on an electronical trading platform. To make the trader more
extensible, we have defined a strategy interface and implemented this
interface for different trading strategies. The problem relates to how
to connect the trader and the strategy.

The problem is tricky because the strategy has to call back the
trader, for instance to get information about orders (i.e. prices) on
the trading platform, and to initiate own orders. Technically, the
strategy constructor takes an argument of type StrategyCallbac k. The
latter is an interface which is implemented by the trader class. [snip]A bit more elegant is the following approach:

The strategy cannot be instantiated before the trader. It would be
nice to let the trader instantiate it. But the trader doesn't know the
exact type of the strategy. So let's make the trader a template. Like
this, the initialization can take place in the trader's constructor
and is hidden from the user.

We have implemented this approach, and it works. However, it doesn't
really solve the design problem. Every instantiation of the trader
template has a different type. The trader class has to be recompiled
whenever we write a new strategy for it. For the same reason, it is
awkward to manage a collection of traders with different strategies.

Is there another way?
You could change the Strategy interface to take a StrategyCallbac k in
the relevent method calls (such as evaluate and trade). That way there
is no direct composition relationship between a Strategy and the
"callback", which might better decouple them (and remove the circular
reference).
struct Strategy;
struct StrategyCallbac k;
It might be better to call that OrderHandler, or similar, to better
express its purpose.

/// trader class aggregating a strategy
class Trader
: public StrategyCallbac k
{
public:
//construction
Trader(trading: :Strategy*);
~Trader();
private:
Trader(const& Trader);
Trader& operator=(const Trader&);

//private data
Strategy* m_pStrategy;


Obviously a smart pointer would be appropriate here (and in the
constructor).

Another solution would be to use a StrategyFactory . e.g.

class StrategyFactory
{
public:
virtual ~StrategyFactor y(){};

typedef shared_ptr<Stra tegy> StrategyPtr;

virtual StrategyPtr createStrategy( OrderHandler& handler) = 0;
};

template <class Strat>
class ConcreteStrateg yFactory: public StrategyFactory
{
public:
virtual StrategyPtr createStrategy( OrderHandler& handler)
{
return StrategyPtr(new Strat(handler)) ;
}
};

and pass that into the Trader constructor (note that the handler must
outlive the Strategy - avoid circular smart pointer references by
using a weak_ptr or a reference to the handler as above).

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #3
Claudio Jolowicz wrote:

The quick and dirty approach would be the following:

The user (1) instantiates the trader and then (2) uses the reference
to the trader to instantiate the strategy. After that (3), the user
calls a method of the trader that initializes the trader's strategy,
passing it the reference to the strategy.

The problem is that the initialization takes place outside of, and
after the constructor. Also, the user has to worry about internals of
the trader.


Hmm.

class StrategyCallbac k
{
public:
virtual OrderIseq getOrders() = 0;
virtual trading::Order* createOrder( double dPrice, double dVolume) = 0;
};

class Strategy
{
public:
Strategy();

void UseWith( StrategyCallbac k& TheTrader );
};

class Trader : public StrategyCallbac k
{
public:
Trader( Strategy& UseStrategy ) : m_Strategy( UseStrategy )
{
m_Strategy.UseW ith( *this );
};

protected:
Strategy m_Strategy;
};

int main()
{
Strategy MyStrat;
Trader MyTrader( MyStrat );
}

Seems acceptable to me, without having the user of the classes have to know
to much details about the Trader class. A Trader cannot be instatiated without
a strategy, thus it cannot be forgotten to give one to it. The passed strategy
is copied at the moment it is given to the trader thus you can throw away the
MyStrat in main without affecting the MyTrader (may or may not be what you want).

--
Karl Heinz Buchegger
kb******@gascad .at
Jul 22 '05 #4
Claudio Jolowicz wrote:

The quick and dirty approach would be the following:

The user (1) instantiates the trader and then (2) uses the reference
to the trader to instantiate the strategy. After that (3), the user
calls a method of the trader that initializes the trader's strategy,
passing it the reference to the strategy.

The problem is that the initialization takes place outside of, and
after the constructor. Also, the user has to worry about internals of
the trader.


Hmm.

class StrategyCallbac k
{
public:
virtual OrderIseq getOrders() = 0;
virtual trading::Order* createOrder( double dPrice, double dVolume) = 0;
};

class Strategy
{
public:
Strategy();

void UseWith( StrategyCallbac k& TheTrader );
};

class Trader : public StrategyCallbac k
{
public:
Trader( Strategy& UseStrategy ) : m_Strategy( UseStrategy )
{
m_Strategy.UseW ith( *this );
};

protected:
Strategy m_Strategy;
};

int main()
{
Strategy MyStrat;
Trader MyTrader( MyStrat );
}

Seems acceptable to me, without having the user of the classes have to know
to much details about the Trader class. A Trader cannot be instatiated without
a strategy, thus it cannot be forgotten to give one to it. The passed strategy
is copied at the moment it is given to the trader thus you can throw away the
MyStrat in main without affecting the MyTrader (may or may not be what you want).

--
Karl Heinz Buchegger
kb******@gascad .at
Jul 22 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

60
7208
by: Fotios | last post by:
Hi guys, I have put together a flexible client-side user agent detector (written in js). I thought that some of you may find it useful. Code is here: http://fotios.cc/software/ua_detect.htm The detector requires javascript 1.0 to work. This translates to netscape 2.0 and IE 3.0 (although maybe IE 2.0 also works with it)
4
295
by: Claudio Jolowicz | last post by:
I am trying to find a solution to the following design problem (code at the bottom): We are implementing a trader agent that can trade with other traders on an electronical trading platform. To make the trader more extensible, we have defined a strategy interface and implemented this interface for different trading strategies. The problem...
6
7309
by: Marvin Libson | last post by:
Hi All: I am running DB2 UDB V7.2 with FP11. Platform is Windows 2000. I have created a java UDF and trigger. When I update my database I get the following error: SQL1224N A database agent could not be started to service a request, or was terminated as a result of a database system shutdown or a force command.
0
3906
by: Suresh | last post by:
Hi Guys I have Db2 server installed on remote server. i am connecting to that remote server by using VPN. I want to connect that remote DB2 server instance using my local machine DB2 development client. Bur Its gives me following error message. I searched lots of things on net and tried on remote server but i didnt got suceess. Can any...
4
7800
by: shsandeep | last post by:
We are trying to connect from DataStage to a DB2 database on Z/OS. It connects fine from the DataStage server, but when connecting from DataStage client it gives the following error: DSR.MetaGeta(GET.TABLES)(SQLConnect('USABCCP1','uspsxs')): BCI Error: SQLSTATE=08S01,CODE=0,Permanent Agent Error. Has anybody encountered this before? Any...
9
7659
by: vikram.mankar | last post by:
I have a stored procedure thats transferring/processing data from one table to two different tables. The destination tables have a unique value constraint as the source tables at times has duplicate records and this will prevent the duplicates from being reported. When the stored procedure (which includes a cursor) is executed through query...
6
6603
by: xeqister | last post by:
Greetings, We are having a situation here whereby one of our staff created a very huge 32K buffer pool in a production database and caused the database to go down. When we try to reconnect to the database using "db2 connect to <dbname>", its giving the following error: SQL1224N A database agent could not be started to service a request, or...
35
2444
by: RobG | last post by:
Seems developers of mobile applications are pretty much devoted to UA sniffing: <URL: http://wurfl.sourceforge.net/vodafonerant/index.htm > -- Rob
2
1129
by: Michael Howes | last post by:
I am trying to upgrade a large asp.net application from .Net 1.1 to ..Net 3.0 I'm getting an error when connecting to the database now that the app runs as a .Net 3.0 application. the database connection code is part of Microsoft's ApplicationBlocks, the Data Access Block. The project is using the SQLHelper class from MS. The...
0
7656
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
1
7416
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
5969
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5325
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
4944
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3449
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3441
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1878
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1013
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.