January 2006 - Posts

Latest pet project

So - I spent the better part of 2 years writing a distributed Optimization and Classification application for use training fully automated trading systems - sometimes you hear me reference OptimalOptimizer - that is what i am refering to. In short - it is software - written in C# that implements much learned for the schools of Memetic Algorithms, Evolutionary Computation, Data Mining, etc, etc. Cool bits with useful purpose. A user recently messaged me to say that he believes it has harvested near 100 tradeable trading systems with near 1000 possible variations of those systems!

Anyhow... To brush up on my Java skills - and to play with Ruby - I have been working on a C# to Java converter - written in Ruby. (I am also upgrading the C# code to use 2.0 features - mainly generics - but that is besides the point).

I am working on strategies for converting the following C# items to Java:

#        package/ namespace
#        events
#        delegates
#        using
#        regions   
#        assertions
#        exceptions
#         attributes
#         get/set
#        foreach
#         constructor overloading
#        extends (base classes)
#         implements (interfaces)

I am sure this list will expand...

This set of exercises has shown me several things so far - so - in no particular order.

1) Delegates/ Events are wonderful
2) Java's notion of events is far inferior
3) Qt's SLOTS/ SIGNALS is better than Java's event mechanisms in many ways
4) Delegates/ Events are better than Qt's SLOTS/ SIGNALS
5) Ruby is a cool little language
6) I am very reliant on IDEs, strong typing etc  - getting used to getting much less from the IDE is a hard exercise (Ruby in Eclipse)
7) Ruby and Qt's Ruby Extensions are nice in thought - not so great to use (yet maybe)
8) Porting .Net 1.1 to the latest 1.5 JDK is easier than older JDK versions - annotations help a ton as I am usually an attribute zealot in .net land
9) I keep learning this lesson - Db4o is wonderful
10) I need an open source message queue (perhaps ActiveMQ + Stomp for DotNet seems most compelling )
11) It is late and I need to go to bed.
12) My kids are really cute - I wish the slept perfectly :)

OK - so some of those are not lessons from this process - but they are true nonetheless

-Chris

db4o rocks

Db4o is just plain good technology.

Db4o is an open source [caveats] object database for Java and/ or .Net. It is purposeful, cool, fun, impressive, well coded - all sorts of good.

Dr Dobbs Journal. I did some work with Db4oaround 6 months ago and was quite impressed with it in general. That being said - there are a few just amazing points about db4o:

1) I persist my C# object and it can be re-hydrated in a Java client or a .Net client ....
2) Native queries are amazing - especially with anon-delegates in .Net 2.0 - they look like...
3) You can easily refresh in memory objects to get updated changes from other objects out there in the DB.
4) Many lovely query mechanisms.
5) Now - they have Hibernate based replication between relational DBs and the object db ( or multiple object DBs).

Anon-Delegates look like this:
delegate(Student student){
return student.Age < 20
&& student.Name.Contains("f");
}

You are simply telling the object DB that you want a 'Student' with a certain 'where clause'. The primary difference is that you are using ... the native language - not some stringy SQL code.

Anyhow - enough for db4o - when I can get back to really using it - I will update.

-Chris

Dev machine software/ tools

Someone at the office was asking about the melange of tools I have installed on my machine - admittedly I am a tool/ software addict....

 

What I have on my current project’s machine (win2k….. man) (at least this stuff - and plenty more of lesser note)

 

VS .Net 2003

Resharper

devMetrics

GhostDoc AddIn

Regions AddIn

Xsd Object Generator

VSWindowManager AddIn

Spring.net

CodeSmith

NDoc

RegexDesigner.NET

CruiseControl.NET

CCTray

NUnit

FxCop

Textpad

Reflector

XmlSpy

Eclipse

Log4net

Infragistics 5.3

Rapid SQL

ClearCase(hatred!!!)

ClearQuest (hatred!!!)

Tomcat

Snippet Compiler

Rhino.Mocks

Simian

Solvent VS.Net Add In

CopySourceAsHtml  VS.Net Add In

 

Things that when they do not kill my machine I keep installed at my current project

 

Compuware DevPartner

 

What I add on other machines as must haves (Windows Server 2k3 @ Home, some XP Pro @ Home) (at least this stuff, along with the above list for the most part - and more of lesser note)

 

VS.Net 2005

SQL Server 2005

Eclipse Ruby

Tomcat

Axis

Spring (for Java)

Ruby

Omea Reader

Subversion

TortoiseSVN

TortoiseCVS

Apex SQL Edit

SQL Server 2000

Microsoft CAB 2.0

 

Linux Machine must haves (Current Suse 10)

 

KDevelop

KDevelop Ruby

Eclipse

MonoDevelop

Subversion

Thunderbird

