The Forex trading system requires additional functionality to be complete, so let’s start to add more. The first functions to add functionality to, such as stop loss or take profit, define the capital to be invested.
The first function we add is to take profits. The code for that is def take_profit(pip:Int):this.type ={
this._pip_profit = pip
this._max_capital_profit =(this._capital+(this._pip_value * pip)) this
}
The take_profit function has the parameter pip. This indicates the number of PIP we can accept to lose before closing the position. Internally, the function defines the value max_capital_profit. This is used to
calculate the new capital and close the position.
Note The function uses this.type to define the return type. This is used in Scala to return the type of method. Because we still have a fluent API pattern, we must be clear about what type we must return.
Using this.type allows the function to return the type at runtime,
without specifying the type of return first. This is useful when we
build a DSL, in particular, when we want functionality that can have
more than one type of return.
175 The other function we can add is stop_loss. This is used to close the position when it loses too much PIP. The function looks like this:
def stop_loss(pip:Int):this.type ={
this._pip_lost = pip
this._max_capital_lost = (this._capital-(this._pip_value * pip)) this
}
We can see that the function is similar to take_profit. At the end, both have the same function: they continue to add functionality to the system.
The end of the code looks like this:
import scala.annotation.switch import scala.math.BigDecimal package com {
package practicalscala { package v1 {
class TradingSystem {
protected var _pair: String = ""
protected var _pip_value: BigDecimal = 0.0 protected var _pip_profit:Int = 0
protected var _pip_lost:Int = 0
protected var _start_position:BigDecimal =0.0 protected var _actual_value:BigDecimal = 0.0 protected var _capital:BigDecimal = 0
protected var _max_capital_lost:BigDecimal = 0 protected var _max_capital_profit:BigDecimal =0
def pair(first: String, second: String): this.type = { this._pair = s"$first/$second"
this }
176
def account(_type:String):this.type = { this._pip_value = (_type: @switch) match { case "MICRO" => 0.1
case "MINI" => 1 case "STANDARD" => 10 }
this }
def take_profit(pip:Int):this.type ={
this._pip_profit = pip
this._max_capital_profit =(this._capital+(this._pip_
value * pip)) this
}
def stop_loss(pip:Int):this.type ={
this._pip_lost = pip
this._max_capital_lost = (this._capital-(this._pip_
value * pip)) this
}
def start_position(start_value:Double):this.type ={
this._start_position=start_value this
}
def actual_position(actual_value:Double):this.type ={
this._actual_value=actual_value this
}
177 def capital(investment:Int):this.type ={
this._capital=investment this
}
def execute() ={
val _gain=(this._actual_value - this._start_position) val _check_profit =((_gain * this._pip_value) + _
capital)
if(_check_profit > _max_capital_profit){
println("Max Profit gain")
}else if(_check_profit > _max_capital_lost){
println("Stop loss gain") }
println("PIP gained:"+_gain)
println("Actual Capital:"+_check_profit) }
} } } }
You can see that BigDecimal has been imported. This is used in Scala to define the currency type. Because a currency can have more decimal numbers, BigDecimal helps to define that. The function that has changed most is execute. This essentially is the core of the system. This calculates the gain and checks the profit. If the value is as specified, we close the position, whether there is a gain or loss.
Now let’s see how we can use the Forex trading system to set a position that takes a profit and stops a loss.
178
import com.practicalscala.v1._
object TestMain{
def main(args:Array[String]):Unit ={
val _pair = new TradingSystem() println(_pair.pair("USD","EUR") .account("MINI")
println(_pair.pair("USD","EUR") .account("MINI")
We create a chain to call the method. We specify the currency pair, the kind of account, the start position, the value at which we buy the currency, the actual position, the position updated, the stop loss and the take profit, and, finally, the capital.
At the end, we call execute, to determine whether we have as a result of the position a gain or loss. Of course, it is best to connect the system with a real-time Forex and let it change the value. In this case, we can use the system for real.
179 When we execute the system, we have a result such as the following:
Max Profit gain PIP gained:0.0099
Actual Capital:10000.0099 Stop loss gain
PIP gained:-0.0101 Actual Capital:9999.9899
The system calculates the PIP gained or lost and updates the capital.
Then, based on the PIP, it decides what is needed to close the position.
Conclusion
You have now seen how to use a DSL to create a trading system. This is not complex; we only need to re-think how we work every day.
The big advantage of using a DSL is how easily it reads the code and how simple it is to understand. Another small advantage is the complexity of the function. Because we define a method chain, we can write very simple functions that can be connected. This allows us to write a simple functionality that we can connect with others to solve big problems, write simple functions, and simplify the maintenance of the code itself. It is always easier to maintain a small function than one with more than one hundred lines of code.
In this chapter, you discovered additional Scala functionality, such as the switch notation and this.type, both of which allow us to write simple and efficient code, which, of course, is crucial when we want write a good DSL.
In the next chapter, I will discuss another important topic: games. You will see how to build a video game using a DSL.
181
© Pierluigi Riti 2018
P. Riti, Practical Scala DSLs, https://doi.org/10.1007/978-1-4842-3036-7_10