Created
June 20, 2018 13:40
-
-
Save dirkolbrich/4067ecb573a5eb693aa0b6e9330bb528 to your computer and use it in GitHub Desktop.
concept of an algorithm tree - test in the playground https://play.golang.org/p/1fV78iCy_71
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This package demonstrates a concept of a strategy/asset tree, where each | |
// strategy has an algorythm stack. Each strategy can have different child strategies or assets. | |
package main | |
import ( | |
"fmt" | |
) | |
// NodeHandler defines the basic node functionality. | |
type NodeHandler interface { | |
Name() string | |
SetName(string) NodeHandler | |
Parent() NodeHandler | |
SetParent(NodeHandler) NodeHandler | |
Children() []NodeHandler | |
SetChildren(...NodeHandler) NodeHandler | |
IsRoot() bool | |
IsChild() bool | |
Run() | |
} | |
// Node implements NodeHandler. It represents the base information of each tree node. | |
// This is the main building block of the tree. | |
type Node struct { | |
name string | |
parent NodeHandler | |
children []NodeHandler | |
} | |
// Name returns the name of Node | |
func (n Node) Name() string { | |
return n.name | |
} | |
// SetName sets the name of Node | |
func (n *Node) SetName(s string) NodeHandler { | |
n.name = s | |
return n | |
} | |
// Parent return the parent of this Node | |
func (n Node) Parent() NodeHandler { | |
return n.parent | |
} | |
// SetParent sets the parent of this Node | |
func (n *Node) SetParent(p NodeHandler) NodeHandler { | |
n.parent = p | |
return n | |
} | |
// Children returns the children of this Node | |
func (n Node) Children() []NodeHandler { | |
return n.children | |
} | |
// SetChildren sets the Children of this Node | |
func (n *Node) SetChildren(children ...NodeHandler) NodeHandler { | |
for _, child := range children { | |
child.SetParent(n) | |
} | |
n.children = children | |
return n | |
} | |
// IsRoot checks if this Node is a root node | |
func (n Node) IsRoot() bool { | |
if n.parent != nil { | |
return false | |
} | |
return true | |
} | |
// IsChild checks if this Node is a child of another node | |
func (n Node) IsChild() bool { | |
if n.parent == nil { | |
return false | |
} | |
return true | |
} | |
// Run is an empty function to satisfy the interface | |
func (n Node) Run() {} | |
// Strategy implements a sub node, used as a strategy building block | |
type Strategy struct { | |
Node | |
algos []Algo | |
} | |
// NewStrategy return a new strategy node ready to use | |
func NewStrategy(name string) *Strategy { | |
var s = &Strategy{} | |
s.SetName(name) | |
return s | |
} | |
// SetAlgo sets the algo stack for the Strategy | |
func (s *Strategy) SetAlgo(algos ...Algo) *Strategy { | |
for _, algo := range algos { | |
s.algos = append(s.algos, algo) | |
} | |
return s | |
} | |
// Run the algos of this Strategy Node, overwrite base Node method functionality | |
func (s Strategy) Run() { | |
// run algos | |
for _, algo := range s.algos { | |
if !algo.Run() { | |
return | |
} | |
} | |
// check for children and run their algos | |
for _, child := range s.Children() { | |
child.Run() | |
} | |
} | |
// Asset is a data building block, eg. Stock, Option, Cash etc | |
type Asset struct { | |
Node | |
} | |
// NewAsset return a new strategy node ready to use | |
func NewAsset(name string) *Asset { | |
var a = &Asset{} | |
a.SetName(name) | |
return a | |
} | |
// Children is an nil return, an Asset is not allowed to have children | |
func (a Asset) Children() []NodeHandler { | |
return []NodeHandler{} | |
} | |
// SetChildren does nothing, as an Asset ist not allowed to have children. | |
func (a *Asset) SetChildren(c ...NodeHandler) NodeHandler { | |
return a | |
} | |
// Algo defines the base algorythm functionality | |
type Algo interface { | |
Run() bool | |
} | |
// BasicAlgo is a base Algo which always returns true | |
type BasicAlgo struct { | |
} | |
// Run runs the algo | |
func (a BasicAlgo) Run() bool { | |
fmt.Println("running basic algo, return true") | |
return true | |
} | |
// FailAlgo is an algo which always fails | |
type FailAlgo struct { | |
} | |
// Run runs the algo | |
func (a FailAlgo) Run() bool { | |
fmt.Println("failing algo, return false") | |
return false | |
} | |
// NeverAlgo is an Algo which never gets called | |
type NeverAlgo struct { | |
} | |
// Run runs the algo | |
func (a NeverAlgo) Run() bool { | |
fmt.Println("never running algo, should return true") | |
return true | |
} | |
func main() { | |
// define main strategy | |
main := NewStrategy("main").SetAlgo( | |
BasicAlgo{}, | |
) | |
// define second strategy | |
sec := NewStrategy("sec").SetAlgo( | |
// define an algo stack | |
BasicAlgo{}, | |
FailAlgo{}, | |
NeverAlgo{}, | |
) | |
// define the tree from the bottom up | |
sec.SetChildren( | |
NewAsset("DBK.DE"), | |
) | |
main.SetChildren( | |
sec, | |
NewAsset("TEST.DE"), | |
NewAsset("BAS.DE"), | |
) | |
fmt.Printf("main: %+v\n", main) | |
fmt.Printf("main parent: %+v\n", main.Parent()) | |
fmt.Printf("main is root: %+v\n", main.IsRoot()) | |
fmt.Printf("main children:%+v\n", main.Children()) | |
for _, child := range main.Children() { | |
fmt.Printf("child: %v, with parent: %v, is child: %+v\n", child.Name(), child.Parent().Name(), child.IsChild()) | |
} | |
fmt.Printf("sec: %+v\n", sec) | |
fmt.Printf("sec parent: %+v\n", sec.Parent()) | |
main.Run() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment