Trading System API  3.0
Library for Simulating and Deploying Trading and Investment Strategies
TSAPosition.h
1 /* ===================================================================
2 *
3 * T R A D I N G S Y S T E M A P I ™
4 * Copyright © 1999 - 2014 by Peter Ritter ( TradingSystemAPI.com )
5 * A L L R I G H T S R E S E R V E D
6 *
7 * Consult your license regarding permissions and restrictions.
8 * You may obtain a copy of the License at:
9 * http://www.TradingSystemAPI.com/licenses/LICENSE-TSAPI-3.0.html
10 *
11 * ====================================================================
12 */
13 
14 #ifndef TSA_POSITION__INCLUDED
15 #define TSA_POSITION__INCLUDED
16 
17 #include <map>
18 #include <list>
19 #include <vector>
20 #include <ostream>
21 
22 #include "TSATypeDef.h"
23 #include "TSATime.h"
24 #include "TSAOrder.h"
25 #include "TSAMemTable.h"
26 #include "TSASimBaseSeries.h"
27 #include "TSAString.h"
28 #include "TSAMetrics.h"
29 #include "TSAMetrics2.h"
30 
31 namespace tsa {
32 
33  /*
34  ** ====================================================
35  ** > > > class position_manager < < <
36  ** ====================================================
37  */
38  // Internal
39  class dll_export position_manager : public object {
40  tsa_declare_testable;
41  private:
42  position_t m_curr_position;
43  position_t m_prev_position;
44  public:
45  position_manager(void);
46  virtual ~position_manager(void);
47  position_t position(void) const;
48  position_t inverse_position(void) const;
49  quantity_t position_size(void) const;
50  position_t previous_position(void) const;
51  POSITION::state position_state() const;
52  bool position_is_long(void) const;
53  bool position_is_short(void) const;
54  bool position_is_flat(void) const;
55  bool position_direction_has_changed(void) const;
56  void notify_long_transaction(quantity_t units);
57  void notify_short_transaction(quantity_t units);
58  POSITION::state long_trade_new_dir_state(quantity_t size) const;
59  POSITION::state short_trade_new_dir_state(quantity_t size) const;
60  };
61 
62  /*
63  ** ====================================================
64  ** > > > class trade_leg < < <
65  ** ====================================================
66  */
67 
71  struct dll_export trade_leg {
72  public:
74  double price;
78  bool had_slippage;
79  public:
80  trade_leg(void) :
81  quantity(0), price(0.0), action(order::oa_undefined) {}
82  };
83 
84  /*
85  ** ====================================================
86  ** > > > class trade_manager < < <
87  ** ====================================================
88  */
89  // Internal
90  class dll_export trade_manager : public position_manager {
91  tsa_declare_testable;
92  private:
93  date_time m_prev_trade_value_timestamp;
94  date_time m_latest_trade_value_timestamp;
95  quantity_t m_max_num_units_in_position = 0;
96  size_t m_bar_count = 0;
97  double m_latest_trade_value = 0.0;
98  double m_min_trade_value = 0.0;
99  double m_max_trade_value = 0.0;
100  double m_prev_trade_value = 0.0;
101  double m_big_point_value = 1.0;
102  double m_trade_entry_leg_price = 0.0;
103  double m_furthest_price = 0;
104  double m_last_interval_price = 0.0;
105  std::vector<trade_leg> m_trade_legs;
106  public:
107  double m_closed_out_PL = 0.0;
108  double m_avg_entry_price = 0.0;
109  position_t m_open_position_size = 0;
110  POSITION::state m_open_position_dir = POSITION::is_flat;
111  size_t m_leg_count__no_slippage = 0;
112  public:
113  quantity_t m_stats__total_num_units = 0;
114  quantity_t m_stats__num_units__no_slippage = 0;
115  quantity_t m_stats__num_units__at_market = 0;
116  quantity_t m_stats__num_units__on_stop = 0;
117  quantity_t m_stats__num_units__at_limit = 0;
118  quantity_t m_stats__num_units__other = 0;
119  private:
120  void clear_leg_array(void);
121  public:
122  const std::vector<trade_leg>& current_trade_legs(void)const;
123  public:
124  trade_manager(void);
125  virtual ~trade_manager(void);
126  void set_big_point_value__base_ccy(double big_point_value);
127  double get_big_point_value__base_ccy(void) const;
128  void set_latest_instrument_price(double);
129  public:
130  double best_price_since_trade_entry(void) const;
131  double initial_trade_leg_price(void) const;
132  double current_trade_value(void) const;
133  double max_trade_value(void) const;
134  double min_trade_value(void) const;
135  size_t bar_count_since_trade_entry(void) const;
136  double most_recent_change_in_position_value(void);
137  const date_time& most_recent_bar_timestamp(void) const;
138  const date_time& initial_trade_leg_timestamp(void) const;
139  size_t position_leg_count(void) const;
140  public:
141  void notify__long_transaction(quantity_t units, double price,
142  const date_time&, bool incurred_slippage, order::type);
143  void notify__short_transaction(quantity_t units, double price,
144  const date_time&, bool incurred_slippage, order::type);
145  void increment_bar_count(void);
146  void add_trade_leg(order::action dir, quantity_t units, double price,
147  const date_time&, bool incurred_slippage, order::type type);
148  public:
149  double position_value__fast(double mkt_price)const;//new
150  double most_recent_bar_price(void) const;
151  bool try_long_transaction_will_change_position_state(quantity_t);
152  bool try_short_transaction_will_change_position_state(quantity_t);
153  void update_position_value_and_increment_bar(double price, const date_time& timestamp);
154  quantity_t max_position_size(void) const;
155  void reset_position(void);
156  quantity_t units_required_to_close_out_trade(void);
157  public:
158  size_t leg_count__no_slippage(void)const;
159  void trade_metrics(quantity_t& total_quantity,
160  quantity_t& units__no_slippage, quantity_t& units_at_market,
161  quantity_t& units_on_stop, quantity_t& units_at_limit, quantity_t& units_other);
162  public:
163  static double calculate_rounded_quantity_from_cash_amount(double unit_price, double cash_amount);
164  public:
165  void print_position_info(std::ostream&) const;
166  public:
167  position_t test__calculate_net_position_from_legs(void) const;
168  private:
169  void test__calculate_trade_metrics(double& total_quantity,
170  double& units__no_slippage, double& units_at_market,
171  double& units_on_stop, double& units_at_limit, double& units_other) const;
172  size_t test__calc_position_leg_count__no_slippage(void) const;
173  quantity_t test__calculate_total_num_units_from_legs(void) const;
174  bool test__check_all_trade_legs_have_same_direction(void) const;
175  void test__notify_long_transaction(quantity_t units, double price);
176  void test__notify_short_transaction(quantity_t units, double price);
177  double test__calc_position_value_base_ccy(double price) const;
178  double test__calc_position_val_and_incr_interval__base_ccy_TEST(double price);
179  void test__calculate_position_value(double mkt_price, double& pos_val) const;
180  };
181 
183  struct trade_info {
184  size_t trade_ID;
185  POSITION::state direction;
188  double net_profit;
189  double gross_profit;
190  size_t num_bars;
191  double slippage;
192  double commission;
204  bool is_open;
205  };
206 
207  /*
208  ** ====================================================
209  ** >>> class trade_metrics <<<
210  ** ====================================================
211  */
212 
213  // Internal
214  // Keeps list of all trades, and once the strategy has ended
215  // runns a series of analytics to determine trade metrics.
216 
217  class dll_export trade_metrics : public object {
218  private:
219  struct trade_stats : public metrics_container {
220  int64_t trade_count = 0;
221  int64_t loser_count = 0;
222  int64_t winner_count = 0;
223  double percent_profitable = 0;
224  double avg_net_trade_pl = 0;
225  double avg_gross_trade_pl = 0;
226  double avg_winner = 0;
227  double avg_loser = 0;
228  double avg_trade_bar_count = 0;
229  int64_t num_bars_in_trade = 0;
230  double percent_bars_in_trade = 0;
231  int64_t total_winner_bar_count = 0;
232  int64_t total_loser_bar_count = 0;
233  double winners_net = 0;
234  double losers_net = 0;
235  double max_loser = 0;
236  double max_winner = 0;
237  double net_profit = 0;
238  double gross_profit = 0;
239  double max_closed_out_runup = 0;
240  double max_closed_out_rundown = 0;
241  double total_slippage = 0;
242  double total_commission = 0;
243  double total_transaction_cost = 0;
244  double avg_winner_bar_count = 0;
245  double avg_loser_bar_count = 0;
246  double stddev_trade_pl = 0;
247  int64_t max_consec_winners = 0;
248  int64_t max_consec_losers = 0;
249  int64_t max_trade_transaction_count = 0;
250  int64_t max_trade_position_size = 0;
251  double avg_trade_transaction_count = 0;
252  double avg_trade_position_size = 0;
253  double avg_transaction_size = 0;
254  double max_pos_excursion = 0;
255  double max_neg_excursion = 0;
256  double avg_pos_excursion = 0;
257  double avg_neg_excursion = 0;
258  int64_t num_units_traded = 0;
260  int64_t num_units_traded_at_market = 0;
261  int64_t num_units_traded_on_stop = 0;
262  int64_t num_units_traded_at_limit = 0;
263  int64_t num_units_traded_other = 0;
264  double avg_trade_commission = 0;
265  double avg_trade_slippage = 0;
266  double avg_trade_cost = 0;
267  double avg_slippage_per_unit = 0;
268  double avg_cost_per_unit = 0;
270  double avg_net_profit_per_unit = 0;
271  double avg_gross_profit_per_unit = 0;
272  double avg_gain_to_avg_loss_ratio = 0;
273  double profit_factor = 0;
274  bool last_trade_is_open = 0;
275  };
276  trade_stats trade_stats__all;
277  trade_stats trade_stats__long;
278  trade_stats trade_stats__short;
279  trade_stats* m_stats[3];
280  size_t m_num_bars__strategy;
281  protected:
282  std::vector<basic_trade_info> m_basic_trade_info_arr;
283  std::vector<trade_info> m_trades;
284  bool m_trade_log_disabled;
285  bool m_is_finalized;
286  void populate_basic_trade_info(void);
287  void finalize_group(trade_grouping);
288  void DEBUG_POST_FINALIZE_CHECKS(void) const;
289  public:
291  const std::vector<trade_info>& get_trade_vector(void)const { return m_trades; }
292  const std::vector<basic_trade_info>& get_basic_trade_vector(void)const { return m_basic_trade_info_arr; }
293  public:
294  trade_metrics(void);
295  virtual ~trade_metrics(void);
296  void notify_trade(const trade_info&);
297  void disable_internal_log(bool _b);
298  bool internal_log_disabled(void) const;
299  // Notify a new bar in the strategy
300  void notify_bar(void);
301  void finalize(void);
302  public:
303  const trade_info& operator[](size_t) const;
304  size_t trade_count(void) const;
305  size_t num_bars_processed(void)const { return m_num_bars__strategy; }
306  public:
307  template<typename T>
308  T metric(perf_metric_type _metric_type, trade_grouping t = all_trades) const {
309  return get_metric(_metric_type, _aggr).get<T>();
310  }
311 
312  variant get_metric(perf_metric_type _metric_type, trade_grouping gr = all_trades) const;
313  variant get_metric(const std::string& metric_name, trade_grouping gr = all_trades) const;
314 
315  const trade_stats& get_trade_stats(trade_grouping);
316  public:
317  void Print(std::ostream& Stream) const;
318  };
319 
320  /*
321  ** ====================================================
322  ** > > > class equity_state < < <
323  ** ====================================================
324  */
325 
326  // Internal
327  class dll_export equity_state {
328  tsa_declare_testable;
329  private:
330  double m_max_equity;
331  double m_current_equity;
332  double m_prev_equity;
333  bool m_in_drawdown;
334  double m_current_drawdown;
335  double m_current_drawdown_watermark;
336  size_t m_current_drawdown_length;
337  size_t m_drawdown_count;
338  size_t m_prev_drawdown_count;
339  double m_avg_drawdown;
340  double m_max_drawdown;
341  double m_avg_drawdown_length;
342  size_t m_max_drawdown_length;
343  private:
344  void notify_drawdown_completed(double ddn_value, size_t length);
345  public:
346  equity_state(void);
347  virtual ~equity_state(void);
348  public:
349  void notify_new_cash_flow(double);
350  void notify_bar_completed(void);
351  public:
352  double current_drawdown_watermark(void) const;
353  double current_drawdown(void) const;
354  size_t max_completed_drawdown_length_in_bars(void) const;
355  double avg_completed_drawdown_length_in_bars(void) const;
356  double avg_completed_drawdown(void) const;
357  double max_completed_drawdown(void) const;
358  size_t num_completed_drawdowns(void) const;
359  bool in_drawdown(void) const;
360  };
361 
362  /*
363  ** ====================================================
364  ** > > > class equity_metrics < < <
365  ** ====================================================
366  */
367 
368  // Internal
369  class dll_export equity_metrics : public object , public metrics_container{
370  tsa_declare_testable;
371  private:
372  equity_state m_equity_state;
373  double m_cumulative_equity;
374  double m_strategy_equity_high;
375  double m_strategy_equity_low;
376  bool m_is_finalized;
377  bool m_lasts_drawdown_is_open;
378  double m_current_drawdown;
379  public:
380  equity_metrics(void);
381  virtual ~equity_metrics(void);
382  void notify_cash_flow(double cash_flow);
383  void notify_bar_completed(void);
384  void finalize(void);
385  bool is_finalized(void) const;
386  public:
387  double cummulative_equity(void) const;
388  double max_account_balance(double account_start_balance) const;
389  double min_account_balance(double account_start_balance) const;
390  double current_drawdown(void) const;
391  size_t max_drawdown_length_in_bars(void) const;
392  double avg_drawdown_length_in_bars(void) const;
393  double avg_drawdown(void) const;
394  double max_drawdown(void) const;
395  size_t num_drawdowns(void) const;
396  bool in_drawdown(void) const;
397  };
398 
399  /*
400  ** ====================================================
401  ** > > > testing support < < <
402  ** ====================================================
403  */
404  // Internal
405  class dll_export test__trade_state {
406  size_t m_nTotalNumberTrades;
407  size_t m_nTotalNumberLosers;
408  size_t m_nTotalNumberWinners;
409  double m_dPercentWinners;
410  double m_dAveTradeSize;
411  double m_dAveWinnerSize;
412  double m_dAveLoserSize;
413  double m_dAveBarsInTrade;
414  size_t m_nNumBarsInATrade;
415  double m_dNetWinners;
416  double m_dNetLosers;
417  double m_dCumTradeVal;
418  double m_dMaxLoser;
419  double m_dMaxWinner;
420  double m_dCumulativePL;
421  private:
422  void UpdateTotalNumberTrades(void);
423  void UpdateTotalNumberLosers(double dTradeVal);
424  void UpdateTotalNumberWinners(double dTradeVal);
425  void UpdatePercentWinners(void);
426  void UpdateCumWinnersVal(double dTradeVal);
427  void UpdateCumLosersVal(double dTradeVal);
428  void UpdateCumTradeVal(double dTradeVal);
429  void UpdateAveTradeSize(void);
430  void UpdateAveWinnerSize(void);
431  void UpdateAveLoserSize(void);
432  void UpdateLargestLoser(double dTradeVal);
433  void UpdateLargestWinner(double dTradeVal);
434  void UpdateAveTradeBars(size_t nLen);
435  void UpdateCumulativePL(double dTradeVal);
436  public:
437  test__trade_state(void);
438  virtual ~test__trade_state(void);
439  void CopyState(test__trade_state* pTradeStats);
440  void notify_new_trade(double dTradeVal, size_t nLen);
441  public:
442  size_t GetTradeCount(void) const;
443  size_t GetLoserCount(void) const;
444  size_t GetWinnerCount(void) const;
445  double GetPercentProfitable(void) const;
446  double GetAveTrade(void) const;
447  double GetAveWinner(void) const;
448  double GetAveLoser(void) const;
449  double GetMaxLoser(void) const;
450  double GetMaxWinner(void) const;
451  double GetAveTradeBarCount(void) const;
452  double GetStrategyIncome(void) const;
453  };
454 
455  //Internal
456  class dll_export test__trade_stats : public object {
457  tsa_declare_testable;
458  private:
459  test__trade_state m_CurrState;
460  test__trade_state m_SavedState;
461  bool m_bStateIsVirtual;
462  public:
463  test__trade_stats(void);
464  virtual ~test__trade_stats(void);
465  void NotifyVirtualTrade(double _dTradePnL, size_t nLen);
466  void NotifyTrade(double _dTradePnL, size_t nLen);
467  bool TradeStateIsVirtual(void) const;
468  void BeginVirtualTrade(void);
469  void RollbackVirtualTrade(void);
470  public:
471  size_t GetTradeCount(void) const;
472  size_t GetLoserCount(void) const;
473  size_t GetWinnerCount(void) const;
474  double GetPercentProfitable(void) const;
475  double GetAveTrade(void) const;
476  double GetAveWinner(void) const;
477  double GetAveLoser(void) const;
478  double GetMaxLoser(void) const;
479  double GetMaxWinner(void) const;
480  double GetAveTradeBarCount(void) const;
481  double GetStrategyIncome(void) const;
482  };
483 } //tsa
484 
485 #endif
type
Order type.
Definition: TSAOrder.h:101
double gross_profit
Definition: TSAPosition.h:189
position_t max_position
Definition: TSAPosition.h:193
The average gross trade profit / loss (cash amount).
double negative_excursion
Definition: TSAPosition.h:197
double commission
Definition: TSAPosition.h:192
The average net trade profit / loss (cash amount)
The average transaction size in units.
The total number of winning trades.
The average &#39;per unit&#39; transaction cost (slippage + commission).
Class order is the library&#39;s internal order representation. Users are not intended to interact with t...
Definition: TSAOrder.h:49
Information on closed out trades.
Definition: TSAPosition.h:183
quantity_t units_traded__at_market
Definition: TSAPosition.h:200
Namespace for the &#39;Trading System API&#39; library.
Definition: original1.TSA3Core.cpp:20
The percent of units filled without &#39;slippage&#39;, via &#39;limit-orders&#39;.
The value of the current drawdown.
The number of bars of all losing trades.
The size of the largest winning trade (cash amount).
double positive_excursion
Definition: TSAPosition.h:196
The maximum number of consecutive losing trades.
size_t trade_ID
Definition: TSAPosition.h:184
The standard deviation of trade net-profit/loss.
The ratio of &#39;total winners net&#39; / &#39;total losers net&#39;.
The strategy &#39;gross profit&#39; (before slippage + commission).
perf_metric_type
Values that represent performance metric types.
Definition: TSATypeDef.h:216
The average negative (adverse) trade profit before trade was closed out.
The average slippage &#39;per unit&#39; traded.
The average cost (slippage + commission) per trade.
The average gross profit/loss per unit.
The total number of bars on which the strategy had exposure (position not &#39;flat&#39;).
The number of bars of all winning trades.
Base class for classes that can produce metrics.
Definition: TSAMetrics.h:75
structure defining all the metric names. For example, you can pass metric::trade_count as metric_name...
Definition: TSATypeDef.h:297
date_time close_timestamp
Definition: TSAPosition.h:187
The average net profit (cash amount) of winning trades.
The percent of trades profitable.
int64_t quantity_t
Definition: TSATypeDef.h:444
double price
Definition: TSAPosition.h:74
The length in bars of the average losing trade.
The average &#39;maximum position size&#39; of all trades.
The net loss generated by losing trades.
size_t num_bars
Definition: TSAPosition.h:190
The number of units traded using &#39;limit orders&#39;.
double slippage
Definition: TSAPosition.h:191
The ratio of the &#39;average winning trade&#39; / &#39;average losing trade&#39;.
variant objects can represent values of different types.
Definition: TSAVariant.h:140
Parent class for many library classes.
Definition: TSATypeDef.h:462
The value of the largest drawdown.
bool had_slippage
Definition: TSAPosition.h:78
The maximum number of transactions for any one trade.
order::type order_type
Definition: TSAPosition.h:77
quantity_t units_traded__at_limit
Definition: TSAPosition.h:202
date_time entry_timestamp
Definition: TSAPosition.h:186
quantity_t units_traded__on_stop
Definition: TSAPosition.h:201
order::action action
Definition: TSAPosition.h:75
size_t num_transactions
Definition: TSAPosition.h:194
flag if the last trade was open before the strategy evaluation/simulation was stopped.
The maximum number of consecutive winning trades.
The size of the largest losing trade (cash amount).
The highest cummulative loss of sequential losing trades.
The total number of trades.
The total number of units traded (not &#39;round trip&#39;).
The value of the average drawdown in the currency in which the securities are traded.
The average trade length in bars.
The number of units traded without slippage. (Limit orders do not have slippage). ...
The average slippage per trade.
The highest cummulative gain of sequential winning trades.
The average net profit (cash amount) of losing trades.
The number of units traded using &#39;stop orders&#39;.
trade_grouping
Trade aggregation types used by reporting functionality.
Definition: TSATypeDef.h:208
The net profit generated by winning trades.
The total number of drawdowns.
A trade leg.
Definition: TSAPosition.h:71
tsa::date_time timestamp
Definition: TSAPosition.h:76
The total &#39;slippage&#39; booked for trades. Trades resulting from &#39;limit orders&#39; have no slippage...
action
Order action.
Definition: TSAOrder.h:94
bool is_open
Definition: TSAPosition.h:204
The strategy &#39;net profit&#39; (after slippage + commission).
POSITION::state direction
Definition: TSAPosition.h:185
All trades.
Definition: TSATypeDef.h:211
The average positive (advantageous) trade profit before trade was closed out.
quantity_t units_traded
Definition: TSAPosition.h:198
size_t num_transactions__no_slippage
Definition: TSAPosition.h:195
The total &#39;commission&#39; booked for trades.
quantity_t quantity
Definition: TSAPosition.h:73
Class representing a gregorian-date and time-of-day combination. The time component has microsecond r...
Definition: TSATime.h:428
The average number of transactions per trade.
The length in bars of the average winning trade.
double net_profit
Definition: TSAPosition.h:188
The percentage of bars during which the strategy had exposure (position not &#39;flat&#39;).
The average commission per trade.
The largest positive (advantageous) trade profit before trade was closed out.
The largest negative (adverse) trade profit before trade was closed out.
int64_t position_t
Definition: TSATypeDef.h:447
The total number of losing trades.
The average net profit/loss per unit.
The maximum position size of any one trade.
The number of units traded using &#39;market orders&#39;.
The total &#39;transaction cost&#39; for all trades.
quantity_t units_traded__other_trade_type
Definition: TSAPosition.h:203
quantity_t units_traded__no_slippage
Definition: TSAPosition.h:199