-
Notifications
You must be signed in to change notification settings - Fork 0
/
backtest.go
executable file
·70 lines (62 loc) · 2.55 KB
/
backtest.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package main
import (
"fmt"
"sort"
"time"
)
func backtest(data map[string]map[string]float64, account Account, params Params) {
// Initialize the capital
account.capital = account.initial_capital
account.lot_size = 100
open_date := time.Now()
// i is declared to iterate a sequential map
i := 0
keys := make([]time.Time, 0, len(data))
for k := range data {
t, _ := time.Parse("2006-01-02", k)
keys = append(keys, t)
}
sort.Slice(keys, func(i, j int) bool {
return keys[i].Before(keys[j])
})
for _, now_date := range keys {
now_date_string := now_date.Format("2006-01-02")
now_close := data[now_date_string]["Close"]
now_open := data[now_date_string]["Open"]
now_candle := now_close - now_open
// Calculate the equity
account.unrealized_pnl = account.num_of_share*(now_close-account.open_price) - commission(account.open_price*account.num_of_share)
account.equity_value = account.capital + account.unrealized_pnl
account.net_profit = account.equity_value - account.initial_capital
trade_logic := false
if params.candle_dir == "positive" {
trade_logic = now_candle > params.candle_len
} else if params.candle_dir == "negative" {
trade_logic = now_candle < -1*params.candle_len
}
min_cost_cond := account.capital > (now_close * account.lot_size)
//fmt.Printf("%v, %v\n", now_date_string, now_close)
close_logic := now_date.Sub(open_date).Hours()/24 >= params.holding_day
profit_target_cond := (now_close-account.open_price)/account.open_price > params.profit_target
stop_loss_cond := (account.open_price-now_close)/account.open_price > params.stop_loss
last_index_cond := i == len(data)
//fmt.Printf("%v, Trade Logic:%v, Close Logic: %v, Profit: %v, Stop: %v\n", now_date, trade_logic, close_logic, profit_target_cond, stop_loss_cond)
// Open Position
if account.num_of_share == 0 && min_cost_cond && trade_logic && !last_index_cond {
account.num_of_share = get_buyable_share(account.capital, now_close, account.lot_size)
account.open_price = now_close
open_date = now_date
fmt.Printf("Open position: %v at %v\n", now_date_string, now_close)
// Close Position
} else if account.num_of_share > 0 && (profit_target_cond || stop_loss_cond || last_index_cond || close_logic) {
account.realized_pnl = account.unrealized_pnl
account.num_of_share = 0
account.capital += account.realized_pnl
account.num_of_trade += 1
fmt.Printf("Close position: %v at %v\n", now_date_string, now_close)
}
i++
}
fmt.Printf("net_profit: %v\n", account.net_profit)
fmt.Printf("num_of_trade: %v\n", account.num_of_trade)
}