Firefox

Krdc

Akregator

EditpadPro

Butterfly XML

 

I could go on - but I am back to work.

 

-Chris

Suse 10 - Lovely

Well -  I must say that Suse 10 is just about the best linux distro I have used ever. Now - I am no *nix expert, but I have installed a good 1/2 dozen different linux distros over the past few years - and Suse 10 is just great. The only battle I had this time - I have had in the past : Video drivers on a laptop. In the end - It would only give me 800x600 resolution by default. To fix that - I simply needed to boot into run level 3, and tell Sax2 to force a resolution on the vesa driver using the --vesa flag. I expect this kind of stuff from any linux distro on a laptop. I did waste some time trying to do a kernel rebuild with some proprietary ATI driver - but it was not the correct solution.

I was able to get Eclipse with the Ruby and Java environments set up in minutes. My wireless network card (a 3com) that has given me problems with older Redhat, fedora, mandriva, etc distros worked out with ease.

My FAVORITE part was the I could remote desktop from the linux laptop to my main windows machine. Since I often sit on the sofa after my wife and kids to to bed with the laptop - I need to be able to get at all my machines (windows mostly). The remote desktop was top notch, 100% clean. Wonderful. One next step is to sort out a pet Ruby project to do 100% on the linux machine. I also plan on porting a C# AI project I spent some zillions of hours on ported to Java/ linux so I could easily value cluster myself on many linux machines...  Aaah clustered AI is lovely.

I also need to get a mono development enviroment fully configured. Plenty of work to do :)

-Chris

Object Binding (.Net 1.0)

Lately - I have been up to some Presentation Layer programming. I have been making a mechanism to create bind-able things from our entity objects. This will enable us to bind to grids and other UI elements. We need to be able to create N number of views for our Entity objects - and not put code in odd places in our layered architecture. For example; if we have a Trade entity class (and/ or several derived Trade types), - we need to make many different views of this same entity - really entity collections - TradeCollection(s).

That being said - in the past I have done this a few ways -

#1) Implement the interfaces for binding (needs to be done over and over for all objects). Since our objects are sometimes quite deep aggregates of other objects, this amounts to lots of work in this case. It is not very DRY (Dont Repeat Yourself) - you need to do this again and again for each object that you want to bind.

#2) Attributes on the entity classes to define attributes at binding- the limitation here is that you get 1 view definition and it is embedded in the entity object. This also puts code for the Presentation Layer in the Domain Layer. This involves reflection and there are more 'reflectiony variations' on this approach - but they are basically the same.

#3) Manually create datasets, datatables, dataviews, etc. from your entities. This means manually plucking info out of your classes and sticking them into the datasets. This approach results in you loosing your entities and programming to datasets etc. It becomes a mess. You could use many dataset variants - strongly typed datasets, non-strongly typed datasets, yadda yadda….

#4) Our approach in the end was to use metadata to create a bindable something. This metadata is XML that looks something like:

The XML Meta-data for binding looks like this (this is a flat view):

    2 <View>

    3   <Band DisplayName="Trade" Type="Some.Name.Space.Trade, Some.Name.Space">

    4     <Column DisplayName="TradeDetails Id" Path="TradeDetails.Id" Type="System.String" />

    5     <Column DisplayName="TradeDetails Version" Path="TradeDetails.Version" Type="System.Int32" />

    6     <Column DisplayName="TradeDetails Type" Path="TradeDetails.Type" Type="System.String" />

    7     <Column DisplayName="TradeDetails Name" Path="TradeDetails.Name" Type="System.String" />

    8     <Column DisplayName="TradeDetails OriginatingSystem" Path="TradeDetails.OriginatingSystem" Type="System.String" />

    9     <Column DisplayName="TradeDetails IsSales" Path="TradeDetails.IsSales" Type="System.Boolean" />

   10     <Column DisplayName="TradeDetails State" Path="TradeDetails.State" Type="Some.Name.Space.State, Some.Name.Space" />

   11     <Column DisplayName= "Location" Path="TradeDetails.Location" Type="Some.Name.Space.Location, Some.Name.Space" />

   12     <Column DisplayName= "TradingMedium" Path="TradeDetails.TradingMedium" Type="Some.Name.Space.TradingMedium, Some.Name.Space" />

   13     <Column DisplayName="TradeDetails TraderId" Path="TradeDetails.TraderId" Type="System.String" />

   14     <Column DisplayName="TradeDetails CreditApproval" Path="TradeDetails.CreditApproval" Type="System.String" />

   15     <Column DisplayName="TradeDetails Book" Path="TradeDetails.Book" Type="System.Int32" />

   16     <Column DisplayName="TradeDetails DealConditions" Path="TradeDetails.DealConditions" Type="System.String" />

   17     <Column DisplayName= "CounterpartySubAccount" Path="TradeDetails.CounterpartySubAccount" Type="System.String" />

   18     <Column DisplayName="TradeDetails IndependentAmount" Path="TradeDetails.IndependentAmount" Type="System.Double" />

   19     <Column DisplayName="TradeDetails Gap" Path="TradeDetails.Gap" Type="System.String" />

   20     <Column DisplayName="TradeDetails ProductGroup" Path="TradeDetails.ProductGroup" Type="System.String" />

   21     <Column DisplayName="TradeDetails RealCounterParty Ref" Path="TradeDetails.RealCounterParty.Ref" Type="System.String" />

   22     <Column DisplayName="TradeDetails RealCounterParty Id" Path="TradeDetails.RealCounterParty.Id" Type="System.String" />

   23     <Column DisplayName= "TradingStrategy" Path="TradeDetails.TradingStrategy" Type="Some.Name.Space.TradingStrategy, Some.Name.Space" />

   24     <Column DisplayName= "FeeType" Path="TradeDetails.SalesCredit.FeeType" Type="Some.Name.Space.FeeType2, Some.Name.Space" />

   25     <Column DisplayName= "SalesPerson" Path="TradeDetails.SalesCredit.SalesPerson" Type="System.String" />

   26     <Column DisplayName= "Markup Currency" Path="TradeDetails.SalesCredit.Markup.Currency" Type="System.String" />

   27     <Column DisplayName= "SalesCredit Markup Amount" Path="TradeDetails.SalesCredit.Markup.Amount"  Type="System.Double" />

   28     <Column DisplayName="TradeDetails SalesCredit Currency" Path="TradeDetails.SalesCredit.Currency" Type="System.String" />

