summaryrefslogtreecommitdiffstats
path: root/kmymoney2/mymoney/mymoneyforecast.h
blob: 6fa231c92683b291705f660a82f04c9fc85de6a7 (plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
/***************************************************************************
                          mymoneyforecast.h
                             -------------------
    begin                : Wed May 30 2007
    copyright            : (C) 2007 by Alvaro Soliverez
    email                : asoliverez@gmail.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef MYMONEYFORECAST_H
#define MYMONEYFORECAST_H

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

// ----------------------------------------------------------------------------
// QT Includes

#include <tqmap.h>
#include <tqvaluelist.h>
#include <tqstring.h>

// ----------------------------------------------------------------------------
// Project Includes

#include <kmymoney/mymoneyobject.h>
#include <kmymoney/mymoneyaccount.h>
#include <kmymoney/mymoneymoney.h>
#include <kmymoney/mymoneyscheduled.h>
#include <kmymoney/export.h>
#include "mymoneybudget.h"

/**
  *
  *
  * @author Alvaro Soliverez <asoliverez@gmail.com>
  */

class MyMoneyForecast
{
public:
  MyMoneyForecast();
  ~MyMoneyForecast();

  /**
   * calculate forecast based on historic transactions
   */
  void doForecast();

  /**
   * Returns the list of accounts to be forecast.
   */
  TQValueList<MyMoneyAccount> accountList(void);

  /**
   * Returns the balance trend for account @a acc based on a number of days @p forecastDays
   * Collects and processes all transactions in the past for the
   * same period of forecast and calculates the balance trend
   */
  static MyMoneyMoney calculateAccountTrend(const MyMoneyAccount& acc, int forecastDays);

  /**
   * Returns the forecast balance trend for account @a acc for day @p TQDate
   */
  MyMoneyMoney forecastBalance(const MyMoneyAccount& acc, TQDate forecastDate);

  /**
   * Returns the forecast balance trend for account @a acc for offset @p int
   * offset is days from current date, inside forecast days.
   * Returns 0 if offset not in range of forecast days.
   */
  MyMoneyMoney forecastBalance(const MyMoneyAccount& acc, int offset);

  /**
   * Returns true if an account @a acc is an account to be forecast
   */
  bool isForecastAccount(const MyMoneyAccount& acc);

  /**
   * returns the number of days when a given account is forecast to be below minimum balance
   * returns -1 if it will not be below minimum balance in the forecast period
   */
  int daysToMinimumBalance(const MyMoneyAccount& acc);

  /**
   * returns the number of days when a given account is forecast to be below zero if it is an asset accounts
   * or above zero if it is a liability account
   * returns -1 if it will not happen in the forecast period
   */
  int daysToZeroBalance(const MyMoneyAccount& acc);

  /**
   * amount of variation of a given account in one cycle
   */
  MyMoneyMoney accountCycleVariation(const MyMoneyAccount& acc);

  /**
   * amount of variation of a given account for the whole forecast period
   */
  MyMoneyMoney accountTotalVariation(const MyMoneyAccount& acc);

  /**
   * returns a list of the dates where the account was on its lowest balance in each cycle
   */
  TQValueList<TQDate> accountMinimumBalanceDateList(const MyMoneyAccount& acc);

  /**
   * returns a list of the dates where the account was on its highest balance in each cycle
   */
  TQValueList<TQDate> accountMaximumBalanceDateList(const MyMoneyAccount& acc);

  /**
   * returns the average balance of the account within the forecast period
   */
  MyMoneyMoney accountAverageBalance(const MyMoneyAccount& acc);

  /**
   * creates a budget based on the history of a given timeframe
   */
  void createBudget(MyMoneyBudget& budget, TQDate historyStart, TQDate historyEnd, TQDate budgetStart, TQDate budgetEnd, const bool returnBudget);

  /**
   * number of days to go back in history to calculate forecast
   */
  int historyDays(void) const { return (m_historyStartDate.daysTo(m_historyEndDate) + 1); }

  void setAccountsCycle(int accountsCycle)   { m_accountsCycle = accountsCycle; }
  void setForecastCycles(int forecastCycles)   { m_forecastCycles = forecastCycles; }
  void setForecastDays(int forecastDays)   { m_forecastDays = forecastDays; }
  void setBeginForecastDate(TQDate beginForecastDate) { m_beginForecastDate = beginForecastDate; }
  void setBeginForecastDay(int beginDay)   { m_beginForecastDay = beginDay; }
  void setForecastMethod(int forecastMethod) { m_forecastMethod = forecastMethod; }
  void setHistoryStartDate(TQDate historyStartDate) { m_historyStartDate = historyStartDate; }
  void setHistoryEndDate(TQDate historyEndDate) { m_historyEndDate = historyEndDate; }
  void setHistoryStartDate(int daysToStartDate) { setHistoryStartDate(TQDate::currentDate().addDays(-daysToStartDate)); }
  void setHistoryEndDate(int daysToEndDate) { setHistoryEndDate(TQDate::currentDate().addDays(-daysToEndDate)); }
  void setForecastStartDate(TQDate _startDate) { m_forecastStartDate = _startDate; }
  void setForecastEndDate(TQDate _endDate) { m_forecastEndDate = _endDate; }
  void setSkipOpeningDate(bool _skip) { m_skipOpeningDate = _skip; }
  void setHistoryMethod(int historyMethod) { m_historyMethod = historyMethod; }
  void setIncludeUnusedAccounts(bool _bool) { m_includeUnusedAccounts = _bool; }
  void setForecastDone(bool _bool) { m_forecastDone = _bool; }
  void setIncludeFutureTransactions(bool _bool) { m_includeFutureTransactions = _bool; }
  void setIncludeScheduledTransactions(bool _bool) { m_includeScheduledTransactions = _bool; }

  int accountsCycle(void) const   { return m_accountsCycle; }
  int forecastCycles(void) const   { return m_forecastCycles; }
  int forecastDays(void) const { return m_forecastDays; }
  TQDate beginForecastDate(void) const   { return m_beginForecastDate; }
  int beginForecastDay(void) const   { return m_beginForecastDay; }
  int forecastMethod(void) const   { return m_forecastMethod; }
  TQDate historyStartDate(void) const { return m_historyStartDate; }
  TQDate historyEndDate(void) const { return m_historyEndDate; }
  TQDate forecastStartDate(void) const { return m_forecastStartDate; }
  TQDate forecastEndDate(void) const { return m_forecastEndDate; }
  bool skipOpeningDate(void) const { return m_skipOpeningDate; }
  int historyMethod(void) const   { return m_historyMethod; }
  bool isIncludingUnusedAccounts(void) const { return m_includeUnusedAccounts; }
  bool isForecastDone(void) const { return m_forecastDone; }
  bool isIncludingFutureTransactions(void) const { return m_includeFutureTransactions; }
  bool isIncludingScheduledTransactions(void) const { return m_includeScheduledTransactions; }

  /**
    * This method modifies a scheduled loan transaction such that all
    * references to automatic calculated values are resolved to actual values.
    *
    * @param schedule const reference to the schedule the transaction is based on
    * @param transaction reference to the transaction to be checked and modified
    * @param balances TQMap of (account-id,balance) pairs to be used as current balance
    *                 for the calculation of interest. If map is empty, the engine
    *                 will be interrogated for current balances.
    */
  static void calculateAutoLoan(const MyMoneySchedule& schedule, MyMoneyTransaction& transaction, const TQMap<TQString, MyMoneyMoney>& balances);

private:

  enum EForecastMethod {eScheduled = 0, eHistoric = 1 };

  /**
   * daily balances of an account
   */
  typedef TQMap<TQDate, MyMoneyMoney> dailyBalances;

  /**
   * map of trends of an account
   */
  typedef TQMap<int, MyMoneyMoney> trendBalances;

  /**
   * Returns the list of accounts to be forecast. Only Asset and Liability are returned.
   */
  static TQValueList<MyMoneyAccount> forecastAccountList(void);

  /**
   * Returns the list of accounts to create a budget. Only Income and Expenses are returned.
   */
  TQValueList<MyMoneyAccount> budgetAccountList(void);

  /**
   * calculate daily forecast balance based on historic transactions
   */
  void calculateHistoricDailyBalances(void);

  /**
   * calculate monthly budget balance based on historic transactions
   */
  void calculateHistoricMonthlyBalances();

  /**
   * calculate monthly budget balance based on historic transactions
   */
  void calculateScheduledMonthlyBalances();

  /**
   * calculate forecast based on future and scheduled transactions
   */
  void doFutureScheduledForecast(void);

  /**
   * add future transactions to forecast
   */
  void addFutureTransactions(void);

  /**
   * add scheduled transactions to forecast
   */
  void addScheduledTransactions (void);

  /**
   * calculate daily forecast balance based on future and scheduled transactions
   */
  void calculateScheduledDailyBalances(void);

  /**
   * set the starting balance for an accounts
   */
  void setStartingBalance(const MyMoneyAccount& acc);

  /**
   * Returns the day moving average for the account @a acc based on the daily balances of a given number of @p forecastTerms
   * It returns the moving average for a given @p trendDay of the forecastTerm
   * With a term of 1 month and 3 terms, it calculates the trend taking the transactions occured
   * at that day and the day before,for the last 3 months
   */
  MyMoneyMoney accountMovingAverage(const MyMoneyAccount& acc, const int trendDay, const int forecastTerms);

  /**
   * Returns the weighted moving average for a given @p trendDay
   */
  MyMoneyMoney accountWeightedMovingAverage(const MyMoneyAccount& acc, const int trendDay, const int totalWeight);

  /**
   * Returns the linear regression for a given @p trendDay
   */
  MyMoneyMoney accountLinearRegression(const MyMoneyAccount &acc, const int trendDay, const int totalWeight, const MyMoneyMoney meanTerms);

  /**
   * calculate daily forecast trend based on historic transactions
   */
  void calculateAccountTrendList(void);

  /**
   * set the internal list of accounts to be forecast
   */
  void setForecastAccountList(void);

  /**
   * set the internal list of accounts to create a budget
   */
  void setBudgetAccountList(void);

  /**
   * get past transactions for the accounts to be forecast
   */
  void pastTransactions(void);

  /**
   * calculate the day to start forecast and sets the begin date
   * The quantity of forecast days will be counted from this date
   * Depends on the values of begin day and accounts cycle
   * The rules to calculate begin day are as follows:
   * - if beginDay is 0, begin date is current date
   * - if the day of the month set by beginDay has not passed, that will be used
   * - if adding an account cycle to beginDay, will not go past the beginDay of next month,
   *   that date will be used, otherwise it will add account cycle to beginDay until it is past current date
   * It returns the total amount of Forecast Days from current date.
   */
  int calculateBeginForecastDay();

  /**
   * remove accounts from the list if the accounts has no transactions in the forecast timeframe.
   * Used for scheduled-forecast method.
   */
  void purgeForecastAccountsList(TQMap<TQString, dailyBalances>& accountList);

  /**
   * daily forecast balance of accounts
   */
  TQMap<TQString, dailyBalances> m_accountList;

  /**
   * daily past balance of accounts
   */
  TQMap<TQString, dailyBalances> m_accountListPast;

  /**
   * daily forecast trends of accounts
   */
  TQMap<TQString, trendBalances> m_accountTrendList;

  /**
   * list of forecast accounts
   */
  TQMap<TQString, TQString> m_nameIdx;

  /**
   * cycle of accounts in days
   */
  int m_accountsCycle;

  /**
   * number of cycles to use in forecast
   */
  int m_forecastCycles;

  /**
   * number of days to forecast
   */
  int m_forecastDays;

  /**
   * date to start forecast
   */
  TQDate m_beginForecastDate;

  /**
   * day to start forecast
   */
  int m_beginForecastDay;

  /**
   * forecast method
   */
  int m_forecastMethod;

  /**
   * history method
   */
  int m_historyMethod;

  /**
   * start date of history
   */
  TQDate m_historyStartDate;

  /**
   * end date of history
   */
  TQDate m_historyEndDate;

  /**
   * start date of forecast
   */
  TQDate m_forecastStartDate;

  /**
   * end date of forecast
   */
  TQDate m_forecastEndDate;

  /**
   * skip opening date when fetching transactions of an account
   */
  bool m_skipOpeningDate;

  /**
   * include accounts with no transactions in the forecast timeframe. default is false.
   */
  bool m_includeUnusedAccounts;

  /**
   * forecast already done
   */
  bool m_forecastDone;

  /**
   * include future transactions when doing a scheduled-based forecast
   */
  bool m_includeFutureTransactions;

  /**
   * include scheduled transactions when doing a scheduled-based forecast
   */
  bool m_includeScheduledTransactions;

};

#endif // MYMONEYFORECAST_H