1 | var util = require('./util.js');
|
2 | var _ = require('underscore');
|
3 | var log = require('./log.js');
|
4 | var moment = require('moment');
|
5 |
|
6 | var Logger = function(config) {
|
7 | this.config = util.getConfig();
|
8 | this.verbose = config.verbose;
|
9 | this.fee = 1 - config.fee / 100;
|
10 |
|
11 | this.reportInCurrency = config.reportInCurrency;
|
12 | if(this.reportInCurrency)
|
13 | this.reportIn = config.currency;
|
14 | else
|
15 | this.reportIn = config.asset;
|
16 |
|
17 |
|
18 | this.start = {
|
19 | asset: config.simulationBalance.asset,
|
20 | currency: config.simulationBalance.currency,
|
21 | balance: false
|
22 | }
|
23 | this.current = {
|
24 | asset: this.start.asset,
|
25 | currency: this.start.currency,
|
26 | balance: false
|
27 | }
|
28 | this.trades = 0;
|
29 | this.tracks = 0;
|
30 |
|
31 | _.bindAll(this);
|
32 |
|
33 | if(config.enabled)
|
34 | log.info('Profit reporter active on simulated balance');
|
35 | }
|
36 |
|
37 |
|
38 | Logger.prototype.inform = function(what, price, meta) {
|
39 | if(!this.verbose && what !== 'SELL' && !this.config.backtest)
|
40 | return;
|
41 |
|
42 | if(!this.verbose && what === 'HOLD' && this.config.backtest)
|
43 | return;
|
44 |
|
45 | log.info('ADVICE is to', what, meta);
|
46 | }
|
47 |
|
48 | Logger.prototype.extractFee = function(amount) {
|
49 | amount *= 100000000;
|
50 | amount *= this.fee;
|
51 | amount = Math.floor(amount);
|
52 | amount /= 100000000;
|
53 | return amount;
|
54 | }
|
55 |
|
56 |
|
57 |
|
58 | Logger.prototype.trackProfits = function(what, price, meta) {
|
59 | this.tracks++;
|
60 |
|
61 |
|
62 | if(!this.start.balance) {
|
63 | if(this.reportInCurrency)
|
64 | this.start.balance = this.start.currency + price * this.start.asset;
|
65 | else
|
66 | this.start.balance = this.start.asset + this.start.currency / price;
|
67 | }
|
68 |
|
69 |
|
70 | if(what === 'BUY') {
|
71 | this.current.asset += this.extractFee(this.current.currency / price);
|
72 | this.current.currency = 0;
|
73 | this.trades++;
|
74 | }
|
75 |
|
76 |
|
77 | if(what === 'SELL') {
|
78 | this.current.currency += this.extractFee(this.current.asset * price);
|
79 | this.current.asset = 0;
|
80 | this.trades++;
|
81 | }
|
82 |
|
83 | if(this.reportInCurrency)
|
84 | this.current.balance = this.current.currency + price * this.current.asset;
|
85 | else
|
86 | this.current.balance = this.current.asset + this.current.currency / price;
|
87 |
|
88 | this.profit = this.current.balance - this.start.balance;
|
89 | this.relativeProfit = this.current.balance / this.start.balance * 100 - 100;
|
90 |
|
91 | if(this.tracks === 1)
|
92 | return;
|
93 |
|
94 | if(!this.verbose && what === 'SELL' && !this.config.backtest)
|
95 | this.report();
|
96 | else if(this.verbose && !this.config.backtest)
|
97 | this.report();
|
98 | }
|
99 |
|
100 | Logger.prototype.finish = function(data) {
|
101 | var round = function(amount) {
|
102 | return amount.toFixed(3);
|
103 | }
|
104 |
|
105 | console.log();
|
106 | console.log();
|
107 |
|
108 | log.info('\tWARNING: BACKTESTING FEATURE NEEDS PROPER TESTING')
|
109 | log.info('\tWARNING: ACT ON THESE NUMBERS AT YOUR OWN RISK!')
|
110 |
|
111 | console.log();
|
112 | console.log();
|
113 |
|
114 | var start = moment.unix(data.startTime);
|
115 | var end = moment.unix(data.endTime);
|
116 | var timespan = end.diff(start, 'days');
|
117 |
|
118 | log.info(
|
119 | '(PROFIT REPORT)',
|
120 | 'start time:\t\t\t',
|
121 | start.format('YYYY-MM-DD HH:mm:ss')
|
122 | );
|
123 |
|
124 | log.info(
|
125 | '(PROFIT REPORT)',
|
126 | 'end time:\t\t\t',
|
127 | end.format('YYYY-MM-DD HH:mm:ss')
|
128 | );
|
129 |
|
130 | log.info(
|
131 | '(PROFIT REPORT)',
|
132 | 'timespan:\t\t\t',
|
133 | timespan,
|
134 | 'days'
|
135 | );
|
136 |
|
137 | console.log();
|
138 |
|
139 | log.info(
|
140 | '(PROFIT REPORT)',
|
141 | 'start price:\t\t\t',
|
142 | data.start
|
143 | );
|
144 |
|
145 | log.info(
|
146 | '(PROFIT REPORT)',
|
147 | 'end price:\t\t\t',
|
148 | data.end
|
149 | );
|
150 |
|
151 | log.info(
|
152 | '(PROFIT REPORT)',
|
153 | 'Buy and Hold profit:\t\t',
|
154 | round((data.end - data.start) / data.start * 100) + '%'
|
155 | );
|
156 |
|
157 | console.log();
|
158 |
|
159 | log.info(
|
160 | '(PROFIT REPORT)',
|
161 | 'amount of trades:\t\t',
|
162 | this.trades
|
163 | );
|
164 |
|
165 | this.report(timespan);
|
166 | }
|
167 |
|
168 | Logger.prototype.report = function(timespan) {
|
169 | var round = function(amount) {
|
170 | return amount.toFixed(3);
|
171 | }
|
172 |
|
173 | log.info(
|
174 | '(PROFIT REPORT)',
|
175 | 'original simulated balance:\t',
|
176 | round(this.start.balance),
|
177 | this.reportIn
|
178 | );
|
179 |
|
180 | log.info(
|
181 | '(PROFIT REPORT)',
|
182 | 'current simulated balance:\t',
|
183 | round(this.current.balance),
|
184 | this.reportIn
|
185 | );
|
186 |
|
187 | log.info(
|
188 | '(PROFIT REPORT)',
|
189 | 'simulated profit:\t\t',
|
190 | round(this.profit),
|
191 | this.reportIn,
|
192 | '(' + round(this.relativeProfit) + '%)'
|
193 | );
|
194 |
|
195 | if(timespan) {
|
196 | var timespanPerYear = 356 / timespan;
|
197 |
|
198 | log.info(
|
199 | '(PROFIT REPORT)',
|
200 | 'simulated yearly profit:\t',
|
201 | round(this.profit * timespanPerYear),
|
202 | this.reportIn,
|
203 | '(' + round(this.relativeProfit * timespanPerYear) + '%)'
|
204 | );
|
205 | }
|
206 | }
|
207 |
|
208 |
|
209 |
|
210 | module.exports = Logger; |
\ | No newline at end of file |