0

I am implementing a trading system, and I want to use the same code for both live trading and backtesting. When doing live trading, I need to persist everything that happens, but when backtesting, I would like to use the same classes and logic but not persist them (for speed and because I have no reason to store them).

I thought I could do this simply by not calling save() on them, but I've run into a problem. I have an Account class that includes a hasMany collection of Position objects. The trouble is that I need to find the right Position in the Account, but it seems that I can't, since it's never been saved. I tried iterating through the hasMany collection of Positions but there's nothing in there, even though I constructed a Position object and added it to the account with addToPositions(). I guess this won't be meaningful until after that call to save() that I'm trying to avoid.

Is there a way to reuse the same classes for both persistant and transient purposes, or am I trying to commit an unnatural act? I am open to any suggestions for how to reuse these classes in both scenarios.

Update (adding code samples):

Account.groovy:

class Account {
    String name
    static belongsTo = [user:S2User]
    static hasMany = [positions:Position, transactions:Transaction]
}

SimAccount.groovy:

class SimAccount extends Account {
}

Position.groovy:

class Position implements Serializable {
    String symbol
    static belongsTo = [account:Account]
}

BacktestController.groovy:

        // add Account
        def acct = new SimAccount(name:"backtest")
        // add position
        def pos = new Position(symbol:'SIRI')
        acct.addToPositions(pos)

Strategy.groovy:

    println "apply($accounts, $quotes) [$name]"
    accounts.each{ a ->
        println "  acct $a (${a?.name})"
        a?.positions?.each{ p ->
            println "    pos: $p"
        }
    }

    def siri = Position.findByAccountAndSymbol(accounts[0], 'SIRI')
    println "siri pos: $siri"

The output from Strategy.groovy when the objects have been saved is

apply([com.lossless.account.SimAccount : 1, null], [:]) [Live SIRI 50k]
  acct com.lossless.account.SimAccount : 1 (sim1)
    pos: com.lossless.account.Position : 1
  acct null (null)
siri pos: com.lossless.account.Position : 1

The output when the objects have not been saved is

apply([com.lossless.account.SimAccount : null, null], [bid:1.74, ask:1.74]) [Backtest SIRI 50k]
  acct com.lossless.account.SimAccount : null (backtest)
    pos: com.lossless.account.Position : null
  acct null (null)
| Error 2013-01-21 03:11:11,984 [http-bio-8080-exec-2] ERROR errors.GrailsExceptionResolver  - TransientObjectException occurred when processing request: [POST] /lossless/backtest/index - parameters:
object references an unsaved transient instance - save the transient instance before flushing: com.lossless.account.Account. Stacktrace follows:
Message: object references an unsaved transient instance - save the transient instance before flushing: com.lossless.account.Account
   Line | Method
->> 105 | doCall         in org.grails.datastore.gorm.GormStaticApi$_methodMissing_closure2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|    66 | apply          in com.lossless.Strategy

Line 66 in Strategy.groovy is the call to Position.findByAccountAndSymbol().

greymatter
  • 840
  • 1
  • 10
  • 25
  • Objects added with addTo.. should exist in the class prior to saving. Post your code – James Kleeh Jan 21 '13 at 03:33
  • I don't know about the purpose of your `backtesting` tasks, but it is not a good practice to test your app in production environment. – coderLMN Jan 21 '13 at 03:37
  • @Jinzhao Backtesting is not a form of software test. It is a way to test a trading system against historical data to see how it performs. In this case, it is part of the functionality of the production environment. – greymatter Jan 21 '13 at 07:04
  • @greymatter so it is a kind of statistics and reporting stuff, right? But why does it need to create new data without being saved? – coderLMN Jan 21 '13 at 07:20
  • @JinzhaoWu These tests can generate many objects, and there is no value in storing them in the database. And it makes the test run MUCH slower. My first version of this app used plain Groovy collections with no Grails domain classes. It was fast, but then I had to create domain classes to implement the same algorithms for live trading. In this rewrite of the application, I am trying to reuse the algorithm implementation for both purposes but still only persist the live trading and not the backtesting. I only want transient objects for backtesting. – greymatter Jan 21 '13 at 08:24
  • @greymatter maybe you can leverage [Command Objects](http://grails.org/doc/latest/guide/theWebLayer.html#commandObjects)? – coderLMN Jan 21 '13 at 08:38
  • 1
    I have not tested it but you can try to use the new http://grails.org/doc/2.0.0.RC1/guide/conf.html#multipleDatasources grails functionality. Simply create a second in memory db (default H2 database?) and use the data you don't want to persist with the volatile H2 database. – Fabiano Taioli Jan 21 '13 at 13:45
  • @JinzhaoWu Can you give an example of how Command Objects might be used to solve this? I'm not sure I get the pattern for this use case. – greymatter Jan 21 '13 at 17:01
  • @FabianoTaioli It's an interesting idea, but I have two concerns. First, I think it will still be much slower than transient objects (though obviously better than a disk-based database). Second, if I am also reusing service classes, can this work? I am not sure that the `static datasource` in the service can be set with a variable. I get the feeling that's wired into Spring and can't be changed per invocation. Do you know? – greymatter Jan 21 '13 at 17:21
  • Unfortunally I can't help you any more. I never tested a thing like this. :/ – Fabiano Taioli Jan 22 '13 at 08:37
  • @FabianoTaioli I appreciate your input. – greymatter Jan 22 '13 at 15:25

0 Answers0