├── Inc ├── AlgoOrder.h ├── BarSeries.h ├── Composer.h ├── Cross.h ├── DataSeries.h ├── Date.h ├── DateTime.h ├── Defines.h ├── Engine.h ├── Event.h ├── HighLow.h ├── IEngine.h ├── MA.h ├── OrderList.h ├── PositionList.h ├── Service.h ├── ServiceConfig.h ├── SimulatorConfig.h ├── Strategy.h ├── StrategyConfig.h ├── Technical.h ├── Utils.h └── circular.h ├── Lib ├── AlgoSE.lib └── x64 │ └── AlgoSE.lib └── README.md /Inc/AlgoOrder.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algosenses/AlgoSE-SDK-Cpp/cda4639c2eea660a0603f63b00edca525dddcbef/Inc/AlgoOrder.h -------------------------------------------------------------------------------- /Inc/BarSeries.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_BAR_SERIES_H 2 | #define ALGOSE_BAR_SERIES_H 3 | 4 | #include "DataSeries.h" 5 | #include "Defines.h" 6 | 7 | namespace AlgoSE 8 | { 9 | 10 | class ALGOSE_API TickSeries : public SequenceDataSeries 11 | { 12 | public: 13 | TickSeries(int maxLen = DataSeries::DEFAULT_MAX_LEN); 14 | void append(const Tick& bar); 15 | void appendWithDateTime(const DateTime& datetime, const void* value); 16 | DataSeries& getLastPriceDataSeries(); 17 | DataSeries& getBidPrice1DataSeries(); 18 | DataSeries& getBidVolume1DataSeries(); 19 | DataSeries& getAskPrice1DataSeries(); 20 | DataSeries& getAskVolume1DataSeries(); 21 | 22 | private: 23 | SequenceDataSeries m_lastPriceDS; 24 | SequenceDataSeries m_bidPrice1DS; 25 | SequenceDataSeries m_bidVolume1DS; 26 | SequenceDataSeries m_askPrice1DS; 27 | SequenceDataSeries m_askVolume1DS; 28 | }; 29 | 30 | // A DataSeries of Bar instances. 31 | class ALGOSE_API BarSeries : public SequenceDataSeries 32 | { 33 | public: 34 | // @param: maxLen: The maximum number of values to hold. 35 | // Once a bounded length is full, when new items are added, a corresponding number of items are discarded from the opposite end. 36 | BarSeries(int maxLen = DataSeries::DEFAULT_MAX_LEN); 37 | void setResolution(int resolution); 38 | int getResolution() const; 39 | void setInterval(int interval); 40 | int getInterval() const; 41 | void append(const Bar& bar); 42 | void appendWithDateTime(const DateTime& datetime, const void* value); 43 | 44 | // Returns a `DataSeries` with the open prices. 45 | DataSeries& getOpenDataSeries(); 46 | // Returns a `DataSeries` with the close prices. 47 | DataSeries& getCloseDataSeries(); 48 | // Returns a `DataSeries` with the high prices. 49 | DataSeries& getHighDataSeries(); 50 | // Returns a `DataSeries` with the low prices. 51 | DataSeries& getLowDataSeries(); 52 | // Returns a `DataSeries` with the volume. 53 | DataSeries& getVolumeDataSeries(); 54 | // Returns a `DataSeries` with the open interest. 55 | DataSeries& getOpenIntDataSeries(); 56 | // Returns a `DataSeries` with the close or adjusted close prices. 57 | DataSeries& getPriceDataSeries(); 58 | 59 | private: 60 | int m_resolution; 61 | int m_interval; 62 | 63 | SequenceDataSeries m_openDS; 64 | SequenceDataSeries m_highDS; 65 | SequenceDataSeries m_lowDS; 66 | SequenceDataSeries m_closeDS; 67 | SequenceDataSeries m_volumeDS; 68 | SequenceDataSeries m_openIntDS; 69 | }; 70 | 71 | } // namespace AlgoSE 72 | 73 | #endif // ALGOSE_BAR_SERIES_H 74 | -------------------------------------------------------------------------------- /Inc/Composer.h: -------------------------------------------------------------------------------- 1 | // 2 | // User space bar composer. 3 | // 4 | #ifndef ATS_COMPOSER_H 5 | #define ATS_COMPOSER_H 6 | 7 | #include "ATS.h" 8 | #include "Export.h" 9 | 10 | namespace ATS 11 | { 12 | 13 | class ComposerImpl; 14 | 15 | class Composer { 16 | public: 17 | Composer(); 18 | ~Composer(); 19 | bool init(const TradingHours& hours, int resolution, int interval); 20 | void appendMarketData(const MarketData& data); 21 | bool hasNewCompositedData(); 22 | MarketData getCompositedData(); 23 | 24 | private: 25 | ComposerImpl* m_implementor; 26 | }; 27 | 28 | } // namespace ATS 29 | 30 | #endif // ATS_COMPOSER_H -------------------------------------------------------------------------------- /Inc/Cross.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_CROSS_H 2 | #define ALGOSE_CROSS_H 3 | 4 | #include "DataSeries.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | class ALGOSE_API Cross 10 | { 11 | public: 12 | // Checks for a cross above conditions over the specified period between two DataSeries objects. 13 | // It returns the number of times values1 crossed above values2 during the given period. 14 | // @param values1: The DataSeries that crosses. 15 | // @param values2: The DataSeries being crossed. 16 | // @param start: The start of the range. 17 | // @param end: The end of the range. 18 | // NOTE: 19 | // The default start and end values check for cross above conditions over the last 2 values. 20 | static int crossAbove(const DataSeries& values1, const DataSeries& values2, int start = 0, int end = 1); 21 | 22 | // Checks for a cross below conditions over the specified period between two DataSeries objects. 23 | // It returns the number of times values1 crossed below values2 during the given period. 24 | // @param values1: The DataSeries that crosses. 25 | // @param values2: The DataSeries being crossed. 26 | // @param start: The start of the range. 27 | // @param end: The end of the range. 28 | // NOTE: 29 | // The default start and end values check for cross below conditions over the last 2 values. 30 | static int crossBelow(const DataSeries& values1, const DataSeries& values2, int start = 0, int end = 1); 31 | 32 | }; 33 | 34 | } // namespace AlgoSE 35 | 36 | #endif // ALGOSE_CROSS_H 37 | -------------------------------------------------------------------------------- /Inc/DataSeries.h: -------------------------------------------------------------------------------- 1 | // Data series are abstractions used to manage time-series data. 2 | #ifndef ALGOSE_DATA_SERIES_H 3 | #define ALGOSE_DATA_SERIES_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include "Defines.h" 9 | #include "circular.h" 10 | #include "Event.h" 11 | 12 | namespace AlgoSE 13 | { 14 | 15 | // Base class for data series. 16 | // This is a base class and should not be used directly. 17 | class ALGOSE_API DataSeries 18 | { 19 | public: 20 | enum BuiltInType { 21 | ElemTypeUnknown = 0, 22 | ElemTypeInt, // int 23 | ElemTypeInt64, // long long 24 | ElemTypeFloat, // double 25 | ElemTypeTick, // Tick 26 | ElemTypeBar, // Bar 27 | ElemBuiltInTypeEnd 28 | }; 29 | 30 | static const unsigned int DEFAULT_MAX_LEN; 31 | 32 | DataSeries(); 33 | // Returns the type of data series. 34 | int getType() const; 35 | void setType(int type); 36 | // Returns the number of elements in the data series. 37 | virtual std::size_t length() const = 0; 38 | // Returns the value at a given position/slice. It raises 'out_of_range' if the position is invalid, 39 | // or TypeError if the key type is invalid. 40 | virtual void* getItem(std::size_t pos) = 0; 41 | 42 | virtual Event& getNewValueEvent() = 0; 43 | 44 | virtual void appendWithDateTime(const DateTime& dateTime, const void* value) = 0; 45 | 46 | virtual ~DataSeries(); 47 | 48 | private: 49 | int m_type; 50 | }; 51 | 52 | // A DataSeries that holds values in a sequence in memory. 53 | template 54 | class ALGOSE_API SequenceDataSeries : public DataSeries 55 | { 56 | public: 57 | // @param: maxLen: The maximum number of values to hold. 58 | // Once a bounded length is full, when new items are added, a corresponding number of items are discarded from the opposite end. 59 | SequenceDataSeries(int maxLen = DataSeries::DEFAULT_MAX_LEN, int type = ElemTypeFloat) 60 | : m_newValueEvt(Event::EvtDataSeriesNewValue) 61 | { 62 | if (typeid(T) == typeid(int)) { 63 | setType(DataSeries::ElemTypeInt); 64 | } else if (typeid(T) == typeid(double)) { 65 | setType(DataSeries::ElemTypeFloat); 66 | } else if (typeid(T) == typeid(long long)) { 67 | setType(DataSeries::ElemTypeInt64); 68 | } else if (typeid(T) == typeid(Tick)) { 69 | setType(DataSeries::ElemTypeTick); 70 | } else if (typeid(T) == typeid(Bar)) { 71 | setType(DataSeries::ElemTypeBar); 72 | } else { 73 | setType(type); 74 | } 75 | 76 | setMaxLen(maxLen); 77 | } 78 | 79 | virtual std::size_t length() const 80 | { 81 | return m_values.size(); 82 | } 83 | 84 | virtual void* getItem(std::size_t idx) 85 | { 86 | if (idx >= 0 && idx < length()) { 87 | return &(m_values[idx]); 88 | } 89 | 90 | return nullptr; 91 | } 92 | 93 | virtual void setItem(std::size_t idx, T value) 94 | { 95 | if (idx >= 0 && idx < length()) { 96 | m_values[idx] = value; 97 | } else { 98 | throw std::out_of_range("Index out of range."); 99 | } 100 | } 101 | 102 | // Latest value placed at the front of data series. 103 | // So m_values[0] is the newest one. 104 | virtual const T operator[](std::size_t idx) const 105 | { 106 | if (idx < 0 || idx >= m_values.size()) { 107 | throw std::out_of_range("Index out of range."); 108 | } 109 | 110 | return m_values[m_values.size() - 1 - idx]; 111 | } 112 | 113 | virtual const T& at(std::size_t idx) const 114 | { 115 | if (idx < 0 || idx >= m_values.size()) { 116 | throw std::out_of_range("Index out of range."); 117 | } 118 | 119 | return m_values[m_values.size() - 1 - idx]; 120 | } 121 | 122 | // Sets the maximum number of values to hold and resizes accordingly if necessary. 123 | virtual void setMaxLen(int maxLen) 124 | { 125 | m_dateTimes.clear(); 126 | m_values.clear(); 127 | // It is important to initialize circular_buffer to zero size 128 | circular_buffer tmpDT(0); 129 | m_dateTimes.swap(tmpDT); 130 | m_dateTimes.reserve(maxLen); 131 | 132 | circular_buffer tmpVal(0); 133 | m_values.swap(tmpVal); 134 | m_values.reserve(maxLen); 135 | m_maxLen = maxLen; 136 | } 137 | 138 | // Returns the maximum number of values to hold. 139 | virtual int getMaxLen() const 140 | { 141 | return m_maxLen; 142 | } 143 | 144 | // Event handler receives: 145 | // 1: Data Series generating the event 146 | // 2: The datetime for the new value 147 | // 3: The new value 148 | virtual Event& getNewValueEvent() 149 | { 150 | return m_newValueEvt; 151 | } 152 | 153 | // Appends a value. 154 | virtual void append(const T& value) 155 | { 156 | appendWithDateTime(DateTime(), &value); 157 | } 158 | 159 | // Appends a value with an associated datetime. 160 | // Note: If dateTime is not None, it must be greater than the last one. 161 | virtual void appendWithDateTime(const DateTime& dateTime, const void* value) 162 | { 163 | assert(m_dateTimes.size() == m_values.size()); 164 | 165 | const T& data = *((T *)value); 166 | 167 | if (value == nullptr || !dateTime.isValid()) { 168 | return; 169 | } 170 | 171 | m_dateTimes.push_back(dateTime); 172 | m_values.push_back(data); 173 | 174 | Event::Context ctx; 175 | ctx.datetime = dateTime; 176 | ctx.data = (void*)value; 177 | m_newValueEvt.emitEvt(dateTime, (void *)&ctx); 178 | } 179 | 180 | void clear() 181 | { 182 | m_dateTimes.clear(); 183 | m_values.clear(); 184 | } 185 | 186 | private: 187 | Event m_newValueEvt; 188 | 189 | int m_maxLen; 190 | circular_buffer m_dateTimes; 191 | circular_buffer m_values; 192 | }; 193 | 194 | } // namespace AlgoSE 195 | 196 | #endif // ALGOSE_DATA_SERIES_H -------------------------------------------------------------------------------- /Inc/Date.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_DATE_H 2 | #define ALGOSE_DATE_H 3 | 4 | #include "Defines.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | // Day number 10 | typedef int Day; 11 | 12 | /* Day's serial number MOD 7; 13 | WEEKDAY Excel function is the same except for Sunday = 7. 14 | */ 15 | enum Weekday { Sunday = 1, 16 | Monday = 2, 17 | Tuesday = 3, 18 | Wednesday = 4, 19 | Thursday = 5, 20 | Friday = 6, 21 | Saturday = 7, 22 | Sun = 1, 23 | Mon = 2, 24 | Tue = 3, 25 | Wed = 4, 26 | Thu = 5, 27 | Fri = 6, 28 | Sat = 7 29 | }; 30 | 31 | // Month names 32 | enum Month { 33 | January = 1, 34 | February = 2, 35 | March = 3, 36 | April = 4, 37 | May = 5, 38 | June = 6, 39 | July = 7, 40 | August = 8, 41 | September = 9, 42 | October = 10, 43 | November = 11, 44 | December = 12, 45 | Jan = 1, 46 | Feb = 2, 47 | Mar = 3, 48 | Apr = 4, 49 | Jun = 6, 50 | Jul = 7, 51 | Aug = 8, 52 | Sep = 9, 53 | Oct = 10, 54 | Nov = 11, 55 | Dec = 12 56 | }; 57 | 58 | // Year number 59 | typedef int Year; 60 | 61 | class ALGOSE_API Date 62 | { 63 | public: 64 | // Default constructor returning a null date. 65 | Date(); 66 | 67 | // Constructor taking a serial number as given by Applix or Excel. 68 | explicit Date(long serialNumber); 69 | 70 | // More traditional constructor. 71 | Date(Day d, Month m, Year y); 72 | 73 | Weekday weekday() const; 74 | Day dayOfMonth() const; 75 | 76 | // One-based (Jan 1st = 1) 77 | Day dayOfYear() const; 78 | Month month() const; 79 | Year year() const; 80 | long serialNumber() const; 81 | 82 | // increments date by the given number of days 83 | Date& operator+=(long days); 84 | // decrement date by the given number of days 85 | Date& operator-=(long days); 86 | // 1-day pre-increment 87 | Date& operator++(); 88 | // 1-day post-increment 89 | Date operator++(int); 90 | // 1-day pre-decrement 91 | Date& operator--(); 92 | // 1-day post-decrement 93 | Date operator--(int); 94 | // returns a new date incremented by the given number of days 95 | Date operator+(long days) const; 96 | // returns a new date decremented by the given number of days 97 | Date operator-(long days) const; 98 | 99 | // today's date. 100 | static Date todaysDate(); 101 | // earliest allowed date 102 | static Date minDate(); 103 | // latest allowed date 104 | static Date maxDate(); 105 | // whether the given year is a leap one 106 | static bool isLeap(Year y); 107 | // last day of the month to which the given date belongs 108 | static Date endOfMonth(const Date& d); 109 | // whether a date is the last day of its month 110 | static bool isEndOfMonth(const Date& d); 111 | // next given weekday following or equal to the given date 112 | /* E.g., the Friday following Tuesday, January 15th, 2002 113 | was January 18th, 2002. 114 | 115 | see http://www.cpearson.com/excel/DateTimeWS.htm 116 | */ 117 | static Date nextWeekday(const Date& d, 118 | Weekday w); 119 | 120 | private: 121 | long serialNumber_; // Elapsed days from 1900 122 | static int monthLength(Month m, bool leapYear); 123 | static int monthOffset(Month m, bool leapYear); 124 | static long yearOffset(Year y); 125 | static long minimumSerialNumber(); 126 | static long maximumSerialNumber(); 127 | static void checkSerialNumber(long serialNumber); 128 | }; 129 | 130 | ALGOSE_API long operator-(const Date& d1, const Date& d2); 131 | ALGOSE_API bool operator==(const Date& d1, const Date& d2); 132 | ALGOSE_API bool operator!=(const Date& d1, const Date& d2); 133 | ALGOSE_API bool operator<(const Date& d1, const Date& d2); 134 | ALGOSE_API bool operator<=(const Date& d1, const Date& d2); 135 | ALGOSE_API bool operator>(const Date& d1, const Date& d2); 136 | ALGOSE_API bool operator>=(const Date& d1, const Date& d2); 137 | 138 | } // namespace AlgoSE 139 | 140 | #endif // ALGOSE_DATE_H -------------------------------------------------------------------------------- /Inc/DateTime.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_DATETIME_H 2 | #define ALGOSE_DATETIME_H 3 | 4 | #include 5 | #include 6 | 7 | #ifdef _MSC_VER 8 | #include 9 | #include 10 | #endif 11 | 12 | #include "Date.h" 13 | #include "Defines.h" 14 | 15 | namespace AlgoSE 16 | { 17 | 18 | /* 19 | * Represents a date convertable among various standard 20 | * date represenations including RFC 3339 used by JSON encodings. 21 | */ 22 | 23 | class ALGOSE_API DateTime 24 | { 25 | public: 26 | DateTime(); 27 | DateTime(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int ms = 0); 28 | // DateTime String Format: yyyy-mm-ddTHH:MM:SS.ms or yyyy-mm-dd 29 | // For example: 2014-03-21T11:03:59.3455 or 2014-10-09 30 | explicit DateTime(const char* date); 31 | // ticks: elapsed milliseconds since the Epoch 32 | explicit DateTime(long long ticks); 33 | DateTime(const TimeStamp& timestamp); 34 | DateTime(const DateTime& date); 35 | ~DateTime(); 36 | std::string toString() const; 37 | 38 | bool isValid() const { return t_.tv_sec != kInvalidEpoch_; } 39 | /* 40 | * Marks this date as being invalid. 41 | */ 42 | void markInvalid(); 43 | 44 | int compare(const DateTime& date) const { 45 | return t_.tv_sec == date.t_.tv_sec 46 | ? t_.tv_usec - date.t_.tv_usec 47 | : t_.tv_sec - date.t_.tv_sec; 48 | } 49 | 50 | bool operator ==(const DateTime& date) const { 51 | return compare(date) == 0 && date.isValid(); 52 | } 53 | 54 | bool operator <(const DateTime& date) const { 55 | return compare(date) < 0 && date.isValid(); 56 | } 57 | 58 | bool operator >(const DateTime& date) const { 59 | return compare(date) > 0 && date.isValid(); 60 | } 61 | 62 | bool operator !=(const DateTime& date) const { 63 | return compare(date) != 0 && isValid(); 64 | } 65 | 66 | bool operator <=(const DateTime& date) const { 67 | return compare(date) <= 0 && isValid(); 68 | } 69 | 70 | bool operator >=(const DateTime& date) const { 71 | return compare(date) >= 0 && date.isValid(); 72 | } 73 | 74 | operator std::string() 75 | { 76 | return toString(); 77 | } 78 | 79 | DateTime& operator=(const DateTime& date) { 80 | t_ = date.t_; 81 | return *this; 82 | } 83 | 84 | DateTime operator -(const DateTime& date) const { 85 | DateTime dt; 86 | dt.t_.tv_sec = t_.tv_sec - date.t_.tv_sec; 87 | dt.t_.tv_usec = t_.tv_usec - date.t_.tv_usec; 88 | return dt; 89 | } 90 | 91 | DateTime date() const { 92 | DateTime dt; 93 | dt.t_.tv_usec = 0; 94 | dt.t_.tv_sec = t_.tv_sec / (60*60*24) * (60*60*24); 95 | return dt; 96 | } 97 | 98 | // Unix time (epoch time) is defined as the number of seconds after 1-1-1970, 00h:00. 99 | // date = (unix_time/86400 + datenum(1970,1,1)) 100 | // if unix_time is given in seconds, unix_time / 86400 will give the number 101 | // of days since Jan. 1st 1970. Add to that the offset used by Matlab's datenum 102 | // (datenum(0000,1,1) == 1), and you have the amount of days since Jan. 1st, 0000. 103 | // If you have milliseconds, just use: 104 | // date = unix_time/86400/1000 + datenum(1970,1,1) 105 | #define ELAPSED_DAYS_FROM_0000_TO_1970 (719529) 106 | #define ELAPSED_DAYS_FROM_0000_TO_1900 (693960) 107 | #define ELAPSED_DAYS_FROM_1900_TO_1970 (25567) 108 | 109 | Date toDate() const 110 | { 111 | // return Date(t_.tv_sec/86400 + 719529); 112 | // Because our Date class use 1900 as it's start point. 113 | return Date(t_.tv_sec / 86400 + ELAPSED_DAYS_FROM_1900_TO_1970); 114 | } 115 | 116 | TimeStamp toTimeStamp() const { 117 | TimeStamp ts = { t_.tv_sec, t_.tv_usec }; 118 | return ts; 119 | } 120 | 121 | void getFields(int& year, int& month, int& day, int& hour, int& minute, int& second, int& millis); 122 | 123 | DateTime yesterday() const { 124 | DateTime dt; 125 | dt.t_.tv_usec = 0; 126 | dt.t_.tv_sec = t_.tv_sec / (60 * 60 * 24) * (60 * 60 * 24); 127 | dt.t_.tv_sec -= (60 * 60 * 24); 128 | return dt; 129 | } 130 | 131 | long secs() const { 132 | return t_.tv_sec; 133 | } 134 | 135 | long millisec() const { 136 | return t_.tv_usec / 1000; 137 | } 138 | 139 | int dateNum() const; 140 | 141 | int timeNum() const { 142 | int sec = secs() % (24 * 3600); 143 | if (sec == 0) { 144 | return 0; 145 | } 146 | 147 | int hour = sec / (3600); 148 | int minute = 0; 149 | if (hour != 0) { 150 | minute = (sec % (hour * 3600)) / 60; 151 | } else { 152 | minute = sec / 60; 153 | } 154 | 155 | return (hour * 10000 + minute * 100 + secs() % 60); 156 | } 157 | 158 | int days() const { 159 | return t_.tv_sec / (60*60*24); 160 | } 161 | 162 | int year() const; 163 | 164 | int month() const; 165 | 166 | int dayOfMonth() const; 167 | 168 | // milliseconds 169 | long long ticks() const { 170 | return ((long long)t_.tv_sec) * 1000 + (t_.tv_usec / 1000); 171 | } 172 | 173 | protected: 174 | struct timeval t_; 175 | static const time_t kInvalidEpoch_; 176 | }; 177 | 178 | ALGOSE_API std::ostream& operator<<(std::ostream&, const DateTime&); 179 | 180 | } // namespace AlgoSE 181 | 182 | #endif // ALGOSE_DATETIME_H -------------------------------------------------------------------------------- /Inc/Defines.h: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | * Data structure and Platform related definitions for Algorithmic Strategy Engine. * 3 | * * 4 | * $Author: zhuangshaobo $ * 5 | * $Mail: zhuang@algo.trade $ * 6 | * $Date: 2013-08-15 $ * 7 | ************************************************************************************/ 8 | 9 | #ifndef ALGOSE_DEFINES_H 10 | #define ALGOSE_DEFINES_H 11 | 12 | namespace AlgoSE 13 | { 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // Platform Related Definitions 17 | //////////////////////////////////////////////////////////////////////////////// 18 | #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) || defined(_WINDOWS) 19 | #define __PLATFORM_WINDOWS__ 20 | #elif defined(__GNUC__) 21 | #define __PLATFORM_LINUX__ 22 | #endif 23 | 24 | // The following ifdef block is the standard way of creating macros which make exporting 25 | // from a DLL simpler. All files within this DLL are compiled with the ALGOSE_EXPORTS 26 | // symbol defined on the command line. this symbol should not be defined on any project 27 | // that uses this DLL. This way any other project whose source files include this file see 28 | // ALGOSE_API functions as being imported from a DLL, whereas this DLL sees symbols 29 | // defined with this macro as being exported. 30 | #if defined(__PLATFORM_WINDOWS__) 31 | #ifdef ALGOSE_EXPORTS 32 | #define ALGOSE_API __declspec(dllexport) 33 | #else 34 | #define ALGOSE_API __declspec(dllimport) 35 | #endif 36 | #elif defined(__PLATFORM_LINUX__) 37 | #define ALGOSE_API __attribute__((visibility("default"))) 38 | #else 39 | // do nothing and hope for the best? 40 | #define ALGOSE_API 41 | #pragma warning Unknown dynamic link import/export semantics. 42 | #endif 43 | 44 | #ifdef _MSC_VER 45 | #pragma warning(disable: 4251) 46 | #endif 47 | 48 | //////////////////////////////////////////////////////////////////////////////// 49 | // Data Structure Definitions 50 | //////////////////////////////////////////////////////////////////////////////// 51 | 52 | // Structure TimeStamp represents the number of seconds that have elapsed since 53 | // January 1, 1970 (midnight UTC/GMT), not counting leap seconds (in ISO 8601: 1970-01-01T00:00:00Z). 54 | // It's also known as 'Unix epoch' (or Unix time or POSIX time or Unix timestamp). 55 | typedef struct { 56 | long sec; // in seconds 57 | long usec; // in microseconds 58 | } TimeStamp; 59 | 60 | const unsigned int LEN_ID = 32; 61 | const unsigned int LEN_NAME = 32; 62 | const unsigned int LEN_INSTRUMENT = 32; 63 | const unsigned int LEN_EXCHANGE = 8; 64 | const unsigned int LEN_STATE_MSG = 128; 65 | const unsigned int LEN_TEXT = 256; 66 | 67 | typedef struct { 68 | enum { 69 | LOG_VERBOSE = 0x01, 70 | LOG_TRACE = 0x02, 71 | LOG_DEBUG = 0x04, 72 | LOG_INFO = 0x08, 73 | LOG_WARN = 0x10, 74 | LOG_ERROR = 0x20, 75 | LOG_FATAL = 0x40, 76 | }; 77 | } LogLevel; 78 | 79 | typedef struct { 80 | enum { 81 | LIVE, 82 | SIMULATION, 83 | OPTIMIZATION, 84 | }; 85 | } RunningMode; 86 | 87 | typedef struct { 88 | enum { 89 | CSV_DATA_FILE, 90 | BIN_DATA_FILE, 91 | }; 92 | } DataFileFormat; 93 | 94 | typedef struct { 95 | enum { 96 | UNKNOWN = 0, 97 | STOCK, 98 | FUTURE, 99 | FOREX, 100 | OPTION 101 | }; 102 | } SecurityType; 103 | 104 | typedef struct { 105 | enum { 106 | // It is important for frequency values to get bigger for bigger windows. 107 | TICK = 0, // The bar represents a single trade. 108 | SECOND = 1, // The bar summarizes the trading activity during 1 second. 109 | MINUTE = 60, // The bar summarizes the trading activity during 1 minute. 110 | HOUR = 60 * 60, // The bar summarizes the trading activity during 1 hour. 111 | DAY = 24 * 60 * 60, // The bar summarizes the trading activity during 1 day. 112 | WEEK = 24 * 60 * 60 * 7, // The bar summarizes the trading activity during 1 week. 113 | }; 114 | } Resolution; 115 | 116 | typedef struct { 117 | enum { 118 | EXCHG_UNKNOWN = 0x00, 119 | EXCHG_SSE = 0x0001, 120 | EXCHG_SZE = 0x0002, 121 | EXCHG_SHFE = 0x0004, 122 | EXCHG_DCE = 0x0008, 123 | EXCHG_CZCE = 0x0010, 124 | EXCHG_CFFEX = 0x0020, 125 | EXCHG_GOLD = 0x0040 126 | }; 127 | } ExchangeCode; 128 | 129 | typedef struct { 130 | enum { 131 | SNAPSHOT = 0, 132 | TRADES, 133 | }; 134 | } TickType; 135 | 136 | typedef struct { 137 | char type; 138 | char secType; // security type 139 | char instrument[LEN_INSTRUMENT]; 140 | char exchange[LEN_EXCHANGE]; 141 | TimeStamp timestamp; 142 | double lastPrice; 143 | double openPrice; 144 | double highestPrice; 145 | double lowestPrice; 146 | double closePrice; 147 | double volume; 148 | long long openInterest; 149 | double turnover; 150 | double upperLimitPrice; 151 | double lowerLimitPrice; 152 | double preSettlePrice; 153 | double preClosePrice; 154 | double settlePrice; 155 | int preOpenInterest; 156 | double averagePrice; 157 | int depth; 158 | 159 | double bidPrice1; 160 | int bidVolume1; 161 | double bidPrice2; 162 | int bidVolume2; 163 | double bidPrice3; 164 | int bidVolume3; 165 | double bidPrice4; 166 | int bidVolume4; 167 | double bidPrice5; 168 | int bidVolume5; 169 | 170 | double askPrice1; 171 | int askVolume1; 172 | double askPrice2; 173 | int askVolume2; 174 | double askPrice3; 175 | int askVolume3; 176 | double askPrice4; 177 | int askVolume4; 178 | double askPrice5; 179 | int askVolume5; 180 | 181 | int srvId; 182 | } Tick; 183 | 184 | typedef struct { 185 | char secType; // security type 186 | char instrument[LEN_INSTRUMENT]; 187 | char exchange[LEN_EXCHANGE]; 188 | TimeStamp timestamp; 189 | int resolution; 190 | int interval; 191 | double open; 192 | double high; 193 | double low; 194 | double close; 195 | double last; 196 | long long volume; 197 | long long openInt; 198 | double amount; 199 | } Bar; 200 | 201 | typedef struct { 202 | long reqId; 203 | int isLast; 204 | char secType; 205 | char exchange[LEN_EXCHANGE]; 206 | char instrument[LEN_INSTRUMENT]; 207 | TimeStamp timestamp; 208 | int resolution; 209 | int interval; 210 | double open; 211 | double high; 212 | double low; 213 | double close; 214 | double last; 215 | long long openInt; 216 | long long volume; 217 | double turnover; 218 | double upperLimitPrice; 219 | double lowerLimitPrice; 220 | double preSettlePrice; 221 | double preClosePrice; 222 | double settlePrice; 223 | int preOpenInterest; 224 | double averagePrice; 225 | int depth; 226 | 227 | double bidPrice1; 228 | int bidVolume1; 229 | double bidPrice2; 230 | int bidVolume2; 231 | double bidPrice3; 232 | int bidVolume3; 233 | double bidPrice4; 234 | int bidVolume4; 235 | double bidPrice5; 236 | int bidVolume5; 237 | 238 | double askPrice1; 239 | int askVolume1; 240 | double askPrice2; 241 | int askVolume2; 242 | double askPrice3; 243 | int askVolume3; 244 | double askPrice4; 245 | int askVolume4; 246 | double askPrice5; 247 | int askVolume5; 248 | 249 | // Identifies whether this bar(market data) is completed. 250 | // Used in the historical data loading scenarios. 251 | int uncompleted; 252 | int srvId; 253 | } HistoricalData; 254 | 255 | // State chart: 256 | // INITIAL -> PENDING_NEW 257 | // PENDING_NEW -> SUBMITTED 258 | // PENDING_NEW -> CANCELED 259 | // SUBMITTED -> ACCEPTED 260 | // SUBMITTED -> PENDING_CANCEL 261 | // ACCEPTED -> FILLED 262 | // ACCEPTED -> PARTIALLY_FILLED 263 | // ACCEPTED -> PENDING_CANCEL 264 | // PARTIALLY_FILLED -> PARTIALLY_FILLED 265 | // PARTIALLY_FILLED -> FILLED 266 | // PARTIALLY_FILLED -> PENDING_CANCEL 267 | // PENDING_CANCEL -> CANCELED 268 | 269 | // ACCEPTED: Engine is triggered to frozen positions. 270 | // CANCELED or REJECTED: Engine is triggered to unfrozen positions. 271 | typedef struct { 272 | enum { 273 | UNKNOWN = 0, 274 | INITIAL, // Initial state. 275 | PENDING_NEW, 276 | SUBMITTED, // Order has been submitted. 277 | ACCEPTED, // Order has been acknowledged by the broker. 278 | PENDING_CANCEL, 279 | CANCELED, // Order has been canceled. 280 | PARTIALLY_FILLED, // Order has been partially filled. 281 | FILLED, // Order has been completely filled. 282 | REJECTED // Order has been rejected. 283 | }; 284 | } OrderState; 285 | 286 | // Class for orders. 287 | // 288 | // Valid type parameter values are: 289 | // 290 | // 1. MARKET 291 | // A market order is an order to buy or sell an asset at the bid or offer price currently available in the marketplace. 292 | // When you submit a market order, you have no guarantee that the order will execute at any specific price. 293 | // 294 | // 2. LIMIT 295 | // A limit order is an order to buy or sell a contract ONLY at the specified price or better. 296 | // 297 | // 3. STOP 298 | // A Stop order becomes a market order to buy or sell securities or commodities once the specified stop price is attained or penetrated. 299 | // A Stop order is not guaranteed a specific execution price. 300 | // 301 | // 4. STOP_LIMIT 302 | // A Stop Limit order is similar to a stop order in that a stop price will activate the order. However, unlike the stop order, 303 | // which is submitted as a market order when elected, the stop limit order is submitted as a limit order. 304 | // 305 | // When you place a stop or limit order, you are telling your broker that you don't want the market price 306 | // (the current price at which a stock is trading), but that you want the stock price to move in a certain 307 | // direction before your order is executed. 308 | // 309 | // With a stop order, your trade will be executed only when the security you want to buy or sell reaches a 310 | // particular price (the stop price). Once the stock has reached this price, a stop order essentially becomes 311 | // a market order and is filled. For instance, if you own stock ABC, which currently trades at $20, and you 312 | // place a stop order to sell it at $15, your order will only be filled once stock ABC drops below $15. Also 313 | // known as a "stop-loss order", this allows you to limit your losses. However, this type of order can also be 314 | // used to guarantee profits. For example, assume that you bought stock XYZ at $10 per share and now the stock 315 | // is trading at $20 per share. Placing a stop order at $15 will guarantee profits of approximately $5 per share, 316 | // depending on how quickly the market order can be filled. 317 | // 318 | // A STOP_LIMIT order is an order placed with a broker that combines the features of stop order with those of a 319 | // limit order. A stop-limit order will be executed at a specified price (or better) after a given stop price 320 | // has been reached. Once the stop price is reached, the stop-limit order becomes a limit order to buy (or sell) 321 | // at the limit price or better. 322 | // 323 | // Valid action parameter values are: 324 | // 325 | // 1. BUY 326 | // 2. BUY_TO_COVER 327 | // 3. SELL 328 | // 4. SHORT 329 | // 330 | typedef struct { 331 | enum { 332 | MARKET = 1, 333 | LIMIT, 334 | STOP, 335 | STOP_LIMIT, 336 | }; 337 | } OrderType; 338 | 339 | typedef struct { 340 | enum { 341 | BUY = 1, 342 | BUY_TO_COVER, 343 | SELL, 344 | SELL_SHORT, 345 | }; 346 | } OrderAction; 347 | 348 | typedef struct { 349 | enum { 350 | CANCEL, 351 | MODIFY, 352 | SUSPEND, 353 | RESUME, 354 | }; 355 | } OrderOperationRequest; 356 | 357 | //0 = Day 358 | //1 = Good Till Cancel (GTC) 359 | //2 = At the Opening (OPG) 360 | //3 = Immediate or Cancel (IOC) 361 | //4 = Fill or Kill (FOK) 362 | //5 = Good Till Crossing (GTX) 363 | //6 = Good Till Date 364 | typedef struct { 365 | enum { 366 | DAY = 0, 367 | GTC, 368 | OPG, 369 | IOC, 370 | FOK, 371 | GTX, 372 | GTD, 373 | }; 374 | } TimeInForce; 375 | 376 | // When buy side places an order, they have only their own Client Reference ID (clOrdId) available. 377 | // The Order ID (ordId) comes to life only when the Order is accepted by the sell side. 378 | typedef struct { 379 | // Buy side's original client order ID, uniqueness must be guaranteed within a single trading day. 380 | char clOrdId[LEN_ID]; 381 | // Sell side's reference for this order. 382 | char ordId[LEN_ID]; 383 | char instrument[LEN_INSTRUMENT]; 384 | int exchange; 385 | int type; 386 | int action; 387 | int timeInforce; 388 | bool allOrNone; 389 | int status; 390 | double quantity; 391 | double price; 392 | double stopPx; 393 | double tradedQty; 394 | double avgTradedPx; 395 | double lastTradedQty; 396 | double lastTradedPx; 397 | TimeStamp timestamp; 398 | double commissions; 399 | char stateMsg[LEN_STATE_MSG]; 400 | char parentClOrdId[LEN_ID]; 401 | int closeEffect; // Distinguish three effects of position closing. 402 | int compId; // Component who submit this order. 403 | int ownerId; // Strategy who submit this order. 404 | int srvId; 405 | } Order; 406 | 407 | typedef struct { 408 | char instrument[LEN_INSTRUMENT]; 409 | int type; 410 | int action; 411 | TimeStamp timestamp; 412 | double quantity; 413 | double price; 414 | int closeEffect; 415 | char clOrdId[LEN_ID]; 416 | char ordId[LEN_ID]; 417 | char execId[LEN_ID]; 418 | int srvId; 419 | } Execution; 420 | 421 | typedef struct { 422 | enum { 423 | CLOSE = 0, 424 | CLOSE_TODAY, 425 | CLOSE_YESTERDAY, 426 | }; 427 | } CloseEffect; 428 | 429 | typedef struct { 430 | char clOrdId[LEN_ID]; 431 | char ordId[LEN_ID]; 432 | char origClOrdId[LEN_ID]; 433 | char instrument[LEN_INSTRUMENT]; 434 | int operation; 435 | TimeStamp timestamp; 436 | int side; 437 | double price; 438 | double quantity; 439 | bool success; 440 | char stateMsg[LEN_STATE_MSG]; 441 | int compId; 442 | int ownerId; 443 | int srvId; 444 | } OrderOperation; 445 | 446 | typedef struct { 447 | char userId[32]; 448 | char password[32]; 449 | char userName[64]; 450 | char currency[8]; 451 | double preBalance; 452 | double preDeposit; 453 | double margin; 454 | double lastFund; 455 | double currMargin; 456 | double deposit; 457 | double withdraw; 458 | double equity; 459 | double availFunds; 460 | double buyFreeze; 461 | double sellFreeze; 462 | double buyBond; 463 | double sellBond; 464 | double realizedPnL; 465 | double unrealizedPnL; 466 | double totalBond; 467 | double totalExBond; 468 | double todayReleaseFund; 469 | double comFreeze; 470 | double commission; 471 | double otherFreeze; 472 | double totalFreeze; 473 | double riskLevel; 474 | 475 | int validFields; 476 | int srvId; 477 | } AccountDetails; 478 | 479 | typedef struct { 480 | char instrument[LEN_INSTRUMENT]; 481 | int secType; 482 | char secName[LEN_NAME]; 483 | int exchgCode; 484 | double upperLimitPrice; 485 | double lowerLimitPrice; 486 | double longMarginRatio; 487 | double shortMarginRatio; 488 | double multiplier; 489 | double tickSize; 490 | int isTrading; 491 | int srvId; 492 | } SecurityDefinition; 493 | 494 | typedef struct { 495 | enum { 496 | POSITION_SIDE_LONG = 'L', 497 | POSITION_SIDE_SHORT = 'S' 498 | }; 499 | } PositionSide; 500 | 501 | // Account Position 502 | // An Account Position is the position you actually hold in a real-time trading account. 503 | typedef struct { 504 | char instrument[LEN_INSTRUMENT]; 505 | char side; 506 | double cumQty; 507 | double todayQty; 508 | double histQty; 509 | double frozen; 510 | double histFrozen; 511 | double unformed; 512 | double preSettlmntPx; 513 | double cost; 514 | double avgPx; 515 | double unrealizedPnL; 516 | double realizedPnL; 517 | double margin; 518 | TimeStamp lastOpenTime; 519 | double lastOpenPx; 520 | double lastOpenQty; 521 | TimeStamp lastCloseTime; 522 | double lastClosePx; 523 | double lastCloseQty; 524 | double histHighestPx; 525 | double histLowestPx; 526 | char accountId[LEN_ID]; 527 | int srvId; 528 | } AccountPosition; 529 | 530 | typedef struct { 531 | int srvId; 532 | int type; 533 | int state; 534 | char name[LEN_NAME]; 535 | char desc[LEN_TEXT]; 536 | } ServiceStatus; 537 | 538 | typedef struct { 539 | enum { 540 | PARAM_TYPE_BOOL, 541 | PARAM_TYPE_INT, 542 | PARAM_TYPE_FLOAT, 543 | PARAM_TYPE_STRING, 544 | }; 545 | } StrategyParamType; 546 | 547 | typedef struct { 548 | enum { 549 | PARAM_CATEGORY_SYSTEM, 550 | PARAM_CATEGORY_ALGO_TRADER, 551 | PARAM_CATEGORY_USER, 552 | }; 553 | } StrategyParamCategory; 554 | 555 | typedef struct { 556 | int strategyId; 557 | int category; 558 | int type; 559 | char name[64]; 560 | char value[64]; 561 | double start; 562 | double end; 563 | double step; 564 | bool isLast; 565 | } StrategyParam; 566 | 567 | typedef struct { 568 | int strategyId; 569 | TimeStamp timestamp; 570 | int level; 571 | char text[LEN_TEXT]; 572 | } StrategyLog; 573 | 574 | // Strategy Position 575 | // A Strategy Position is a virtual position that is created by the entry and exit executions 576 | // generated by a strategy and is independent from any other running strategy's position or an 577 | // Account Position. 578 | typedef struct { 579 | int strategyId; 580 | char instrument[LEN_INSTRUMENT]; 581 | TimeStamp timestamp; 582 | int side; 583 | double quantity; 584 | double frozen; 585 | double unformed; 586 | double avgPx; 587 | double margin; 588 | double unrealizedPnL; 589 | double realizedPnL; 590 | double highestPx; 591 | double lowestPx; 592 | } StrategyPosition; 593 | 594 | typedef struct { 595 | int strategyId; 596 | char name[LEN_NAME]; 597 | char desc[64]; 598 | int state; 599 | bool verbose; 600 | int submittion; 601 | int cancellation; 602 | } StrategyStatus; 603 | 604 | typedef struct { 605 | TimeStamp timestamp; 606 | int level; 607 | char text[LEN_TEXT]; 608 | } SystemLog; 609 | 610 | // For example: begin: "09:00:00", end: "10:15:00" 611 | typedef struct { 612 | char begin[16]; 613 | char end[16]; 614 | } TradingHour; 615 | 616 | typedef struct { 617 | enum { 618 | BackRef, 619 | TimeRange, 620 | }; 621 | } HistoricalDataRequestType; 622 | 623 | typedef struct { 624 | enum { 625 | SyncLoad, 626 | AsyncLoad, 627 | }; 628 | } HistoricalDataLoadMode; 629 | 630 | typedef struct _HistoricalDataRequest { 631 | long reqId; 632 | int type; 633 | char instrument[LEN_INSTRUMENT]; 634 | int resolution; 635 | int interval; 636 | int beginDate; 637 | int beginTime; 638 | int endDate; 639 | int endTime; 640 | int refNum; 641 | int mode; 642 | int srvId; 643 | HistoricalData* histDataBuffer; 644 | int ownerId; 645 | int respond; 646 | int retNum; 647 | } HistoricalDataRequest; 648 | 649 | typedef struct { 650 | int timerId; 651 | int compId; 652 | int ownerId; 653 | char extra[LEN_ID]; 654 | int srvId; 655 | } TimerMsg; 656 | 657 | #define INVALID_TIMER_ID (0) 658 | #define INVALID_STRATEGY_ID (0) 659 | 660 | //////////////////////////////////////////////////////////////////////////////// 661 | // Backtesting Related Definitions 662 | //////////////////////////////////////////////////////////////////////////////// 663 | typedef struct { 664 | enum { 665 | NO_COMMISSION, 666 | FIXED_PER_TRADE, 667 | TRADE_PERCENTAGE // percent of trade value 668 | }; 669 | } CommissionType; 670 | 671 | typedef struct { 672 | enum { 673 | NO_SLIPPAGE, 674 | FIXED_PER_TRADE, 675 | TRADE_PERCENTAGE 676 | }; 677 | } SlippageType; 678 | 679 | typedef struct _Contract { 680 | int secType; 681 | char instrument[32]; 682 | int exchange; 683 | double multiplier; 684 | double tickSize; 685 | double marginRatio; 686 | int commType; 687 | double commission; 688 | int slippageType; 689 | double slippage; 690 | int mktOpenTime; 691 | int mktCloseTime; 692 | _Contract() 693 | { 694 | secType = SecurityType::UNKNOWN; 695 | instrument[0] = '\0'; 696 | exchange = ExchangeCode::EXCHG_UNKNOWN; 697 | multiplier = 1; 698 | tickSize = 1; 699 | marginRatio = 0; 700 | commType = CommissionType::TRADE_PERCENTAGE; 701 | commission = 4.0 / 10000; // default commission 702 | slippageType = SlippageType::TRADE_PERCENTAGE; 703 | slippage = 0; 704 | mktOpenTime = 90000; // 09:00:00 by default 705 | mktCloseTime = 153000; // 15:30:00 by default 706 | } 707 | } Contract; 708 | 709 | typedef struct { 710 | double initialCapital; 711 | long long tradingPeriod; 712 | double finalPortfolioValue; 713 | // 'Account Size Required' calculates the amount of money you must 714 | // have in your account to trade the strategy. 715 | double acctSizeRequired; 716 | double cumReturn; 717 | double annualReturn; 718 | double monthlyReturn; 719 | double totalNetProfits; 720 | double maxDD; // Max. Drawdown. 721 | double maxDDPercentage; 722 | double maxCTCDD; // Max. Close To Close Drawdown. 723 | TimeStamp maxDDBegin; 724 | TimeStamp maxDDEnd; 725 | int longestDDDuration; // Longest Drawdown Duration, in days 726 | TimeStamp longestDDDBegin; 727 | TimeStamp longestDDDEnd; 728 | double retOnMaxDD; // Return on max drawdown. 729 | // The sum of money you would make compared to the sum of money required 730 | // to trade the strategy, after considering the margin and margin calls. 731 | // This value is calculated by dividing the net profit by the account 732 | // size required. 733 | // For leverage trading this value is more important than the Total Net 734 | // Profit (e.g., buy or sell futures contracts or stocks on margin). 735 | // When trading using leverage, you must a sizable margin deposit. 736 | // The margin size is a certain percent of the overall transaction cost. 737 | // In addition, when trading on leverage, you need sufficient money to 738 | // counteract equity dips - the same as in futures and stock trading is 739 | // named margin calls. 740 | double retOnAcctSizeRequired; // Return on Account Size Required. 741 | 742 | // Nobel laureate William Sharpe introduced the Sharpe Ratio, in 1996, 743 | // under the name reward-to-variability ratio. This ratio is perhaps the 744 | // best known of the return to risk measures. The formula for the Sharpe 745 | // ratio is SR = (MR -RFR) / SD, where MR is the average return for period 746 | // (monthly), RFR is the risk-free rate of return. SD is the standard 747 | // deviation of returns. Thus, this formula yields a value that could be 748 | // loosely defined as return per unit risked if we accept the premise 749 | // that variability is risk. The higher Sharpe ratio the smoother the 750 | // equity curve on a monthly basis. Having a smooth equity curve is a very 751 | // important objective for many traders. That is why this ratio is widely 752 | // used both at individual market and at a portfolio level. 753 | double sharpeRatio; 754 | 755 | // The total number of trades (both winning and losing) generated by 756 | // a strategy. The total number of trades is important for a number of 757 | // reasons. For example, no matter how large is the strategies Total 758 | // Net Profit, one must be sure the value is statistically valid, i.e. 759 | // the number of trades is large enough. Also important is the relation 760 | // between the number of trades and time; even good, profitable trades 761 | // may be taking place too rarely or too frequently for your needs. 762 | long totalTrades; 763 | 764 | // The number of positions currently opened. 765 | long totalOpenTrades; 766 | // The total number of winning trades generated by a strategy. 767 | long winningTrades; 768 | // The total number of losing trades generated by a strategy. 769 | long losingTrades; 770 | 771 | // The percentage of winning trades generated by a strategy. 772 | // Calculated by dividing the number of winning trades by total 773 | // number of trades generated by a strategy. Percent profitable is not a 774 | // very reliable measure by itself since approaches to profitability can 775 | // differ. A strategy could have many small winning trades, making the 776 | // percent profitable high with a small average winning trade, or a few big 777 | // winning trades accounting for a low percent profitable and a big average 778 | // winning trade. Many successful strategies have a percent profitability 779 | // below 50% but are still profitable due to proper loss control. 780 | double percentProfitable; 781 | 782 | // The Gross Profits divided by the number of Winning Trades. 783 | double avgWinningTrade; 784 | 785 | // The Gross Loss divided by the number of Losing Trades. 786 | double avgLosingTrade; 787 | 788 | // The average value of how many $ you win for every $ you lose. 789 | // This is calculated by dividing the average winning trades by the average 790 | // losing trade. This field is not a very meaningful value by itself, because 791 | // strategies can have different approaches to profitability. A strategy may 792 | // attempt trading at every possibility in order to capture many small profits 793 | // yet have an average losing trade greater than the average winning trade. 794 | // The higher this value is the better, but it should be regarded together with 795 | // the percentage of winning trades and the net profit. 796 | double ratioAvgWinAvgLoss; 797 | 798 | double avgProfit; 799 | double maxProfit; 800 | double minProfit; 801 | double grossProfit; 802 | double grossLoss; 803 | double slippagePaid; 804 | double commissionPaid; 805 | } BacktestingMetrics; 806 | 807 | typedef struct { 808 | double cumReturns; 809 | double totalNetProfits; 810 | double sharpeRatio; 811 | double maxDrawDown; 812 | double retOnMaxDD; 813 | } SimplifiedMetrics; 814 | 815 | typedef struct { 816 | TimeStamp tradingDay; 817 | double closedProfit; 818 | double realizedProfit; 819 | double posProfit; 820 | int tradesNum; 821 | int openVolume; 822 | int tradedVolume; 823 | int todayPosition; 824 | double commissions; 825 | double slippages; 826 | double tradeCost; 827 | 828 | double cash; 829 | double equity; 830 | double profit; 831 | double margin; 832 | 833 | double cumRealizedProfit; 834 | int cumTradesNum; 835 | int cumTradedVolume; 836 | int cumCloseVolume; 837 | double cumCommissions; 838 | double cumSlippages; 839 | double cumTradeCost; 840 | } DailyMetrics; 841 | 842 | } // namespace AlgoSE 843 | 844 | #endif // ALGOSE_DEFINES_H -------------------------------------------------------------------------------- /Inc/Engine.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_ENGINE_H 2 | #define ALGOSE_ENGINE_H 3 | 4 | #include "Defines.h" 5 | #include "IEngine.h" 6 | 7 | namespace AlgoSE 8 | { 9 | 10 | #define DEFAULT_ENGINE_CONFIG_FILE "AlgoSE.xml" 11 | 12 | //////////////////////////////////////////////////////////////////////////////// 13 | class EngineImpl; 14 | class ServiceConfig; 15 | class SimulatorConfig; 16 | 17 | class ALGOSE_API Engine : public IEngine 18 | { 19 | public: 20 | /* API collections for engine and strategy controlling. */ 21 | static Engine* getInstance(); 22 | void setRunningMode(int mode); 23 | void enableRemoteSrvAccess(); 24 | void setRemoteSrvAddress(const char* addr, int port); 25 | void setRemoteMgrListenPort(int port); 26 | void setRemoteMgrUnderlyingServiceName(int type, const char* name); 27 | void enableRemoteManager(); 28 | void setLogFilePath(const char* path); 29 | void disableConsoleLog(int mask); 30 | void enableConsoleLog(int mask); 31 | void setSimulatorConfig(const SimulatorConfig& config); 32 | void enablePerformanceMode(); 33 | bool isPerformanceMode() const; 34 | bool registerListener(Listener* listener); 35 | bool unregisterListener(Listener* listener); 36 | bool initialize(const char* config = ""); 37 | int loadStrategy(const char* config); 38 | int loadStrategy(Strategy& strategy, const StrategyConfig& config); 39 | int loadStrategy(const StrategyConfig& config); 40 | bool run(); 41 | bool launchStrategy(int stratId); 42 | int getStrategyStatus(int stratId) const; 43 | bool assignStrategyPosition(int stratId, const char* instrument, int side, int quantity, double price); 44 | bool sendStrategyCommand(int stratId, const char* command); 45 | bool setStrategyParameter(int stratId, const StrategyParam& param); 46 | bool showVerboseMsg(int stratId); 47 | bool hideVerboseMsg(int stratId); 48 | bool pauseStrategy(int stratId); 49 | bool resumeStrategy(int stratId); 50 | bool stopStrategy(int stratId); 51 | bool registerService(const char* name, int type, void* srvObject); 52 | bool registerService(const ServiceConfig& config); 53 | bool reloadService(int type, int id); 54 | bool reinitializeService(int type, int id); 55 | void writeLogMsg(int level, const char* msg); 56 | MarketDataAPI* getMarketDataAPI(); 57 | TradingAPI* getTradingAPI(); 58 | bool stop(); 59 | int version(); 60 | void release(); 61 | 62 | private: 63 | Engine(); 64 | Engine(Engine const&); 65 | Engine& operator=(Engine const&); 66 | ~Engine(); 67 | 68 | private: 69 | static Engine* m_instance; 70 | EngineImpl* m_implementor; 71 | }; 72 | 73 | } // namespace AlgoSE 74 | 75 | #endif // ALGOSE_ENGINE_H -------------------------------------------------------------------------------- /Inc/Event.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_EVENT_H 2 | #define ALGOSE_EVENT_H 3 | 4 | #include 5 | #include "DateTime.h" 6 | 7 | namespace AlgoSE 8 | { 9 | 10 | class ALGOSE_API IEventHandler 11 | { 12 | public: 13 | virtual void onEvent( 14 | int type, 15 | const DateTime& datetime, 16 | const void * context) = 0; 17 | }; 18 | 19 | class ALGOSE_API Event 20 | { 21 | public: 22 | enum EvtType { 23 | EvtNone, 24 | EvtDispatcherStart, 25 | EvtDispatcherIdle, 26 | EvtDispatcherTimeElapsed, 27 | EvtDataSeriesNewValue, 28 | EvtDataSeriesReset, 29 | EvtOrderUpdate, 30 | EvtMarketDataProcessed, 31 | EvtNewMarketData, 32 | EvtNewReturns, 33 | EvtNewTradingDay 34 | }; 35 | 36 | typedef struct { 37 | DateTime datetime; 38 | void* data; 39 | } Context; 40 | 41 | Event(EvtType type = EvtNone); 42 | void setType(EvtType type); 43 | EvtType getType() const; 44 | void subscribe(IEventHandler* handler); 45 | void unsubscribe(); 46 | void emitEvt(const DateTime& datetime, const void *context); 47 | 48 | private: 49 | void applyChanges(); 50 | 51 | private: 52 | std::vector m_handlers; 53 | std::vector m_toSubscribe; 54 | std::vector m_toUnsubscribe; 55 | volatile bool m_emitting; 56 | bool m_applyChanges; 57 | EvtType m_type; 58 | }; 59 | 60 | } // namespace AlgoSE 61 | 62 | #endif // ALGOSE_EVENT_H -------------------------------------------------------------------------------- /Inc/HighLow.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_HIGH_LOW_H 2 | #define ALGOSE_HIGH_LOW_H 3 | 4 | #include 5 | #include "Technical.h" 6 | 7 | namespace AlgoSE 8 | { 9 | 10 | class ALGOSE_API HighLowEventWindow : public EventWindow 11 | { 12 | public: 13 | void init(int period, bool useMin); 14 | void onNewValue(const DateTime& datetime, const double& value); 15 | double getValue() const; 16 | 17 | private: 18 | bool m_useMin; 19 | int m_winSize; 20 | double m_minimun; 21 | double m_maximum; 22 | std::int64_t count; 23 | 24 | std::deque< std::pair > m_window; 25 | }; 26 | 27 | class ALGOSE_API High : public EventBasedFilter 28 | { 29 | public: 30 | void init(DataSeries& dataSeries, int period, int maxLen = DataSeries::DEFAULT_MAX_LEN); 31 | 32 | private: 33 | HighLowEventWindow m_eventWindow; 34 | }; 35 | 36 | class ALGOSE_API Low : public EventBasedFilter 37 | { 38 | public: 39 | void init(DataSeries& dataSeries, int period, int maxLen = DataSeries::DEFAULT_MAX_LEN); 40 | 41 | private: 42 | HighLowEventWindow m_eventWindow; 43 | }; 44 | 45 | ALGOSE_API int SwingHigh(const DataSeries& dataSeries, int leftStrength, int rightStrength); 46 | 47 | ALGOSE_API int SwingLow(const DataSeries& dataSeries, int leftStrength, int rightStrength); 48 | 49 | } // namespace AlgoSE 50 | 51 | #endif // ALGOSE_HIGH_LOW_H 52 | -------------------------------------------------------------------------------- /Inc/IEngine.h: -------------------------------------------------------------------------------- 1 | #ifndef ENGINE_INTERFACE_H 2 | #define ENGINE_INTERFACE_H 3 | 4 | #include "Defines.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | class Strategy; 10 | class StrategyConfig; 11 | 12 | class ALGOSE_API IEngine 13 | { 14 | public: 15 | class Listener { 16 | public: 17 | virtual ~Listener() {} 18 | virtual void onSystemLog(const SystemLog& log) {} 19 | virtual void onServiceStatus(const ServiceStatus& status) {} 20 | virtual void onAccountDetails(const AccountDetails& account) {} 21 | virtual void onAccountPosition(const AccountPosition& position) {} 22 | virtual void onTick(const Tick& tick) {} 23 | virtual void onBar(const Bar& bar) {} 24 | virtual void onOrderStatus(const Order& order) {} 25 | virtual void onExecutionReport(const Execution& execution) {} 26 | virtual void onStrategyStatus(const StrategyStatus& status) {} 27 | virtual void onStrategyParameter(const StrategyParam& param) {} 28 | virtual void onStrategyPosition(const StrategyPosition& position) {} 29 | virtual void onStrategyLog(const StrategyLog& log) {} 30 | virtual void onRemoteConnect() {} 31 | virtual void onRemoteDisconnect() {} 32 | }; 33 | 34 | class MarketDataAPI { 35 | public: 36 | virtual ~MarketDataAPI() {} 37 | virtual int subscribe(const char** instruments, int num, int srvId = 0) = 0; 38 | virtual bool subscribe(const char* instrument, int srvId = 0) = 0; 39 | virtual double getTickSize(const char* instrument, int srvId = 0) = 0; 40 | virtual double getLastPrice(const char* instrument, int srvId = 0) = 0; 41 | virtual double getAskPrice(const char* instrument, int srvId = 0) = 0; 42 | virtual double getBidPrice(const char* instrument, int srvId = 0) = 0; 43 | virtual double getUpperLimitPrice(const char* instrument, int srvId = 0) = 0; 44 | virtual double getLowerLimitPrice(const char* instrument, int srvId = 0) = 0; 45 | }; 46 | 47 | class TradingAPI { 48 | public: 49 | virtual ~TradingAPI() {} 50 | virtual bool buy(const char* instrument, double quantity, double price, char* clOrdId = nullptr, int srvId = 0) = 0; 51 | virtual bool sell(const char* instrument, double quantity, double price, char* clOrdId = nullptr, int srvId = 0) = 0; 52 | virtual bool sellShort(const char* instrument, double quantity, double price, char* clOrdId = nullptr, int srvId = 0) = 0; 53 | virtual bool buyToCover(const char* instrument, double quantity, double price, char* clOrdId = nullptr, int srvId = 0) = 0; 54 | virtual bool submitOrder(const Order& order) = 0; 55 | virtual bool cancelOrder(const Order& order) = 0; 56 | virtual bool cancelOrder(const char* clOrdId) = 0; 57 | virtual void closeAllPos() = 0; 58 | }; 59 | 60 | /* API collections for engine and strategy controlling. */ 61 | virtual ~IEngine() {} 62 | virtual bool registerListener(Listener* listener) = 0; 63 | virtual bool unregisterListener(Listener* listener) = 0; 64 | virtual int loadStrategy(const char* config) = 0; 65 | virtual int loadStrategy(Strategy& strategy, const StrategyConfig& config) = 0; 66 | virtual int loadStrategy(const StrategyConfig& config) = 0; 67 | virtual bool run() = 0; 68 | virtual bool launchStrategy(int stratId) = 0; 69 | virtual int getStrategyStatus(int stratId) const = 0; 70 | virtual bool assignStrategyPosition(int stratId, const char* instrument, int side, int quantity, double price) = 0; 71 | virtual bool sendStrategyCommand(int stratId, const char* command) = 0; 72 | virtual bool setStrategyParameter(int stratId, const StrategyParam& param) = 0; 73 | virtual bool showVerboseMsg(int stratId) = 0; 74 | virtual bool hideVerboseMsg(int stratId) = 0; 75 | virtual bool pauseStrategy(int stratId) = 0; 76 | virtual bool resumeStrategy(int stratId) = 0; 77 | virtual bool stopStrategy(int stratId) = 0; 78 | virtual void writeLogMsg(int level, const char* msg) = 0; 79 | virtual MarketDataAPI* getMarketDataAPI() = 0; 80 | virtual TradingAPI* getTradingAPI() = 0; 81 | virtual bool stop() = 0; 82 | virtual int version() = 0; 83 | }; 84 | 85 | } // namespace AlgoSE 86 | 87 | #endif // ENGINE_INTERFACE_H -------------------------------------------------------------------------------- /Inc/MA.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_MA_H 2 | #define ALGOSE_MA_H 3 | 4 | #include "Technical.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | //////////////////////////////////////////////////////////////////////////////// 10 | // This is the formula I'm using to calculate the averages based on previous ones. 11 | // 1 2 3 4 12 | // x x x 13 | // x x x 14 | // 15 | // avg0 = (a + b + c) / 3 16 | // avg1 = (b + c + d) / 3 17 | // 18 | // avg0 = avg1 + x 19 | // (a + b + c) / 3 = (b + c + d) / 3 + x 20 | // a/3 + b/3 + c/3 = b/3 + c/3 + d/3 + x 21 | // a/3 = d/3 + x 22 | // x = a/3 - d/3 23 | // 24 | // avg1 = avg0 - x 25 | // avg1 = avg0 + d/3 - a/3 26 | class ALGOSE_API MAEventWindow : public EventWindow 27 | { 28 | public: 29 | void init(int period); 30 | void onNewValue(const DateTime& datetime, const double& value); 31 | double getValue() const; 32 | 33 | private: 34 | double m_value; 35 | }; 36 | 37 | // Simple Moving Average filter. 38 | class ALGOSE_API MA : public EventBasedFilter 39 | { 40 | public: 41 | MA(); 42 | // @param: dataSeries: The DataSeries instance being filtered. 43 | // @param: period: The number of values to use to calculate the SMA. 44 | // @param: maxLen: The maximum number of values to hold. 45 | // Once a bounded length is full, when new items are added, a corresponding number of items are discarded from the opposite end. 46 | void init(DataSeries& dataSeries, int period, int maxLen = DataSeries::DEFAULT_MAX_LEN); 47 | 48 | private: 49 | MAEventWindow m_maEventWnd; 50 | }; 51 | 52 | //////////////////////////////////////////////////////////////////////////////// 53 | class ALGOSE_API EMAEventWindow : public EventWindow 54 | { 55 | public: 56 | void init(int period); 57 | void onNewValue(const DateTime& datetime, const double& value); 58 | double getValue() const; 59 | 60 | private: 61 | double m_multiplier; 62 | double m_value; 63 | }; 64 | 65 | class ALGOSE_API EMA : public EventBasedFilter 66 | { 67 | public: 68 | // Exponential Moving Average filter. 69 | // @param dataSeries: The DataSeries instance being filtered. 70 | // @param period: The number of values to use to calculate the EMA. Must be an integer greater than 1. 71 | // @param maxLen: The maximum number of values to hold. 72 | // Once a bounded length is full, when new items are added, a corresponding number of items are discarded from the opposite end. 73 | void init(DataSeries& dataSeries, int period, int maxLen = DataSeries::DEFAULT_MAX_LEN); 74 | 75 | private: 76 | EMAEventWindow m_emaEventWnd; 77 | }; 78 | 79 | //////////////////////////////////////////////////////////////////////////////// 80 | class ALGOSE_API SMAEventWindow : public EventWindow 81 | { 82 | public: 83 | void init(int period, double weight); 84 | void onNewValue(const DateTime& datetime, const double& value); 85 | double getValue() const; 86 | 87 | private: 88 | double m_weight; 89 | double m_multiplier; 90 | double m_value; 91 | }; 92 | 93 | class ALGOSE_API SMA : public EventBasedFilter 94 | { 95 | public: 96 | void init(DataSeries& dataSeries, int period, double weight = 1, int maxLen = DataSeries::DEFAULT_MAX_LEN); 97 | 98 | private: 99 | SMAEventWindow m_smaEventWnd; 100 | }; 101 | 102 | //////////////////////////////////////////////////////////////////////////////// 103 | class ALGOSE_API AMAEventWindow : public EventWindow 104 | { 105 | public: 106 | void init(int effRatioLen, int fastAvgLen, int slowAvgLen); 107 | void onNewValue(const DateTime& datetime, const double& value); 108 | double getValue() const; 109 | 110 | private: 111 | double m_value; 112 | int m_effRatioLen; 113 | int m_fastAvgLen; 114 | int m_slowAvgLen; 115 | 116 | // Scaled smoothing constant 117 | double m_fastSc; 118 | double m_slowSc; 119 | }; 120 | 121 | // Kaufman Adaptive Moving Average filter. 122 | class ALGOSE_API AMA : public EventBasedFilter 123 | { 124 | public: 125 | AMA(); 126 | // @param: dataSeries: The DataSeries instance being filtered. 127 | // @param: effRatioLen: The number of values to use to calculate the AMA. 128 | // @param: maxLen: The maximum number of values to hold. 129 | // Once a bounded length is full, when new items are added, a corresponding number of items are discarded from the opposite end. 130 | void init(DataSeries& dataSeries, int effRatioLen, int fastAvgLen = 2, int slowAvgLen = 30, int maxLen = DataSeries::DEFAULT_MAX_LEN); 131 | 132 | private: 133 | AMAEventWindow m_amaEventWnd; 134 | }; 135 | 136 | } // namespace AlgoSE 137 | 138 | #endif // ALGOSE_MA_H -------------------------------------------------------------------------------- /Inc/OrderList.h: -------------------------------------------------------------------------------- 1 | #ifndef ORDER_LIST_H 2 | #define ORDER_LIST_H 3 | 4 | #include "Defines.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | class OrderListImpl; 10 | 11 | class ALGOSE_API OrderList 12 | { 13 | public: 14 | typedef Order* iterator; 15 | typedef const Order* const_iterator; 16 | 17 | OrderList(); 18 | OrderList(const OrderList& other); 19 | ~OrderList(); 20 | OrderList &operator=(const OrderList& other); 21 | void push_back(const Order& order); 22 | void clear(); 23 | int size() const; 24 | const Order& operator[](int idx) const; 25 | 26 | iterator begin(); 27 | const_iterator begin() const; 28 | iterator end(); 29 | const_iterator end() const; 30 | 31 | OrderListImpl& getImplementor() const; 32 | 33 | private: 34 | OrderListImpl* m_implementor; 35 | }; 36 | 37 | } // namespace AlgoSE 38 | 39 | #endif // ORDER_LIST_H -------------------------------------------------------------------------------- /Inc/PositionList.h: -------------------------------------------------------------------------------- 1 | #ifndef POSITION_LIST_H 2 | #define POSITION_LIST_H 3 | 4 | #include "Defines.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | class AccountPositionListImpl; 10 | class StrategyPositionListImpl; 11 | 12 | class ALGOSE_API AccountPositionList 13 | { 14 | public: 15 | typedef AccountPosition* iterator; 16 | typedef const AccountPosition* const_iterator; 17 | 18 | AccountPositionList(); 19 | AccountPositionList(const AccountPositionList& other); 20 | ~AccountPositionList(); 21 | AccountPositionList &operator=(const AccountPositionList& other); 22 | 23 | void clear(); 24 | int size() const; 25 | const AccountPosition& operator[](int idx) const; 26 | 27 | iterator begin(); 28 | const_iterator begin() const; 29 | iterator end(); 30 | const_iterator end() const; 31 | 32 | AccountPositionListImpl& getImplementor() const; 33 | 34 | private: 35 | AccountPositionListImpl* m_implementor; 36 | }; 37 | 38 | class ALGOSE_API StrategyPositionList 39 | { 40 | public: 41 | typedef StrategyPosition* iterator; 42 | typedef const StrategyPosition* const_iterator; 43 | 44 | StrategyPositionList(); 45 | StrategyPositionList(const StrategyPositionList& other); 46 | ~StrategyPositionList(); 47 | StrategyPositionList &operator=(const StrategyPositionList& other); 48 | 49 | void clear(); 50 | int size() const; 51 | const StrategyPosition& operator[](int idx) const; 52 | 53 | iterator begin(); 54 | const_iterator begin() const; 55 | iterator end(); 56 | const_iterator end() const; 57 | 58 | StrategyPositionListImpl& getImplementor() const; 59 | 60 | private: 61 | StrategyPositionListImpl* m_implementor; 62 | }; 63 | 64 | } // namespace AlgoSE 65 | 66 | #endif // POSITION_LIST_H -------------------------------------------------------------------------------- /Inc/Service.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_SERVICE_H 2 | #define ALGOSE_SERVICE_H 3 | 4 | #include "Defines.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | #if defined(__PLATFORM_WINDOWS__) 10 | #ifdef SERVICE_EXPORTS 11 | #define SERVICE_API __declspec(dllexport) 12 | #else 13 | #define SERVICE_API __declspec(dllimport) 14 | #endif 15 | #elif defined(__PLATFORM_LINUX__) 16 | #define SERVICE_API __attribute__((visibility("default"))) 17 | #else 18 | // do nothing and hope for the best? 19 | #define SERVICE_API 20 | #pragma warning Unknown dynamic link import/export semantics. 21 | #endif 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // Service Definitions 25 | //////////////////////////////////////////////////////////////////////////////// 26 | typedef struct { 27 | enum { 28 | SERVICE_UNKNOWN = 0x00, 29 | SERVICE_TIMER = 0x01, // Timer. 30 | SERVICE_INSTRUMENT = 0x02, // Instrument definitions. 31 | SERVICE_MARKET_DATA = 0x04, // Real time market data. 32 | SERVICE_HISTORICAL_DATA = 0x08, // Historical market data. 33 | SERVICE_ORDER_EXECUTION = 0x10, // Trade execution. 34 | }; 35 | } ServiceType; 36 | 37 | typedef struct { 38 | enum { 39 | LOADED, 40 | CONNECTED, 41 | CONNECT_ERROR, 42 | DISCONNECTED, 43 | INITIALIZE_DONE, 44 | }; 45 | } MarketDataServiceState; 46 | 47 | typedef struct { 48 | enum { 49 | LOADED, 50 | CONNECTED, 51 | CONNECT_ERROR, 52 | DISCONNECTED, 53 | INITIALIZE_DONE, 54 | READY, 55 | RESET, 56 | }; 57 | } ExecutionServiceState; 58 | 59 | typedef struct { 60 | enum { 61 | LOADED, 62 | CONNECTED, 63 | CONNECT_ERROR, 64 | DISCONNECTED, 65 | INITIALIZE_DONE, 66 | }; 67 | } HistoricalDataServiceState; 68 | 69 | typedef struct { 70 | enum { 71 | LOADED, 72 | CONNECTED, 73 | CONNECT_ERROR, 74 | DISCONNECTED, 75 | INITIALIZE_DONE, 76 | }; 77 | } TimerServiceState; 78 | 79 | class EngineImpl; 80 | 81 | class ALGOSE_API ServiceBase 82 | { 83 | public: 84 | ServiceBase(); 85 | virtual ~ServiceBase(); 86 | 87 | virtual bool initialize(const char* config) = 0; 88 | virtual bool reinitialize() { return false; } 89 | virtual bool release() = 0; 90 | 91 | void setId(int id); 92 | int getId() const; 93 | void setType(int type); 94 | int getType() const; 95 | void setName(const char* name); 96 | const char* getName() const; 97 | void attach(EngineImpl* engine); 98 | 99 | protected: 100 | const char* getParamValue(const char* name); 101 | void writeLog(int level, const char* fmt, ...); 102 | void notifyStatus(int state, const char* desc = ""); 103 | 104 | protected: 105 | int m_id; 106 | int m_type; 107 | char m_name[32]; 108 | EngineImpl* m_engine; 109 | }; 110 | 111 | #define INVALID_SERVICE_ID (-1) 112 | 113 | #define TIMER_SERVICE_TYPE_NAME "Timer" 114 | 115 | class ALGOSE_API TimerService : public ServiceBase 116 | { 117 | public: 118 | virtual int registerTimer(int msFromNow, const char* extra, int compId, int ownerId) = 0; 119 | virtual void unregisterTimer(int timerId) = 0; 120 | 121 | protected: 122 | void notifyTimer(TimerMsg& timerMsg); 123 | }; 124 | 125 | extern "C" typedef TimerService *CreateTimerServiceProc(); 126 | #define EXPORT_TIMER_SERVICE(service_name) \ 127 | extern "C" SERVICE_API TimerService* CreateTimerService() \ 128 | { \ 129 | return new service_name; \ 130 | } 131 | 132 | #define INSTRUMENT_SERVICE_TYPE_NAME "Instrument" 133 | 134 | class ALGOSE_API SecurityDefinitionService : public ServiceBase 135 | { 136 | protected: 137 | void notifySecurityDefinition(SecurityDefinition& security); 138 | }; 139 | 140 | #define MARKET_DATA_SERVICE_TYPE_NAME "MarketData" 141 | 142 | class ALGOSE_API MarketDataService : public ServiceBase 143 | { 144 | public: 145 | // Reenterable and thread-safe must be guaranteed by implementor. 146 | virtual int getSupportedExchanges(); 147 | virtual int subscribe(const char** instruments, int num) = 0; 148 | virtual int unsubscribe(const char** instruments, int num) = 0; 149 | 150 | protected: 151 | void notifyMarketData(Tick& tick); 152 | }; 153 | 154 | extern "C" typedef MarketDataService *CreateMarketDataServiceProc(); 155 | #define EXPORT_MARKET_DATA_SERVICE(service_name) \ 156 | extern "C" SERVICE_API MarketDataService* CreateMarketDataService() \ 157 | { \ 158 | return new service_name; \ 159 | } 160 | 161 | #define EXECUTION_SERVICE_TYPE_NAME "Execution" 162 | 163 | #define EXEC_SRV_POS_PRICING_MODEL_PARAM_NAME "PosPricingModel" 164 | #define EXEC_SRV_POS_PRICING_FIFO "FIFO" 165 | #define EXEC_SRV_POS_PRICING_COMBINED "Combined" 166 | 167 | class ALGOSE_API ExecutionService : public ServiceBase 168 | { 169 | public: 170 | // Reenterable and thread-safe must be guaranteed by implementor. 171 | virtual bool submitOrder(const Order& order) = 0; 172 | virtual bool cancelOrder(const Order& order) = 0; 173 | virtual bool motifyOrder(const Order& order) = 0; 174 | 175 | protected: 176 | void notifySecurityDefinition(SecurityDefinition& security); 177 | void notifyOrderStatus(Order& order); 178 | void notifyOrderOperationStatus(OrderOperation& operation); 179 | void notifyExecutionReport(Execution& execution); 180 | void notifyAccountDetails(AccountDetails& details); 181 | void notifyAccountPosition(AccountPosition& position); 182 | void initializeDone(); 183 | void ready(); 184 | void reset(); 185 | }; 186 | 187 | extern "C" typedef ExecutionService *CreateExecutionServiceProc(); 188 | #define EXPORT_EXECUTION_SERVICE(service_name) \ 189 | extern "C" SERVICE_API ExecutionService* CreateExecutionService() \ 190 | { \ 191 | return new service_name; \ 192 | } 193 | 194 | #define HISTORICAL_DATA_SERVICE_TYPE_NAME "HistoricalData" 195 | 196 | class ALGOSE_API HistoricalDataService : public ServiceBase 197 | { 198 | public: 199 | virtual int requestHistoricMarketData(const HistoricalDataRequest& request) = 0; 200 | virtual void freeRequest(int reqId) = 0; 201 | }; 202 | 203 | extern "C" typedef HistoricalDataService *CreateHistoricalDataServiceProc(); 204 | #define EXPORT_HISTORICAL_DATA_SERVICE(service_name) \ 205 | extern "C" SERVICE_API HistoricalDataService* CreateHistoricalDataService() \ 206 | { \ 207 | return new service_name; \ 208 | } 209 | 210 | #define ALERT_SERVICE_TYPE_NAME "Alert" 211 | 212 | class ALGOSE_API AlertService : public ServiceBase 213 | { 214 | public: 215 | virtual int sendAlertMessage(int level, const char* text) = 0; 216 | virtual bool cancelAlert(int alertId) = 0; 217 | }; 218 | 219 | extern "C" typedef AlertService *CreateAlertServiceProc(); 220 | #define EXPORT_ALERT_SERVICE(service_name) \ 221 | extern "C" SERVICE_API AlertService* CreateAlertService() \ 222 | { \ 223 | return new service_name; \ 224 | } 225 | 226 | } // namespace AlgoSE 227 | 228 | #endif // ALGOSE_SERVICE_H -------------------------------------------------------------------------------- /Inc/ServiceConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_SERVICE_CONFIG_H 2 | #define ALGOSE_SERVICE_CONFIG_H 3 | 4 | #include "Defines.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | class ServiceConfigImpl; 10 | 11 | class ALGOSE_API ServiceConfig 12 | { 13 | public: 14 | ServiceConfig(); 15 | ServiceConfig(const ServiceConfig& other); 16 | ~ServiceConfig(); 17 | ServiceConfig &operator=(const ServiceConfig& other); 18 | 19 | void setType(int type); 20 | int getType() const; 21 | void setName(const char* name); 22 | const char* getName() const; 23 | void setConfigFile(const char* file); 24 | const char* getConfigFile() const; 25 | void setSharedLibrary(const char* library); 26 | const char* getSharedLibrary() const; 27 | void setServiceObject(void* object); 28 | void* getServiceObject() const; 29 | void setParameter(const char* name, const char* value); 30 | 31 | const ServiceConfigImpl& getImplementor() const; 32 | 33 | private: 34 | ServiceConfigImpl* m_implementor; 35 | }; 36 | 37 | } // namespace AlgoSE 38 | 39 | #endif // ALGOSE_SERVICE_CONFIG_H -------------------------------------------------------------------------------- /Inc/SimulatorConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATOR_CONFIG_H 2 | #define SIMULATOR_CONFIG_H 3 | 4 | #include "Defines.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | class SimulatorConfigImpl; 10 | 11 | class ALGOSE_API SimulatorConfig 12 | { 13 | public: 14 | enum { 15 | REPORT_SUMMARY = 0x01, 16 | REPORT_TRADES = 0x02, 17 | REPORT_POSITION = 0x04, 18 | REPORT_RETURNS = 0x08, 19 | REPORT_EQUITIES = 0x10, 20 | REPORT_DAILY_METRICS = 0x20, 21 | REPORT_OPTIMIZATION = 0x40 22 | }; 23 | 24 | SimulatorConfig(); 25 | SimulatorConfig(const SimulatorConfig& other); 26 | ~SimulatorConfig(); 27 | SimulatorConfig &operator=(const SimulatorConfig& other); 28 | void setRunningMode(int mode); 29 | int getRunningMode() const; 30 | void registerDataStream(const char* instrument, int resolution, int interval, const char* filename, int format, const Contract& contract); 31 | void setCash(double cash); 32 | double getCash() const; 33 | void setTradingDayEndTime(int timeNum); 34 | int getTradingDayEndTime() const; 35 | void setProcessorNum(int num); 36 | void setOptimizeMode(int mode); 37 | void enableReporting(int mask); 38 | void disableReporting(int mask); 39 | bool isReportingEnable(int mask) const; 40 | void setSummaryReportFileName(const char* filename); 41 | const char* getSummaryReportFileName() const; 42 | void setDailyMetricsReportFileName(const char* filename); 43 | const char* getDailyMetricsReportFileName() const; 44 | void setTradeLogFileName(const char* filename); 45 | const char* getTradeLogFileName() const; 46 | void setPositionsReportFileName(const char* filename); 47 | const char* getPositionsReportFileName() const; 48 | void setReturnsReportFile(const char* filename); 49 | const char* getReturnsReportFileName() const; 50 | const char* getEquitiesReportFileName() const; 51 | void setOptimizationReportFileName(const char* filename); 52 | const char* getOptimizationReportFileName() const; 53 | 54 | const SimulatorConfigImpl& getImplementor() const; 55 | 56 | private: 57 | SimulatorConfigImpl* m_implementor; 58 | }; 59 | 60 | } // namespace AlgoSE 61 | 62 | #endif // SIMULATOR_CONFIG_H -------------------------------------------------------------------------------- /Inc/Strategy.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_STRATEGY_H 2 | #define ALGOSE_STRATEGY_H 3 | 4 | #include "Defines.h" 5 | #include "BarSeries.h" 6 | #include "OrderList.h" 7 | #include "PositionList.h" 8 | #include "AlgoOrder.h" 9 | #include "StrategyConfig.h" 10 | 11 | // The following ifdef block is the standard way of creating macros which make exporting 12 | // from a DLL simpler. All files within this DLL are compiled with the STRATEGY_EXPORTS 13 | // symbol defined on the command line. this symbol should not be defined on any project 14 | // that uses this DLL. This way any other project whose source files include this file see 15 | // STRATEGY_API functions as being imported from a DLL, whereas this DLL sees symbols 16 | // defined with this macro as being exported. 17 | #if defined(__PLATFORM_WINDOWS__) 18 | #ifdef STRATEGY_EXPORTS 19 | #define STRATEGY_API __declspec(dllexport) 20 | #else 21 | #define STRATEGY_API __declspec(dllimport) 22 | #endif 23 | #elif defined(__PLATFORM_LINUX__) 24 | #ifdef STRATEGY_EXPORTS 25 | #define STRATEGY_API __attribute__((visibility("default"))) 26 | #else 27 | #define STRATEGY_API 28 | #endif 29 | #else 30 | #define STRATEGY_API 31 | #endif 32 | 33 | namespace AlgoSE 34 | { 35 | 36 | class IRuntime; 37 | 38 | class STRATEGY_API Strategy 39 | { 40 | public: 41 | enum State { 42 | UNKNOWN = 0, 43 | LOADING, // Loading and filling historical data. 44 | RUNNING, // Receiving realtime market data. 45 | PAUSED, 46 | STOPPED, 47 | UNLOADED, 48 | }; 49 | 50 | Strategy(); 51 | virtual ~Strategy(); 52 | 53 | void attach(IRuntime* runtime); 54 | virtual void onCreate() {} 55 | virtual void onSetParameter(const char* name, int type, const char* value, bool isLast) {} 56 | virtual int onBarSeriesFeed(const char* instrument, int resolution, int interval, int num, Tick* buffer) { return 0; } 57 | virtual void onStart() {} 58 | virtual void onTick(const Tick& tick) {} 59 | virtual void onBar(const Bar& bar) {} 60 | 61 | virtual void onOrderSubmitted(const Order& order) {} 62 | virtual void onOrderUpdated(const Order& order) {} 63 | virtual void onExecutionReport(const Execution& exec) {} 64 | virtual void onOrderPartiallyFilled(const Order& order) {} 65 | // This method is called when an order is filled. 66 | virtual void onOrderFilled(const Order& order) {} 67 | // This method is called when an order is rejected. 68 | virtual void onOrderRejected(const Order& order) {} 69 | virtual void onOrderReplaced(const Order& order) {} 70 | virtual void onOrderReplaceRejected(const Order& order) {} 71 | // This method is called when an order is cancelled. 72 | virtual void onOrderCancelled(const Order& order) {} 73 | virtual void onOrderCancelRejected(const Order& order) {} 74 | 75 | virtual bool onAlgoOrderSubmitted(AlgoOrder* order) { return false; } 76 | virtual bool onAlgoOrderPartiallyFilled(AlgoOrder* order) { return false; } 77 | // This method is called when an algorithmic order is temporarily failed. 78 | virtual bool onAlgoOrderUpdated(AlgoOrder* order) { return false; } 79 | virtual void onAlgoOrderFilled(const AlgoOrder& order) {} 80 | virtual void onAlgoOrderFailed(const AlgoOrder& order) {} 81 | 82 | virtual void onHistoricalDataRequestAck(const HistoricalDataRequest& request) {} 83 | virtual void onCommand(const char* command) {} 84 | virtual void onTimer(int timerId) {} 85 | virtual void onEnvVariable(const char* name, const char* value) {} 86 | virtual void onPause() {} 87 | virtual void onResume() {} 88 | virtual void onStop() {} 89 | virtual void onDestory() {} 90 | 91 | public: 92 | // Convenient wrapper functions. 93 | int run(const StrategyConfig& config, const char* srvAddr = nullptr, int srvPort = 0); 94 | bool sendCommand(const char* command); 95 | bool setVerbosity(bool onoff); 96 | bool pause(); 97 | bool resume(); 98 | bool stop(); 99 | 100 | protected: 101 | int getId() const; 102 | int getStatus() const; 103 | const char* getName() const; 104 | const char* getMainInstrument() const; 105 | TickSeries* getTickSeries(const char* instrument = ""); 106 | BarSeries* getBarSeries(const char* instrument = "", int resolution = Resolution::MINUTE, int interval = 1); 107 | 108 | // If paper trading is enabled, strategy's onBar() function will be called 109 | // using historical data, thus simulative trading signal will be generated 110 | // and printed, when historical data playback is done, strategy will switch 111 | // to live mode automatically. 112 | void enablePaperTrading(); 113 | void setFastFlowMode(bool onoff); 114 | 115 | bool openLong(const char* instrument = "", double quantity = 1, char* clOrdId = nullptr); 116 | bool closeLong(const char* instrument = "", char* clOrdId = nullptr); 117 | bool openShort(const char* instrument = "", double quantity = 1, char* clOrdId = nullptr); 118 | bool closeShort(const char* instrument = "", char* clOrdId = nullptr); 119 | 120 | bool buy(const char* instrument, double quantity, double price, char* clOrdId = nullptr, int srvId = 0); 121 | bool sell(const char* instrument, double quantity, double price, char* clOrdId = nullptr, int srvId = 0); 122 | bool sellShort(const char* instrument, double quantity, double price, char* clOrdId = nullptr, int srvId = 0); 123 | bool buyToCover(const char* instrument, double quantity, double price, char* clOrdId = nullptr, int srvId = 0); 124 | const AlgoParams& getDefaultAlgoParams() const; 125 | bool algoBuy(const char* instrument, double quantity, double price, const AlgoParams* params = nullptr, char* clOrdId = nullptr, int srvId = 0); 126 | bool algoSell(const char* instrument, double quantity, double price, const AlgoParams* params = nullptr, char* clOrdId = nullptr, int srvId = 0); 127 | bool algoSellShort(const char* instrument, double quantity, double price, const AlgoParams* params = nullptr, char* clOrdId = nullptr, int srvId = 0); 128 | bool algoBuyToCover(const char* instrument, double quantity, double price, const AlgoParams* params = nullptr, char* clOrdId = nullptr, int srvId = 0); 129 | Order createMarketOrder(int action, const char* instrument, double quantity, int srvId = 0); 130 | Order createLimitOrder(int action, const char* instrument, double limitPrice, double quantity, int srvId = 0); 131 | void setDefaultExecSrvId(int id); 132 | int getServiceId(const char* name, int type); 133 | bool subscribe(const char* instrument, int resolution = Resolution::TICK, int interval = 1, int srvId = 0); 134 | bool unsubscribe(const char* instrument, int resolution = Resolution::TICK, int interval = 1, int srvId = 0); 135 | bool submitOrder(Order& order); 136 | bool splitOrder(Order& order, OrderList& ordGroup); 137 | int getOrderStatus(const char* clOrdId); 138 | Order getOrderSnapshot(const char* clOrdId); 139 | int getPendingOrders(OrderList& list, const char* instrument = ""); 140 | int getAccountPendingOrders(OrderList& list, const char* instrument = ""); 141 | bool cancelOrder(const char* clOrdId); 142 | bool cancelOrder(const Order& order); 143 | bool isOrderPending(const char* clOrdId); 144 | long registerTimer(int msFromNow); 145 | void unregisterTimer(int timerId); 146 | void setEnv(const char* name, const char* value); 147 | void unsetEnv(const char* name); 148 | void monitorEnv(const char* name); 149 | unsigned long getSysTickCount(); 150 | bool saveUserParameter(const char* name, const char* value); 151 | // Sync read. 152 | int loadHistoricalData(const char* instrument, int resolution, int interval, int refNum, HistoricalData* buffer, int srvId = 0); 153 | // Async read. 154 | int requestHistoricalData(const char* instrument, int resolution, int interval, int refNum, HistoricalData* buffer, int srvId = 0); 155 | 156 | // Price fetching functions 157 | double getMultiplier(const char* instrument = ""); 158 | double getTickSize(const char* instrument = ""); 159 | double getLastPrice(const char* instrument = ""); 160 | double getAskPrice(const char* instrument = ""); 161 | double getBidPrice(const char* instrument = ""); 162 | 163 | // Position fetching functions 164 | int getAccountPositions(AccountPositionList& list, const char* instrument = "", bool includeClosed = false); 165 | int getStrategyPositions(StrategyPositionList& list, const char* instrument = ""); 166 | double getTotalPosSize(const char* instrument = ""); 167 | 168 | double getLongPosSize(const char* instrument = ""); 169 | void getLongPosSize(double* closable, double* frozen, double* unformed); 170 | void getLongPosSize(const char* instrument, double* closable, double* frozen, double* unformed); 171 | StrategyPosition getLongPos(const char* instrument = ""); 172 | 173 | double getShortPosSize(const char* instrument = ""); 174 | void getShortPosSize(double* closable, double* frozen, double* unformed); 175 | void getShortPosSize(const char* instrument, double* closable, double* frozen, double* unformed); 176 | StrategyPosition getShortPos(const char* instrument = ""); 177 | 178 | double getClosableLongPosSize(const char* instrument = ""); 179 | StrategyPosition getClosableLongPos(const char* instrument = ""); 180 | 181 | double getClosableShortPosSize(const char* instrument = ""); 182 | StrategyPosition getClosableShortPos(const char* instrument = ""); 183 | 184 | double getFrozenLongPosSize(const char* instrument = ""); 185 | double getFrozenShortPosSize(const char* instrument = ""); 186 | 187 | double getUnformedLongPosSize(const char* instrument = ""); 188 | double getUnformedShortPosSize(const char* instrument = ""); 189 | 190 | double getAcctClosableLongPosSize(const char* instrument = "", int srvId = 0); 191 | StrategyPosition getAcctClosableLongPos(const char* instrument = "", int srvId = 0); 192 | 193 | double getAcctClosableShortPosSize(const char* instrument = "", int srvId = 0); 194 | StrategyPosition getAcctClosableShortPos(const char* instrument = "", int srvId = 0); 195 | 196 | double getAcctLongPosSize(const char* instrument = "", int srvId = 0); 197 | double getAcctHistLongPosSize(const char* instrument = "", int srvId = 0); 198 | double getAcctLongPos(const char* instrument, double* price, TimeStamp* ts, int srvId = 0); 199 | StrategyPosition getAcctLongPos(const char* instrument = "", int srvId = 0); 200 | 201 | double getAcctShortPosSize(const char* instrument = "", int srvId = 0); 202 | double getAcctHistShortPosSize(const char* instrument = "", int srvId = 0); 203 | double getAcctShortPos(const char* instrument, double* price, TimeStamp* ts, int srvId = 0); 204 | StrategyPosition getAcctShortPos(const char* instrument = "", int srvId = 0); 205 | 206 | bool assignLongPosition(const char* instrument, double quantity, double price, const TimeStamp& timestamp, 207 | double frozen = 0, double highest = 0, double lowest = 0); 208 | bool assignShortPosition(const char* instrument, double quantity, double price, const TimeStamp& timestamp, 209 | double frozen = 0, double highest = 0, double lowest = 0); 210 | 211 | double getAcctUnrealizedPnL(int srvId = 0) const; 212 | double getAcctRealizedPnL(int srvId = 0) const; 213 | double getInstrumentUnrealizedPnL() const; 214 | double getInstrumentRealizedPnL() const; 215 | 216 | bool setStopLossAmount(const char* instrument, int side, double amount); 217 | bool setStopLossPrice(const char* instrument, int side, double price); 218 | bool setStopLossPercent(const char* instrument, int side, double pct); 219 | bool setStopLossTick(const char* instrument, int side, int tick); 220 | bool setStopProfitAmount(const char* instrument, int side, double amount); 221 | bool setStopProfitPrice(const char* instrument, int side, double price); 222 | bool setStopProfitPct(const char* instrument, int side, double returns); 223 | bool setPercentTrailing(const char* instrument, int side, double amount, double percentage); 224 | bool setTrailingStop(const char* instrument, int side, double returns, double drawdown); 225 | 226 | void writeLogMsg(const char* msg); 227 | bool isVerbose() const; 228 | void writeVerboseMsg(const char* msg); 229 | void writeErrorMsg(const char* msg); 230 | 231 | private: 232 | IRuntime* m_runtime; 233 | }; 234 | 235 | #define EXPORT_STRATEGY(strategy_name) \ 236 | extern "C" STRATEGY_API Strategy* CreateStrategy() \ 237 | { \ 238 | return new strategy_name; \ 239 | } 240 | 241 | //////////////////////////////////////////////////////////////////////////////// 242 | // Strategy Creator Definitions 243 | //////////////////////////////////////////////////////////////////////////////// 244 | extern "C" typedef Strategy *StrategyCreator(); 245 | 246 | // Only lambdas with no capture can be converted to a function pointer. 247 | // This is an extension of lambdas for only this particular case. 248 | // In general, lambdas are function objects, and you cannot convert a 249 | // function object to a function. 250 | // The alternative for lambdas that have state(capture) is to use 251 | // std::function rather than a plain function pointer. 252 | #define STRATEGY_CREATOR(strategy_name) \ 253 | []() -> Strategy* { return new strategy_name; } 254 | 255 | } // namespace AlgoSE 256 | 257 | #endif // ALGOSE_STRATEGY_H -------------------------------------------------------------------------------- /Inc/StrategyConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_STRATEGY_CONFIG_H 2 | #define ALGOSE_STRATEGY_CONFIG_H 3 | 4 | #include "Defines.h" 5 | 6 | namespace AlgoSE 7 | { 8 | 9 | class Strategy; 10 | class StrategyConfigImpl; 11 | 12 | extern "C" typedef Strategy *StrategyCreator(); 13 | 14 | class ALGOSE_API StrategyConfig 15 | { 16 | public: 17 | StrategyConfig(); 18 | StrategyConfig(const StrategyConfig& other); 19 | ~StrategyConfig(); 20 | StrategyConfig &operator=(const StrategyConfig& other); 21 | 22 | void setName(const char* name); 23 | const char* getName() const; 24 | void setDescription(const char* desc); 25 | const char* getDescription() const; 26 | void setAuthor(const char* author); 27 | const char* getAuthor() const; 28 | void setSharedLibrary(const char* library); 29 | const char* getSharedLibrary() const; 30 | void setStrategyCreator(StrategyCreator* creator); 31 | StrategyCreator* getStrategyCreator() const; 32 | 33 | // Subscribe instrument. 34 | void subscribe(const char* instrument, int resolution = Resolution::TICK, int interval = 0, int backRefNum = 0); 35 | void enableAlgoTrader(); 36 | void disableAlgoTrader(); 37 | bool isAlgoTraderEnabled() const; 38 | void enableAutoStart(); 39 | void disableAutoStart(); 40 | bool isAutoStartDisabled() const; 41 | void setAcceptAllOrders(bool onoff); 42 | bool isAcceptAllOrders() const; 43 | void directActOnAcctPos(bool onoff); 44 | bool isDirectActOnAcctPos() const; 45 | bool setPosition(const char* instrument, int side, int quantity, double price, 46 | const TimeStamp& ts, double highest, double lowest); 47 | bool addTradingHour(const char* instrument, const TradingHour& hour); 48 | 49 | StrategyConfig& setUserParameter(const StrategyParam& item); 50 | StrategyConfig& setUserParameter(const char* name, int value); 51 | StrategyConfig& setUserParameter(const char* name, double value); 52 | StrategyConfig& setUserParameter(const char* name, bool value); 53 | StrategyConfig& setUserParameter(const char* name, const char* value); 54 | StrategyConfig& setOptimizeParameter(const char* name, double start, double end, double step); 55 | // template 56 | // StrategyConfig& setUserParameter(T1 name, T2 value) = delete; 57 | StrategyConfig& setAlgoTraderParameter(int id, double value); 58 | StrategyConfig& setAlgoTraderParameter(const char* name, const char* value); 59 | 60 | const StrategyConfigImpl& getImplementor() const; 61 | 62 | private: 63 | StrategyConfigImpl* m_implementor; 64 | }; 65 | 66 | } // namespace AlgoSE 67 | 68 | #endif // ALGOSE_STRATEGY_CONFIG_H -------------------------------------------------------------------------------- /Inc/Technical.h: -------------------------------------------------------------------------------- 1 | #ifndef TECHNICAL_H 2 | #define TECHNICAL_H 3 | 4 | #include "DateTime.h" 5 | #include "DataSeries.h" 6 | 7 | namespace AlgoSE 8 | { 9 | 10 | // An EventWindow class is responsible for making calculation over a moving window of values. 11 | // Note: This is a base class and should not be used directly. 12 | // @param: FilterType: Event window accept this type of data 13 | // @param: ValueType: Event window output this type of data 14 | template 15 | class EventWindow 16 | { 17 | public: 18 | 19 | class Values 20 | { 21 | public: 22 | void setDataBuffer(circular_buffer* buf) 23 | { 24 | m_pDataBuf = buf; 25 | } 26 | 27 | ValueType operator[](int pos) const 28 | { 29 | if (m_pDataBuf != NULL) { 30 | circular_buffer& buf = *m_pDataBuf; 31 | int size = buf.size(); 32 | 33 | if (pos >= size || 34 | (pos < 0 && abs(pos) > size)) { 35 | throw std::out_of_range("circular buffer out of range."); 36 | } 37 | 38 | if (pos >= 0) { 39 | return buf[pos]; 40 | } else { 41 | return buf[size + pos]; 42 | } 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | ValueType mean() const 49 | { 50 | ValueType mean = 0.0; 51 | if (m_pDataBuf != NULL) { 52 | circular_buffer& buf = *m_pDataBuf; 53 | typename circular_buffer::iterator it = buf.begin(); 54 | while (it != buf.end()) { 55 | mean += *it; 56 | it++; 57 | } 58 | mean /= buf.size(); 59 | } 60 | 61 | return mean; 62 | } 63 | 64 | ValueType minimum() const 65 | { 66 | double ret = std::numeric_limits::quiet_NaN(); 67 | if (m_pDataBuf != NULL) { 68 | circular_buffer& buf = *m_pDataBuf; 69 | if (buf.size() == 0) { 70 | return ret; 71 | } 72 | 73 | typename circular_buffer::iterator it = buf.begin(); 74 | ret = *it; 75 | it++; 76 | while (it != buf.end()) { 77 | if (*it < ret) { 78 | ret = *it; 79 | } 80 | it++; 81 | } 82 | } 83 | 84 | return ret; 85 | } 86 | 87 | ValueType maximum() const 88 | { 89 | double ret = std::numeric_limits::quiet_NaN(); 90 | if (m_pDataBuf != NULL) { 91 | circular_buffer& buf = *m_pDataBuf; 92 | if (buf.size() == 0) { 93 | return ret; 94 | } 95 | 96 | typename circular_buffer::iterator it = buf.begin(); 97 | ret = *it; 98 | it++; 99 | while (it != buf.end()) { 100 | if (*it > ret) { 101 | ret = *it; 102 | } 103 | it++; 104 | } 105 | } 106 | 107 | return ret; 108 | } 109 | 110 | std::size_t size() const 111 | { 112 | if (m_pDataBuf != NULL) { 113 | circular_buffer& buf = *m_pDataBuf; 114 | return buf.size(); 115 | } 116 | 117 | return 0; 118 | } 119 | 120 | private: 121 | circular_buffer* m_pDataBuf; 122 | }; 123 | 124 | EventWindow() : m_values(0) { } // It is important to initialize circular_buffer to zero size 125 | // @param: windowSize: The size of the window. Must be greater than 0. 126 | // @param: dtype: The desired data-type for the array. 127 | // @param: skipNone: True if None values should not be included in the window. 128 | void init(int windowSize, int dtype = 0, bool skipNone = true) 129 | { 130 | m_windowSize = windowSize; 131 | m_skipNone = skipNone; 132 | m_values.clear(); 133 | m_values.reserve(windowSize); 134 | 135 | m_outRefValues.setDataBuffer(&m_values); 136 | } 137 | 138 | // Default implementation be used in the scene where FilterType equals to EvtWinType. 139 | virtual void onNewValue(const DateTime& datetime, const FilterType& value) 140 | { 141 | pushNewValue(datetime, (ValueType&)value); 142 | } 143 | 144 | void pushNewValue(const DateTime& datetime, const ValueType& value) 145 | { 146 | if (!m_skipNone) { 147 | } 148 | 149 | m_values.push_back(value); 150 | } 151 | 152 | const Values& getValues() const 153 | { 154 | return m_outRefValues; 155 | } 156 | 157 | // Returns the window size. 158 | int getWindowSize() const 159 | { 160 | return m_windowSize; 161 | } 162 | 163 | // Return True if window is full. 164 | bool windowFull() const 165 | { 166 | return m_values.size() == m_windowSize; 167 | } 168 | 169 | // Override to calculate a value using the values in the window. 170 | virtual ValueType getValue() const = 0; 171 | 172 | void clear() 173 | { 174 | m_values.clear(); 175 | } 176 | 177 | private: 178 | circular_buffer m_values; 179 | int m_windowSize; 180 | bool m_skipNone; 181 | Values m_outRefValues; 182 | }; 183 | 184 | //////////////////////////////////////////////////////////////////////////////// 185 | //////////////////////////////////////////////////////////////////////////////// 186 | 187 | // An EventBasedFilter class is responsible for capturing new values in a DataSeries 188 | // and using an EventWindow to calculate new values. 189 | // @param: FilterType: Filter capturing this type of data stream. 190 | // @param: ValueType: Filter output this type of data item. 191 | template 192 | class EventBasedFilter : public SequenceDataSeries, public IEventHandler 193 | { 194 | public: 195 | EventBasedFilter() {} 196 | // @param: dataSeries: The DataSeries instance being filtered. 197 | // @param: eventWindow: The EventWindow instance to use to calculate new values. 198 | // @param: maxLen: The maximum number of values to hold. 199 | // Once a bounded length is full, when new items are added, a corresponding number of items are discarded from the opposite end. 200 | void init(DataSeries* dataSeries, EventWindow* eventWindow, int maxLen = DataSeries::DEFAULT_MAX_LEN) 201 | { 202 | SequenceDataSeries::setMaxLen(maxLen); 203 | m_dataSeries = dataSeries; 204 | m_eventWindow = eventWindow; 205 | m_dataSeries->getNewValueEvent().subscribe(this); 206 | } 207 | 208 | DataSeries* getDataSeries() const { return m_dataSeries; } 209 | 210 | EventWindow* getEventWindow() const { return m_eventWindow; } 211 | 212 | void reset() 213 | { 214 | m_eventWindow->clear(); 215 | SequenceDataSeries::clear(); 216 | } 217 | 218 | private: 219 | void onEvent(int type, const DateTime& datetime, const void* context) 220 | { 221 | if (type == Event::EvtDataSeriesNewValue) { 222 | Event::Context& ctx = *((Event::Context *)context); 223 | // Let the event window perform calculations. 224 | m_eventWindow->onNewValue(ctx.datetime, *(FilterType *)ctx.data); 225 | // Get the resulting value. 226 | ValueType newValue = m_eventWindow->getValue(); 227 | // Add the new value. 228 | SequenceDataSeries::appendWithDateTime(ctx.datetime, &newValue); 229 | } 230 | } 231 | 232 | DataSeries* m_dataSeries; 233 | EventWindow* m_eventWindow; 234 | }; 235 | 236 | } // namespace AlgoSE 237 | 238 | #endif // TECHNICAL_H -------------------------------------------------------------------------------- /Inc/Utils.h: -------------------------------------------------------------------------------- 1 | #ifndef ALGOSE_UTILS_H 2 | #define ALGOSE_UTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "Defines.h" 8 | 9 | namespace AlgoSE 10 | { 11 | 12 | #ifdef __PLATFORM_WINDOWS__ 13 | 14 | std::wstring s2ws(const std::string& s); 15 | #define getTickCount GetTickCount 16 | #define snprintf _snprintf 17 | #include 18 | #define GetCurrentDir _getcwd 19 | 20 | #define LIBRARY_POINTER_TYPE HMODULE 21 | #define GET_PROC_ADDR GetProcAddress 22 | #define LOAD_LIBRARY(X) LoadLibrary(X) 23 | #define FREE_LIBRARY FreeLibrary 24 | 25 | #else 26 | 27 | #define s2ws(s) (s) 28 | #define stricmp strcasecmp 29 | #define _stricmp strcasecmp 30 | #define strnicmp strncasecmp 31 | #define _snprintf snprintf 32 | #define strncpy_s strncpy 33 | unsigned long getTickCount(); 34 | #define GetCurrentDir getcwd 35 | 36 | #include 37 | #define LIBRARY_POINTER_TYPE void* 38 | #define GET_PROC_ADDR dlsym 39 | #define LOAD_LIBRARY(X) dlopen(X, RTLD_NOW) 40 | #define FREE_LIBRARY dlclose 41 | 42 | #endif 43 | 44 | int _snprintf_s( 45 | char *buffer, 46 | size_t sizeOfBuffer, 47 | size_t count, 48 | const char *format, 49 | ... 50 | ); 51 | 52 | ALGOSE_API char* printInt(int num, char out[]); 53 | 54 | void SetThreadName(std::thread* thread, const char* threadName); 55 | void SetThreadName(const char* threadName); 56 | 57 | class ALGOSE_API hiresclock 58 | { 59 | public: 60 | // Returns the number of 10/th microseconds 61 | // (or 100-nanoseconds intervals if you will) since epoch (UTC). 62 | static std::uint64_t now(); // in 0.1us 63 | static void timestamping(void* addr); 64 | static std::uint64_t getTimeDelta(std::uint64_t start); 65 | }; 66 | 67 | } // namespace AlgoSE 68 | 69 | #endif // ALGOSE_UTILS_H -------------------------------------------------------------------------------- /Inc/circular.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * $Id: $ 3 | * $Name: $ 4 | * 5 | * Author: Pete Goodliffe 6 | * 7 | * ---------------------------------------------------------------------------- 8 | * Copyright 2002 Pete Goodliffe All rights reserved. 9 | * 10 | * ---------------------------------------------------------------------------- 11 | * Purpose: STL-style circular buffer 12 | * 13 | * ---------------------------------------------------------------------------- 14 | * History: See source control system log. 15 | * 16 | *****************************************************************************/ 17 | 18 | #ifndef CIRCULAR_BUFFER_H 19 | #define CIRCULAR_BUFFER_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | /****************************************************************************** 26 | * Iterators 27 | *****************************************************************************/ 28 | 29 | /** 30 | * Iterator type for the circular_buffer class. 31 | * 32 | * This one template class provides all variants of forward/reverse 33 | * const/non const iterators through plentiful template magic. 34 | * 35 | * You don't need to instantiate it directly, use the good public functions 36 | * availble in circular_buffer. 37 | */ 38 | template //+ const for const iter 42 | class circular_buffer_iterator 43 | { 44 | public: 45 | 46 | typedef circular_buffer_iterator self_type; 47 | 48 | typedef T cbuf_type; 49 | typedef std::random_access_iterator_tag iterator_category; 50 | typedef typename cbuf_type::value_type value_type; 51 | typedef typename cbuf_type::size_type size_type; 52 | typedef typename cbuf_type::pointer pointer; 53 | typedef typename cbuf_type::const_pointer const_pointer; 54 | typedef typename cbuf_type::reference reference; 55 | typedef typename cbuf_type::const_reference const_reference; 56 | typedef typename cbuf_type::difference_type difference_type; 57 | 58 | circular_buffer_iterator(cbuf_type *b, size_type p) 59 | : buf_(b), pos_(p) {} 60 | 61 | // Converting a non-const iterator to a const iterator 62 | circular_buffer_iterator 63 | (const circular_buffer_iterator 65 | &other) 66 | : buf_(other.buf_), pos_(other.pos_) {} 67 | friend class circular_buffer_iterator; 68 | 69 | // Use compiler generated copy ctor, copy assignment operator and dtor 70 | 71 | elem_type &operator*() { return (*buf_)[pos_]; } 72 | elem_type *operator->() { return &(operator*()); } 73 | 74 | self_type &operator++() 75 | { 76 | pos_ += 1; 77 | return *this; 78 | } 79 | self_type operator++(int) 80 | { 81 | self_type tmp(*this); 82 | ++(*this); 83 | return tmp; 84 | } 85 | 86 | self_type &operator--() 87 | { 88 | pos_ -= 1; 89 | return *this; 90 | } 91 | self_type operator--(int) 92 | { 93 | self_type tmp(*this); 94 | --(*this); 95 | return tmp; 96 | } 97 | 98 | self_type operator+(difference_type n) const 99 | { 100 | self_type tmp(*this); 101 | tmp.pos_ += n; 102 | return tmp; 103 | } 104 | self_type &operator+=(difference_type n) 105 | { 106 | pos_ += n; 107 | return *this; 108 | } 109 | 110 | self_type operator-(difference_type n) const 111 | { 112 | self_type tmp(*this); 113 | tmp.pos_ -= n; 114 | return tmp; 115 | } 116 | self_type &operator-=(difference_type n) 117 | { 118 | pos_ -= n; 119 | return *this; 120 | } 121 | 122 | difference_type operator-(const self_type &c) const 123 | { 124 | return pos_ - c.pos_; 125 | } 126 | 127 | bool operator==(const self_type &other) const 128 | { 129 | return pos_ == other.pos_ && buf_ == other.buf_; 130 | } 131 | bool operator!=(const self_type &other) const 132 | { 133 | return pos_ != other.pos_ && buf_ == other.buf_; 134 | } 135 | bool operator>(const self_type &other) const 136 | { 137 | return pos_ > other.pos_; 138 | } 139 | bool operator>=(const self_type &other) const 140 | { 141 | return pos_ >= other.pos_; 142 | } 143 | bool operator<(const self_type &other) const 144 | { 145 | return pos_ < other.pos_; 146 | } 147 | bool operator<=(const self_type &other) const 148 | { 149 | return pos_ <= other.pos_; 150 | } 151 | 152 | private: 153 | 154 | cbuf_type *buf_; 155 | size_type pos_; 156 | }; 157 | 158 | template 159 | circular_buffer_iterator_t operator+ 160 | (const typename circular_buffer_iterator_t::difference_type &a, 161 | const circular_buffer_iterator_t &b) 162 | { 163 | return circular_buffer_iterator_t(a) + b; 164 | } 165 | 166 | template 167 | circular_buffer_iterator_t operator- 168 | (const typename circular_buffer_iterator_t::difference_type &a, 169 | const circular_buffer_iterator_t &b) 170 | { 171 | return circular_buffer_iterator_t(a) - b; 172 | } 173 | 174 | 175 | /****************************************************************************** 176 | * circular_buffer 177 | *****************************************************************************/ 178 | 179 | /** 180 | * This class provides a circular buffer in the STL style. 181 | * 182 | * You can add data to the end using the @ref push_back function, read data 183 | * using @ref front() and remove data using @ref pop_front(). 184 | * 185 | * The class also provides random access through the @ref operator[]() 186 | * function and its random access iterator. Subscripting the array with 187 | * an invalid (out of range) index number leads to undefined results, both 188 | * for reading and writing. 189 | * 190 | * This class template accepts three template parameters: 191 | *
  • T The type of object contained 192 | *
  • always_accept_data_when_full Determines the behaviour of 193 | * @ref push_back when the buffer is full. 194 | * Set to true new data is always added, the 195 | * old "end" data is thrown away. 196 | * Set to false, the new data is not added. 197 | * No error is returned neither is an 198 | * exception raised. 199 | *
  • Alloc Allocator type to use (in line with other 200 | * STL containers). 201 | * 202 | * @short STL style circule buffer 203 | * @author Pete Goodliffe 204 | * @version 1.00 205 | */ 206 | template > 209 | class circular_buffer 210 | { 211 | public: 212 | 213 | enum 214 | { 215 | version_major = 1, 216 | version_minor = 0 217 | }; 218 | 219 | // Typedefs 220 | typedef circular_buffer 221 | self_type; 222 | 223 | typedef Alloc allocator_type; 224 | 225 | typedef typename Alloc::value_type value_type; 226 | typedef typename Alloc::pointer pointer; 227 | typedef typename Alloc::const_pointer const_pointer; 228 | typedef typename Alloc::reference reference; 229 | typedef typename Alloc::const_reference const_reference; 230 | 231 | typedef typename Alloc::size_type size_type; 232 | typedef typename Alloc::difference_type difference_type; 233 | 234 | typedef circular_buffer_iterator 235 | 236 | iterator; 237 | typedef circular_buffer_iterator 238 | 239 | const_iterator; 240 | typedef std::reverse_iterator reverse_iterator; 241 | typedef std::reverse_iterator const_reverse_iterator; 242 | 243 | // Lifetime 244 | enum { default_capacity = 100 }; 245 | explicit circular_buffer(size_type capacity = default_capacity) 246 | : array_(alloc_.allocate(capacity)), array_size_(capacity), 247 | head_(1), tail_(0), contents_size_(0) 248 | { 249 | } 250 | circular_buffer(const circular_buffer &other) 251 | : array_(alloc_.allocate(other.array_size_)), 252 | array_size_(other.array_size_), 253 | head_(other.head_), tail_(other.tail_), 254 | contents_size_(other.contents_size_) 255 | { 256 | try 257 | { 258 | assign_into(other.begin(), other.end()); 259 | } 260 | catch (...) 261 | { 262 | destroy_all_elements(); 263 | alloc_.deallocate(array_, array_size_); 264 | throw; 265 | } 266 | } 267 | template 268 | circular_buffer(InputIterator from, InputIterator to) 269 | : array_(alloc_.allocate(1)), array_size_(1), 270 | head_(1), tail_(0), contents_size_(0) 271 | { 272 | circular_buffer tmp; 273 | tmp.assign_into_reserving(from, to); 274 | swap(tmp); 275 | } 276 | ~circular_buffer() 277 | { 278 | destroy_all_elements(); 279 | alloc_.deallocate(array_, array_size_); 280 | } 281 | circular_buffer &operator=(const self_type &other) 282 | { 283 | circular_buffer tmp(other); 284 | swap(tmp); 285 | return *this; 286 | } 287 | void swap(circular_buffer &other) 288 | { 289 | std::swap(array_, other.array_); 290 | std::swap(array_size_, other.array_size_); 291 | std::swap(head_, other.head_); 292 | std::swap(tail_, other.tail_); 293 | std::swap(contents_size_, other.contents_size_); 294 | } 295 | allocator_type get_allocator() const { return alloc_; } 296 | 297 | // Iterators 298 | iterator begin() { return iterator(this, 0); } 299 | iterator end() { return iterator(this, size()); } 300 | 301 | const_iterator begin() const { return const_iterator(this, 0); } 302 | const_iterator end() const { return const_iterator(this, size()); } 303 | 304 | reverse_iterator rbegin() { return reverse_iterator(end()); } 305 | reverse_iterator rend() { return reverse_iterator(begin()); } 306 | 307 | const_reverse_iterator rbegin() const 308 | { 309 | return const_reverse_iterator(end()); 310 | } 311 | const_reverse_iterator rend() const 312 | { 313 | return const_reverse_iterator(begin()); 314 | } 315 | 316 | // Size 317 | size_type size() const { return contents_size_; } 318 | size_type capacity() const { return array_size_; } 319 | bool empty() const { return !contents_size_; } 320 | size_type max_size() const 321 | { 322 | return alloc_.max_size(); 323 | } 324 | void reserve(size_type new_size) 325 | { 326 | if (capacity() < new_size) 327 | { 328 | circular_buffer tmp(new_size); 329 | tmp.assign_into(begin(), end()); 330 | swap(tmp); 331 | } 332 | } 333 | 334 | // Accessing 335 | reference front() {return array_[head_];} 336 | reference back() {return array_[tail_];} 337 | const_reference front() const {return array_[head_];} 338 | const_reference back() const {return array_[tail_];} 339 | 340 | void push_back(const value_type &item) 341 | { 342 | size_type next = next_tail(); 343 | if (contents_size_ == array_size_) 344 | { 345 | if (always_accept_data_when_full) 346 | { 347 | array_[next] = item; 348 | increment_head(); 349 | } 350 | } 351 | else 352 | { 353 | alloc_.construct(array_ + next, item); 354 | } 355 | increment_tail(); 356 | } 357 | void pop_front() 358 | { 359 | size_type destroy_pos = head_; 360 | increment_head(); 361 | alloc_.destroy(array_ + destroy_pos); 362 | } 363 | void clear() 364 | { 365 | for (size_type n = 0; n < contents_size_; ++n) 366 | { 367 | alloc_.destroy(array_ + index_to_subscript(n)); 368 | } 369 | head_ = 1; 370 | tail_ = contents_size_ = 0; 371 | } 372 | 373 | reference operator[](size_type n) {return at_unchecked(n);} 374 | const_reference operator[](size_type n) const {return at_unchecked(n);} 375 | 376 | reference at(size_type n) {return at_checked(n);} 377 | const_reference at(size_type n) const {return at_checked(n);} 378 | 379 | private: 380 | 381 | reference at_unchecked(size_type index) const 382 | { 383 | return array_[index_to_subscript(index)]; 384 | } 385 | 386 | reference at_checked(size_type index) const 387 | { 388 | if (size >= contents_size_) 389 | { 390 | throw std::out_of_range(); 391 | } 392 | return at_unchecked(index); 393 | } 394 | 395 | // Rounds an unbounded to an index into array_ 396 | size_type normalise(size_type n) const { return n % array_size_; } 397 | 398 | // Converts external index to an array subscript 399 | size_type index_to_subscript(size_type index) const 400 | { 401 | return normalise(index + head_); 402 | } 403 | 404 | void increment_tail() 405 | { 406 | ++contents_size_; 407 | tail_ = next_tail(); 408 | } 409 | 410 | size_type next_tail() 411 | { 412 | return (tail_+1 == array_size_) ? 0 : tail_+1; 413 | } 414 | 415 | void increment_head() 416 | { 417 | // precondition: !empty() 418 | ++head_; 419 | --contents_size_; 420 | if (head_ == array_size_) head_ = 0; 421 | } 422 | 423 | template 424 | void assign_into(f_iter from, f_iter to) 425 | { 426 | if (contents_size_) clear(); 427 | while (from != to) 428 | { 429 | push_back(*from); 430 | ++from; 431 | } 432 | } 433 | 434 | template 435 | void assign_into_reserving(f_iter from, f_iter to) 436 | { 437 | if (contents_size_) clear(); 438 | while (from != to) 439 | { 440 | if (contents_size_ == array_size_) 441 | { 442 | reserve(static_cast(array_size_ * 1.5)); 443 | } 444 | push_back(*from); 445 | ++from; 446 | } 447 | } 448 | 449 | void destroy_all_elements() 450 | { 451 | for (size_type n = 0; n < contents_size_; ++n) 452 | { 453 | alloc_.destroy(array_ + index_to_subscript(n)); 454 | } 455 | } 456 | 457 | allocator_type alloc_; 458 | value_type *array_; 459 | size_type array_size_; 460 | size_type head_; 461 | size_type tail_; 462 | size_type contents_size_; 463 | }; 464 | 465 | template 468 | bool operator==(const circular_buffer &a, 469 | const circular_buffer &b) 470 | { 471 | return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin()); 472 | } 473 | 474 | template 477 | bool operator!=(const circular_buffer &a, 478 | const circular_buffer &b) 479 | { 480 | return a.size() != b.size() || !std::equal(a.begin(), a.end(), b.begin()); 481 | } 482 | 483 | template 486 | bool operator<(const circular_buffer &a, 487 | const circular_buffer &b) 488 | { 489 | return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); 490 | } 491 | 492 | #endif 493 | -------------------------------------------------------------------------------- /Lib/AlgoSE.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algosenses/AlgoSE-SDK-Cpp/cda4639c2eea660a0603f63b00edca525dddcbef/Lib/AlgoSE.lib -------------------------------------------------------------------------------- /Lib/x64/AlgoSE.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/algosenses/AlgoSE-SDK-Cpp/cda4639c2eea660a0603f63b00edca525dddcbef/Lib/x64/AlgoSE.lib -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AlgoSE-SDK-Cpp: AlgoSE算法策略引擎C++ SDK 2 | 3 | ## 说明 4 | AlgoSE高性能算法策略引擎原生SDK,文档暂未上传。 --------------------------------------------------------------------------------