That Xml is then loaded as part of a IViewDescriptor in IObjectView :

    3     public interface IObjectView

    4     {

    5         ///

    6         /// Gets or sets the source object.

    7         ///

    8         /// The source object.

    9         object SourceObject { get; set; }

   10 

   11         ///

   12         /// Gets or sets the view descriptor.

   13         ///

   14         /// The view descriptor.

   15         IViewDescriptor ViewDescriptor { get; set; }

   16 

   17         ///

   18         /// Gets the bindable object.

   19         ///

   20         ///

   21         object GetBindableObject();

   22     }

Then at runtime you get the IViewDefintion, the source object – and call GetBindableObject() to get something to bind to.

Like so:

  257         private void BindDemoForm_Load(object sender, EventArgs e)

  258         {

  262             // Get a view from the view repository

  263             IObjectView objectView = appContext.ObjectViewRepository.GetByKey( "BindDemoForm.ModelView3" );

  264 

  265             //give the view some data to bind to (the trades in the TradeRepository in this case)

  266             objectView.SourceObject = appContext.TradeRepository.Values;

  267 

  268             // bind to the grid

  269             gridBinder.SetObjectToGrid( grid, objectView );

  270 

  271             // get underlying objects when grid is clicked

  272             gridBinder.RowDoubleClick += new StuckRowClickHandler(gridBinder_RowDoubleClick);

  273         }

After that – we hook up some events so that when we select or click on a row in a grid – we get the underlying Entity object in stead of a row. This means that all of your business operations can happen on your business object – not on a dataset, etc.

This looks something like:

  345         private void gridBinder_RowDoubleClick(object sender, StuckRowClickEventArgs e)

  346         {

  347             // get the underlying item in 1 line of code :)

  348             Trade trade  =  e.BoundObject as Trade;

  349             Debug.Assert( trade != null );   

  350             string formatString = "Your underlying object \nTrade Id = {0}, Trade Version = {1}, Type = [{2}]";

  351             string tradeDescription = string.Format(

  352                     formatString, 

  353                     trade.TradeDetails.Id, 

  354                     trade.TradeDetails.Version,

  355                     trade.GetType().ToString()

  356                 );           

  357             trade.TradeDetails.TraderId = new Random().Next().ToString();

  358             gridBinder.UpdateRowFromObject( e.GridRow, trade );

  359             MessageBox.Show( this, tradeDescription );

  360         }

There are several advantages to this approach: You can flatten your view of a hierarchical object, you can change the look in the hierarchy, or of course – you can use the existing hierarchy. You can define an unlimited number of views. You can do business operations on your objects directly – not on DataSets/ DataTables/ DataRows, etc.

Behind the scenes – in essence – we are inferring a schema from the root object using reflection. From there – we create a series of datatables in a dataset – complete with relations for the hierarchy etc.

It was quite easy to derive classes from DataTable, DataRow and DataColumn. Doing this allowed me to attach the ColumnDescriptor class and the bound object to the DataRow. The Colu