C++

範例

spdOrderAPI 使用範例 (testSpdOrderAPI)

testSpdOrderAPI.h
#pragma once

#include "spdOrderAPI.h"

class testSpdOrderAPI : public spdOrderAPI
{
private:
    bool isLogon{ false };
    bool exit{ false };
protected:
    void OnSpeedyConnected() override;
    void OnSpeedyDisconnected() override;
    void OnSpeedyLogonResponse(bool isLoginOK, const char* ReplyMsg) override;
    void OnNewOrderReport(long long nid, const char* UDD, const char* Symbol, double Price, const char* Side, long OrderQty, const char* OrderType, const char* TimeinForce, const char* OrderID) override;
    void OnCancelOrderReport(long long nid, const char* UDD, const char* Symbol, double Price, const char* Side, const char* OrderID) override;
    void OnReplaceOrderReport(long long nid, const char* UDD, const char* Symbol, double Price, const char* Side, long OrderQty, const char* OrderType, const char* TimeinForce, const char* OrderID) override;
    void OnOrderRejectedReport(long long nid, const char* UDD, const char* ActionFrom, const char* ErrCode, const char* ErrMsg) override;
    void OnOrderMatchReport(long long nid, const char* UDD, const char* OrderID, long ReportSeq, double MatchPrice, long MatchQty, const char* MatchTime) override;

private:
    void cmdNewOrder();
    void cmdCancelOrder();
    void cmdNewForeignOrder();
    void cmdCancelForeignOrder();
    void cmdReplaceOrder();
    void cmdMakeStockAccountInquriy();
    void cmdQueryStkOrder();
    void cmdQueryStkMatch();
    void cmdQueryFutOrder();
    void cmdQueryFutMatch();
    void cmdQueryFutUncoverRT();
    void cmdQueryFutMargin();
    void cmdChangePassword();
    void cmdQueryForeignStockInventory();
    void cmdQueryForeignStockOrder();
    void cmdQueryForeignStockFilled();
    void cmdDownloadForeignStockProductData();
    void cmdDownloadForeignStockCurrencyData();
    void cmdDownloadForeignStockMarketData();

public:
    void MainLoop();
};
testSpdOrderAPI.cpp
#include <iostream>
  #include <thread>
  #include <chrono>
  
  #include "testSpdOrderAPI.h"
  
  void testSpdOrderAPI::OnSpeedyConnected()
  {
      std::cout << "----------OnSpeedyConnected--------------" << std::endl;  
       /*
          登入證券
          LogonSpeedy('身分證字號(大寫字母)', '電子登入密碼', '證券帳號七位數如:[0023456]')
  
          登入期貨
          LogonSpeedy('身分證字號(大寫字母)', '電子登入密碼', '期貨帳號七位數如:[0123457]')
  
          登入多市場逗號分隔
          LogonSpeedy('身分證字號(大寫字母)', '電子登入密碼', '證券帳號七位數如:[0023456],期貨帳號七位數如:[0123457]')
          */
      if (!LogonSpeedy("Z323456789", "1234", "0023456"))
      {
          std::string msg = GetOrderAPILastErrorMessage();
          std::cout << msg << std::endl;
      }
  }
  
  void testSpdOrderAPI::OnSpeedyDisconnected()
  {
      std::cout << "----------OnSpeedyDisConnected-----------" << std::endl;
      exit = true;
  }
  
  void testSpdOrderAPI::OnSpeedyLogonResponse(bool isLoginOK,
                                              const char* ReplyMsg)
  {
      std::cout << "----------OnSpeedyLogonResponse----------" << std::endl;
      std::cout << "[isLoginOK]:" << isLoginOK << std::endl;
      std::cout << "[ReplyMsg]: " << ReplyMsg << std::endl;
      std::cout << std::endl;
  
      if (isLoginOK)
      {
          //期貨設定下單帳號
          // SetAccount( 'TAIFEX', 'F030000', '期貨帳號七位數')
          SetAccount("TAIFEX", "F030000", "0123457");
          //證券設定下單帳號
          //SetAccount( 'TWSE', '分公司別四位數', '證券帳號七位數')
          SetAccount("TWSE", "7000", "0023456");
          //海外證券設定下單帳號
          //SetAccount( 'US', '分公司別四位數', '證券帳號六位數')
          SetAccount("US", "7000", "002345");
          isLogon = true;
      }
  }
  
  void testSpdOrderAPI::OnNewOrderReport(long long nid,
                                         const char* UDD,
                                         const char* Symbol,
                                         double Price,
                                         const char* Side,
                                         long OrderQty,
                                         const char* OrderType,
                                         const char* TimeInForce,
                                         const char* OrderID)
  {
      std::cout << "----------OnNewOrderReport---------------" << std::endl;
      std::cout << "[NID]:        " << nid << std::endl;
      std::cout << "[UDD]:        " << UDD << std::endl;
      std::cout << "[Symbol]:     " << Symbol << std::endl;
      std::cout << "[Price]:      " << Price << std::endl;
      std::cout << "[Side]:       " << Side << std::endl;
      std::cout << "[OrderQty]:   " << OrderQty << std::endl;
      std::cout << "[OrderType]:  " << OrderType << std::endl;
      std::cout << "[TimeInForce]:" << TimeInForce << std::endl;
      std::cout << "[OrderID]:    " << OrderID << std::endl;
      std::cout << std::endl;
  
  }
  
  void testSpdOrderAPI::OnCancelOrderReport(long long nid,
                                            const char* UDD,
                                            const char* Symbol,
                                            double Price,
                                            const char* Side,
                                            const char* OrderID)
  {
      std::cout << "----------OnCancelOrderReport------------" << std::endl;
      std::cout << "[NID]:        " << nid << std::endl;
      std::cout << "[UDD]:        " << UDD << std::endl;
      std::cout << "[Symbol]:     " << Symbol << std::endl;
      std::cout << "[Price]:      " << Price << std::endl;
      std::cout << "[Side]:       " << Side << std::endl;
      std::cout << "[OrderID]:    " << OrderID << std::endl;
      std::cout << std::endl;
  }
  
  void testSpdOrderAPI::OnReplaceOrderReport(long long nid,
                                             const char* UDD,
                                             const char* Symbol,
                                             double Price,
                                             const char* Side,
                                             long OrderQty,
                                             const char* OrderType,
                                             const char* TimeInForce,
                                             const char* OrderID)
  {
      std::cout << "----------OnReplaceOrderReport-----------" << std::endl;
      std::cout << "[NID]:        " << nid << std::endl;
      std::cout << "[UDD]:        " << UDD << std::endl;
      std::cout << "[Symbol]:     " << Symbol << std::endl;
      std::cout << "[Price]:      " << Price << std::endl;
      std::cout << "[Side]:       " << Side << std::endl;
      std::cout << "[OrderQty]:   " << OrderQty << std::endl;
      std::cout << "[OrderType]:  " << OrderType << std::endl;
      std::cout << "[TimeInForce]:" << TimeInForce << std::endl;
      std::cout << "[OrderID]:    " << OrderID << std::endl;
      std::cout << std::endl;
  }
  
  void testSpdOrderAPI::OnOrderRejectedReport(long long nid,
                                              const char* UDD,
                                              const char* ActionFrom,
                                              const char* ErrCode,
                                              const char* ErrMsg)
  {
      std::cout << "----------OnOrderRejectedReport----------" << std::endl;
      std::cout << "[NID]:        " << nid << std::endl;
      std::cout << "[UDD]:        " << UDD << std::endl;
      std::cout << "[ActionFrom]: " << ActionFrom << std::endl;
      std::cout << "[ErrCode]:    " << ErrCode << std::endl;
      std::cout << "[ErrMsg]:     " << ErrMsg << std::endl;
      std::cout << std::endl;
  }
  
  void testSpdOrderAPI::OnOrderMatchReport(long long nid,
                                           const char* UDD,
                                           const char* OrderID,
                                           long ReportSeq,
                                           double MatchPrice,
                                           long MatchQty,
                                           const char* MatchTime)
  {
      std::cout << "----------OnOrderMatchReport-------------" << std::endl;
      std::cout << "[NID]:       " << nid << std::endl;
      std::cout << "[UDD]:       " << UDD << std::endl;
      std::cout << "[OrderID]:   " << OrderID << std::endl;
      std::cout << "[ReportSeq]: " << ReportSeq << std::endl;
      std::cout << "[MatchPrice]:" << MatchPrice << std::endl;
      std::cout << "[MatchQty]:  " << MatchQty << std::endl;
      std::cout << "[MatchTime]: " << MatchTime << std::endl;
      std::cout << std::endl;
  }
  
  static std::string ReadLine()
  {
      std::string input;
      std::getline(std::cin, input);
  
      if (!input.empty() && input.back() == '\r')
          input.pop_back();
      return input;
  }
  
  void testSpdOrderAPI::cmdNewOrder()
  {
      std::cout << "[Market] (fut:futures opt:options tse:stock otc:otc_stock) ->";
      std::string Market = ReadLine();
      std::cout << "[UDD] ->";
      std::string UDD = ReadLine();
      std::cout << "[Symbol] ->";
      std::string Symbol = ReadLine();
      std::cout << "[Price] ->";
      std::string s_Price = ReadLine();
      std::cout << "[Quantity] ->";
      std::string s_Qty = ReadLine();
      std::cout << "[Side] (B:Buy S:Sell) ->";
      std::string Side = ReadLine();
      std::cout << "[OrderType] (L:Limit Price M:Market Price P:Market with protection) ->";
      std::string OrderType = ReadLine();
      std::cout << "[TimeInForce] (R:ROD I:IOC F:FOK) ->";
      std::string Tif = ReadLine();
      std::cout << "[TradingSession] ->";
      std::string TS = ReadLine();
      std::cout << "[PositionEffect] ->";
      std::string PE = ReadLine();
      std::cout << "[TWEOrdTyp] ->";
      std::string TO = ReadLine();
  
      double price = 0;
      int qty = 0;
      try
      {
          price = std::stod(s_Price);
          qty = std::stoi(s_Qty);
      }
      catch (...)
      {
          std::cout << "input error!" << std::endl;
      }
  
      auto rt = SendNewOrder(Market.c_str(),
                             UDD.c_str(),
                             Symbol.c_str(),
                             price,
                             Side.c_str(),
                             qty,
                             OrderType.c_str(),
                             Tif.c_str(),
                             TS.c_str(),
                             PE.c_str(),
                             TO.c_str());
      if (!rt)
      {
          auto msg = GetOrderAPILastErrorMessage();
          std::cout << "SendNewOrder fail! " << msg << std::endl;
      }
  }
  
  void testSpdOrderAPI::cmdNewForeignOrder()
  {
      std::cout << "[Exchange] ->";
      std::string Exchange = ReadLine();
      std::cout << "[UDD] ->";
      std::string UDD = ReadLine();
      std::cout << "[Symbol] ->";
      std::string Symbol = ReadLine();
      std::cout << "[Price] ->";
      std::string s_Price = ReadLine();
      std::cout << "[StopPrice] ->";
      std::string s_StopPrice = ReadLine();
      std::cout << "[Quantity] ->";
      std::string s_Qty = ReadLine();
      std::cout << "[Side] (B:Buy S:Sell) ->";
      std::string Side = ReadLine();
      std::cout << "[OrderType] " << std::endl;
      std::cout << "    L: 限價" << std::endl;
      std::cout << "    M: 市價" << std::endl;
      std::cout << "   SL: 停損限價" << std::endl;
      std::cout << "   OL: 開盤LMT" << std::endl;
      std::cout << "   CL: 收盤LMT" << std::endl;
      std::cout << "   OM: 開盤MKT" << std::endl;
      std::cout << "   CM: 收盤MKT" << std::endl;
      std::cout << "   VL: VWAP LMT" << std::endl;
      std::cout << "   TL: TWAP LMT" << std::endl;
      std::cout << "   VM: VWAP MKT" << std::endl;
      std::cout << "   TM: TWAP MKT" << std::endl;
      std::cout << "->";
      std::string OrderType = ReadLine();
      std::cout << "[TimeInForce] (R:ROD I:IOC F:FOK) ->";
      std::string Tif = ReadLine();
      std::cout << "[Currency] (1:TWD 2:NON-TWD) ->";
      std::string Currency = ReadLine();
      std::cout << "[ExecInst] (G: AON) ->";
      std::string ExecInst = ReadLine();
  
      double price = 0;
      double stop_price = 0;
      int qty = 0;
      try
      {
          price = std::stod(s_Price);
          stop_price = std::stod(s_StopPrice);
          qty = std::stoi(s_Qty);
      }
      catch (...)
      {
          std::cout << "input error!" << std::endl;
      }   
  
      auto rt = SendNewForeignOrder(Exchange.c_str(),
                                    UDD.c_str(),
                                    Symbol.c_str(),
                                    price,
                                    stop_price,
                                    Side.c_str(),
                                    qty,
                                    OrderType.c_str(),
                                    Tif.c_str(),
                                    Currency.c_str(),
                                    ExecInst.c_str());
      if (!rt)
      {
          auto msg = GetOrderAPILastErrorMessage();
          std::cout << "SendNewForeignOrder fail! " << msg << std::endl;
      }
  }
  
  void testSpdOrderAPI::cmdCancelOrder()
  {
      std::cout << "[Market] (fut:futures opt:options tse:stock otc:otc_stock) ->";
      std::string Market = ReadLine();
      std::cout << "[UDD] ->";
      std::string UDD = ReadLine();
      std::cout << "[Symbol] ->";
      std::string Symbol = ReadLine();
      std::cout << "[Price] ->";
      std::string s_Price = ReadLine();
      std::cout << "[Side] (B:Buy S:Sell) ->";
      std::string Side = ReadLine();
      std::cout << "[OrderID] ->";
      std::string OrderID = ReadLine();
      std::cout << "[TradingSession] ->";
      std::string TS = ReadLine();
      std::cout << "[TWEOrdTyp] ->";
      std::string TO = ReadLine();
  
      double price = 0;
      try
      {
          price = std::stod(s_Price);     
      }
      catch (...)
      {
          std::cout << "input error!" << std::endl;
      }
  
      auto rt = SendCancelOrder(Market.c_str(),
                                UDD.c_str(),
                                Symbol.c_str(),
                                price,
                                Side.c_str(),
                                OrderID.c_str(),
                                TS.c_str(),
                                TO.c_str());
      if (!rt)
      {
          auto msg = GetOrderAPILastErrorMessage();
          std::cout << "SendCancelOrder fail! " << msg << std::endl;
      }
  }
  
  void testSpdOrderAPI::cmdCancelForeignOrder()
  {
      std::cout << "[Exchange] ->";
      std::string Exchange = ReadLine();
      std::cout << "[UDD] ->";
      std::string UDD = ReadLine();
      std::cout << "[Symbol] ->";
      std::string Symbol = ReadLine();
      std::cout << "[Side] (B:Buy S:Sell) ->";
      std::string Side = ReadLine();
      std::cout << "[OrderID] ->";
      std::string OrderID = ReadLine();
  
      auto rt = SendCancelForeignOrder(Exchange.c_str(),
                                       UDD.c_str(),
                                       Symbol.c_str(),
                                       Side.c_str(),
                                       OrderID.c_str());
      if (!rt)
      {
          auto msg = GetOrderAPILastErrorMessage();
          std::cout << "SendCancelForeignOrder fail! " << msg << std::endl;
      }
  }
  
  void testSpdOrderAPI::cmdReplaceOrder()
  {
      std::cout << "[Market] (fut:futures opt:options tse:stock otc:otc_stock) ->";
      std::string Market = ReadLine();
      std::cout << "[UDD] ->";
      std::string UDD = ReadLine();
      std::cout << "[Symbol] ->";
      std::string Symbol = ReadLine();
      std::cout << "[OrderID] ->";
      std::string OrderID = ReadLine();
      std::cout << "[Side] (B:Buy S:Sell) ->";
      std::string Side = ReadLine();
      std::cout << "[Price] ->";
      std::string s_Price = ReadLine();
      std::cout << "[Quantity] ->";
      std::string s_Qty = ReadLine();
      std::cout << "[OrderType] (L:Limit Price M:Market Price P:Market with protection) ->";
      std::string OrderType = ReadLine();
      std::cout << "[TimeInForce] (R:ROD I:IOC F:FOK) ->";
      std::string Tif = ReadLine();
      std::cout << "[TradingSession] ->";
      std::string TS = ReadLine();
      std::cout << "[TWEOrdTyp] ->";
      std::string TO = ReadLine();
  
      double price = 0;
      int qty = 0;
      try
      {
          price = std::stod(s_Price);
          qty = std::stoi(s_Qty);
      }
      catch (...)
      {
          std::cout << "input error!" << std::endl;
      }
  
      auto rt = SendReplaceOrder(Market.c_str(),
                                 UDD.c_str(),
                                 Symbol.c_str(),
                                 OrderID.c_str(),
                                 Side.c_str(),
                                 price,       
                                 qty,
                                 OrderType.c_str(),
                                 Tif.c_str(),
                                 TS.c_str(),
                                 TO.c_str());
      if (!rt)
      {
          auto msg = GetOrderAPILastErrorMessage();
          std::cout << "SendReplaceOrder fail! " << msg << std::endl;
      }
  }
  
  void testSpdOrderAPI::cmdMakeStockAccountInquriy()
  {
      std::cout << "[branch_id] ->";
      std::string branch_id = ReadLine();
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
      std::map<std::string, std::string> query_param
      {
          {"branch_id", branch_id },
          { "cust_id", cust_id }
      };
  
      std::string s_json = MakeStockAccountInquriy(query_param);
      std::cout << s_json << std::endl;   
  }
  
  void testSpdOrderAPI::cmdQueryStkOrder()
  {
      std::cout << "[branch_id] ->";
      std::string branch_id = ReadLine();
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
      std::cout << "[apcode] ->";
      std::string apcode = ReadLine();
      std::cout << "[market] ->";
      std::string market = ReadLine();
      std::cout << "[qry_type] ->";
      std::string qry_type = ReadLine();
      std::map<std::string, std::string> query_param
      {
          {"branch_id", branch_id },
          { "cust_id", cust_id },
          { "apcode", apcode },
          { "market",market },
          { "qry_type",qry_type }
      };
  
      std::string s_json = QueryStkOrder(query_param);
      std::cout << s_json << std::endl;   
  }
  
  void testSpdOrderAPI::cmdQueryStkMatch()
  {
      std::cout << "[branch_id] ->";
      std::string branch_id = ReadLine();
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
      std::cout << "[qry_type] ->";
      std::string qry_type = ReadLine();
      std::map<std::string, std::string> query_param
      {
          {"branch_id", branch_id },
          { "cust_id", cust_id },
          { "qry_type", qry_type }
      };
  
      std::string s_json = QueryStkMatch(query_param);
      std::cout << s_json << std::endl;   
  }
  
  void testSpdOrderAPI::cmdQueryFutOrder()
  {
      std::cout << "[branch_id] ->";
      std::string branch_id = ReadLine();
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
      std::cout << "[type] ->";
      std::string type = ReadLine();
      std::cout << "[apcode] ->";
      std::string apcode = ReadLine();
      std::map<std::string, std::string> query_param
      {
          {"branch_id", branch_id },
          { "cust_id", cust_id },
          { "type", type },
          { "apcode", apcode }
      };
  
      std::string s_json = QueryFutOrder(query_param);
      std::cout << s_json << std::endl;
  
  }
  
  void testSpdOrderAPI::cmdQueryFutMatch()
  {
      std::cout << "[branch_id] ->";
      std::string branch_id = ReadLine();
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
      std::map<std::string, std::string> query_param
      {
          {"branch_id", branch_id },
          { "cust_id", cust_id }
      };
  
      std::string s_json = QueryFutMatch(query_param);
      std::cout << s_json << std::endl;   
  }
  
  void testSpdOrderAPI::cmdQueryFutUncoverRT()
  {
      std::cout << "[branch_id] ->";
      std::string branch_id = ReadLine();
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
      std::map<std::string, std::string> query_param
      {
          {"branch_id", branch_id },
          { "cust_id", cust_id }
      };
  
      std::string s_json = QueryFutUncoverRT(query_param);
      std::cout << s_json << std::endl;   
  }
  
  void testSpdOrderAPI::cmdQueryFutMargin()
  {
      std::cout << "[branch_id] ->";
      std::string branch_id = ReadLine();
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
      std::cout << "[type] ->";
      std::string type = ReadLine();
  
      std::map<std::string, std::string> query_param
      {
          {"branch_id", branch_id },
          { "cust_id", cust_id },
          { "type", type }
      };
  
      std::string s_json = QueryMargin(query_param);
      std::cout << s_json << std::endl;   
  }
  
  void testSpdOrderAPI::cmdChangePassword()
  {
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
      std::cout << "[func] ->";
      std::string func = ReadLine();
  
      std::map<std::string, std::string> query_param
      {
          {"cust_id", cust_id },
          { "func", func }
      };
  
      std::cout << "[oldpwd] ->";
      std::string oldpwd = ReadLine();
      std::cout << "[newpwd] ->";
      std::string newpwd = ReadLine();
  
      query_param.insert(std::pair<std::string, std::string>("oldpwd", oldpwd));
      query_param.insert(std::pair<std::string, std::string>("newpwd", newpwd));
  
      std::string s_json = ChangePassword(query_param);
      std::cout << s_json << std::endl;   
  }
  
  void testSpdOrderAPI::cmdQueryForeignStockInventory()
  {
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
  
      std::map<std::string, std::string> query_param
      {
          { "cust_id", cust_id }      
      };
  
      std::string s_json = QueryForeignStockInventory(query_param);
      std::cout << s_json << std::endl;
  }
  
  void testSpdOrderAPI::cmdQueryForeignStockOrder()
  {
      std::cout << "[branch_id] ->";
      std::string branch_id = ReadLine();
      std::cout << "[cust_id] ->";
      std::string cust_id = ReadLine();
      std::cout << "[qry_kind] " << std::endl;
      std::cout << "0: all" << std::endl;
      std::cout << "1: pending new" << std::endl;
      std::cout << "2: new" << std::endl;
      std::cout << "3: filled" << std::endl;
      std::cout << "4: partial filled" << std::endl;
      std::cout << "5: canceled" << std::endl;
      std::cout << "6: pending cancel" << std::endl;
      std::cout << "7: pre-order" << std::endl;
      std::cout << "8: rejected" << std::endl;
      std::cout << " ->";
      std::string qry_kind = ReadLine();
  
      std::map<std::string, std::string> query_param
      {
          { "branch_id", branch_id },
          { "cust_id", cust_id },
          { "qry_kind", qry_kind }
      };
  
      std::string s_json = QueryForeignStockOrder(query_param);
      std::cout << s_json << std::endl;
  }
  
  void testSpdOrderAPI::cmdQueryForeignStockFilled()
  {
      std::cout << "[branch_id] -> ";
      std::string branch_id = ReadLine();
      std::cout << "[cust_id] -> ";
      std::string cust_id = ReadLine();
  
      std::map<std::string, std::string> query_param
      {
          { "branch_id", branch_id },
          { "cust_id", cust_id }
      };
  
      std::string s_json = QueryForeignStockFilled(query_param);
      std::cout << s_json << std::endl;
  }
  
  void testSpdOrderAPI::cmdDownloadForeignStockProductData()
  {
      std::cout << "[cust_id] -> ";
      std::string cust_id = ReadLine();
      std::cout << "[keyword] (stkno or ename) -> ";
      std::string keyword = ReadLine();
      std::cout << "[gzip file name] -> ";
      std::string gzfname_prefix = ReadLine();
  
      std::map<std::string, std::string> query_param
      {
          { "cust_id", cust_id },
          { "keyword", keyword }
      };
  
      std::string s_json = DownloadForeignStockProductData(query_param, gzfname_prefix.c_str());
      std::cout << s_json << std::endl;   
  }
  
  void testSpdOrderAPI::cmdDownloadForeignStockCurrencyData()
  {
      std::cout << "[cust_id] -> ";
      std::string cust_id = ReadLine();
  
      std::map<std::string, std::string> query_param
      {
          { "cust_id", cust_id }
      };
  
      std::string s_json = DownloadForeignStockCurrencyData(query_param);
      std::cout << s_json << std::endl;
  }
  
  void testSpdOrderAPI::cmdDownloadForeignStockMarketData()
  {
      std::cout << "[cust_id] -> ";
      std::string cust_id = ReadLine();
  
      std::map<std::string, std::string> query_param
      {
          { "cust_id", cust_id }
      };
  
      std::string s_json = DownloadForeignStockMarketData(query_param);
      std::cout << s_json << std::endl;
  }
  
  void testSpdOrderAPI::MainLoop()
  {
      //EnableMEGACA("憑證檔路徑","身分證字號(大寫字母)","憑證密碼")
      if (!EnableMegaCA("Z323456789.pfx","Z323456789", "Z323456789"))
      {
          std::string msg = GetOrderAPILastErrorMessage();
          std::cout << msg << std::endl;
          return;
      }
  
      std::cout << "certificate is ready" << std::endl;
  
      //ConnectSpeedy('主機位置', 56789, 設定連線逾時[秒,如設定5為5秒])
      ConnectSpeedy("spapitest.emega.com.tw", 56789, 10);
  
      while (!isLogon && !exit)
          std::this_thread::sleep_for(std::chrono::milliseconds{ 1000 });
  
      while (!exit)
      {
          std::cout << "[Select Function]" << std::endl;
          std::cout << " 1: NewOrder" << std::endl;
          std::cout << " 2: CancelOrder" << std::endl;
          std::cout << " 3: ReplaceOrder" << std::endl;
          std::cout << " 4: SendForeignOrder" << std::endl;
          std::cout << " 5: CancelForeignOrder" << std::endl;
          std::cout << " 6: MakeStockAccountInquriy" << std::endl;
          std::cout << " 7: QueryStkOrder" << std::endl;
          std::cout << " 8: QueryStkMatch" << std::endl;
          std::cout << " 9: QueryFutOrder" << std::endl;
          std::cout << "10: QueryFutMatch" << std::endl;
          std::cout << "11: QueryFutUncoverRT" << std::endl;
          std::cout << "12: QueryFutMargin" << std::endl;
          std::cout << "13: ChangePassword" << std::endl;
          std::cout << "14: QueryForeignStockInventory" << std::endl;
          std::cout << "15: QueryForeignStockOrder" << std::endl;
          std::cout << "16: QueryForeignStockFilled" << std::endl;
          std::cout << "17: DownloadForeignStockProductData" << std::endl;
          std::cout << "18: DownloadForeignStockCurrentData" << std::endl;
          std::cout << "19: DownloadForeignStockMarketData" << std::endl;
          std::cout << " 0: Quit" << std::endl;
          std::cout << "-->";
  
          std::string input;
          std::getline(std::cin, input);
          if (input.back() == '\r')
              input.pop_back();
  
          int n = -1;
          try
          {
              n = std::stoi(input);
          }
          catch (...)
          {
              std::cout << "input error! try again." << std::endl;
              continue;
          }
  
          if (0 == n)
          {
              break;
          }
          else if (1 == n)
              cmdNewOrder();
          else if (2 == n)
              cmdCancelOrder();
          else if (3 == n)
              cmdReplaceOrder();
          else if (4 == n)
              cmdNewForeignOrder();
          else if (5 == n)
              cmdCancelForeignOrder();        
          else if (6 == n)
              cmdMakeStockAccountInquriy();
          else if (7 == n)
              cmdQueryStkOrder();
          else if (8 == n)
              cmdQueryStkMatch();
          else if (9 == n)
              cmdQueryFutOrder();
          else if (10 == n)
              cmdQueryFutMatch();
          else if (11 == n)
              cmdQueryFutUncoverRT();
          else if (12 == n)
              cmdQueryFutMargin();
          else if (13 == n)
              cmdChangePassword();
          else if (14 == n)
              cmdQueryForeignStockInventory();
          else if (15 == n)
              cmdQueryForeignStockOrder();
          else if (16 == n)
              cmdQueryForeignStockFilled();
          else if (17 == n)
              cmdDownloadForeignStockProductData();
          else if (18 == n)
              cmdDownloadForeignStockCurrencyData();
          else if (19 == n)
              cmdDownloadForeignStockMarketData();
      }
  }  
main.cpp

#include <iostream>
#include "testSpdOrderAPI.h"
int main()
{
testSpdOrderAPI test_api;
test_api.MainLoop();
return 0;
}

spdQuoteAPI 使用範例 (testSpdQuoteAPI)

testSpdQuoteAPI.h
#pragma once
#include <map>
#include <string>

#include "spdQuoteAPI.h"

struct ContractInfo
{
    std::string Exchange;
    std::string Symbol;
    std::string DisplayName;
    std::string MaturityDate;
    std::string Category;
    double BullPx;
    double BearPx;
    double RefPx;
    double ContractMultiplier;
    double StrikePx;
    std::string Market;
    int TradeUnit;
    std::string DayTrade;
    int WarningStock;
    bool TradeFlag;
    bool IsWarrant;
    std::string CallPut;
};

class testSpdQuoteAPI : public spdQuoteAPI
{
private:
    bool exit{ false };

    std::map<std::string, ContractInfo> Stocks;
    std::map<std::string, ContractInfo> Futures;
    std::map<std::string, ContractInfo> Options;

private:
    void OnStarwaveConnected() override;
    void OnStarwaveDisconnected() override;
    void OnOrderBook(const char* Exchange, const char* Symbol, const char* MsgTime, spdMsgOrderBook* OrderBook) override;
    void OnTrade(const char* Exchange, const char* Symbol, const char* MatchTime, double MatchPrice, int MatchQty, bool isTestMatch) override;
    void OnStarwaveLogonResponse(bool isLoginOK, const char* ReplyMsg) override;
    void OnContract(const char* Exchange, const char* Symbol, const char* Name, const char* MaturityDate, const char* Category, spdContract* Contract) override;
    void OnContractDownloadComplete(int TotalContracts) override;

public:
    void MainLoop();
    void Stop() { exit = true; }
    void AddStock(const char* symbol, ContractInfo* contract) { Stocks.insert(std::pair<std::string, ContractInfo>(symbol, *contract)); }
    void AddFuture(const char* symbol, ContractInfo* contract) { Futures.insert(std::pair<std::string, ContractInfo>(symbol, *contract)); }
    void AddOption(const char* symbol, ContractInfo* contract) { Options.insert(std::pair<std::string, ContractInfo>(symbol, *contract)); }
    void OnDownloadComplete(int TotalContracts);
};

testSpdQuoteAPI.cpp
#include <Windows.h>
#include <iostream>
#include <vector>

#include "testSpdQuoteAPI.h"

void testSpdQuoteAPI::MainLoop()
{

    //訂閱檔數上限20檔
    //LogonStarwave('IP', 34567, '身分證字號(大寫字母)', '電子登入密碼', True )
    //取消訂閱商品:UnsubscribeAll()
    LogonStarwave("ip", 34567, "Z323456789", "1234", true);

    while (!exit)
        Sleep(1000);

}

void testSpdQuoteAPI::OnStarwaveConnected()
{
    std::cout << "-------------- OnConnected() --------------" << std::endl;
}

void testSpdQuoteAPI::OnStarwaveDisconnected()
{
    std::cout << "-------------- OnDisConnected() --------------" << std::endl;
    Stop();
}

void testSpdQuoteAPI::OnOrderBook(const char* Exchange,
                  const char* Symbol, 
                  const char* MsgTime, 
                  spdMsgOrderBook* OrderBook)
{
    std::cout << "-------------- OnOrderBook() --------------" << std::endl;
    std::cout << "--- Exchange[" << Exchange << "]  Symbol[" << Symbol << "]  MsgTime[" << MsgTime << "]" << std::endl;
}

void testSpdQuoteAPI::OnTrade(const char* Exchange,
              const char* Symbol,
              const char* MatchTime,
              double MatchPrice,
              int MatchQty,
              bool isTestMatch)
{
    std::cout << "--------OnTrade---------------" << std::endl;
    std::cout << "---Exchange[" << Exchange << "] Symbol[" << Symbol << "]" << std::endl;
    std::cout << "---MatchTime=" << MatchTime << " MatchPrice = " << MatchPrice << " MatchQty = " << MatchQty << std::endl;
    std::cout << "---isTestMatch=" << isTestMatch << std::endl;
}

void testSpdQuoteAPI::OnStarwaveLogonResponse(bool isLoginOK, const char* ReplyMsg)
{
    std::cout << "-------------- OnLogonResponse() --------------" << std::endl;
    std::cout << "--- IsSucceed:" << isLoginOK << " ReplyString:" << ReplyMsg << std::endl;
}

void testSpdQuoteAPI::OnContract(const char* Exchange,
                const char* Symbol,
                const char* Name,
                const char* MaturityDate,
                const char* Category,
                spdContract* Contract)
{
    ContractInfo contract;
    std::string market = "unknown";
    if (Contract->Market == 0)
        market = "fut";
    else if (Contract->Market == 1)
        market = "opt";
    else if (Contract->Market == 2)
        market = "tse";
    else if (Contract->Market == 3)
        market = "otc";
    else if (Contract->Market == 4)
        market = "ffut";
    else if (Contract->Market == 5)
        market = "fopt";

    std::string day_trade = "No";
    if (Contract->DayTrade == 1)
        day_trade = "Yes";
    else if (Contract->DayTrade == 2)
        day_trade = "OnlyBuy";

    std::string callput = "None";
    if (Contract->CallPut == 'C')
        callput = "Call";
    else if (Contract->CallPut == 'P')
        callput = "Put";

    contract.Exchange = Exchange;
    contract.Symbol = Symbol;
    contract.DisplayName = Name;
    contract.MaturityDate = MaturityDate;
    contract.Category = Category;
    contract.BullPx = Contract->BullPx,
    contract.BearPx = Contract->BearPx,
    contract.RefPx = Contract->RefPx,
    contract.ContractMultiplier = Contract->ContractMultiplier,
    contract.StrikePx = Contract->StrikePx,
    contract.Market = market,
    contract.TradeUnit = Contract->TradeUnit,
    contract.DayTrade = day_trade,
    contract.WarningStock = Contract->WarningStock,
    contract.TradeFlag = Contract->TradeFlag,
    contract.IsWarrant = Contract->IsWarrant,
    contract.CallPut = callput;

    if (Contract->Market == 0)
        AddFuture(contract.Symbol.c_str(), &contract);
    else if (Contract->Market == 1)
        AddOption(contract.Symbol.c_str(), &contract);
    else if (Contract->Market == 2 || Contract->Market == 3)
        AddStock(contract.Symbol.c_str(), &contract);
}

void testSpdQuoteAPI::OnContractDownloadComplete(int TotalContracts)
{
    std::cout << "-------------- OnContractDownloadComplete(" << TotalContracts << ")--------------" << std::endl;
    std::cout << "已下載股票商品" << Stocks.size() << "筆" << std::endl;
    std::cout << "已下載期貨商品" << Futures.size() << "筆" << std::endl;
    std::cout << "已下載選擇權商品" << Options.size() << "筆" << std::endl;

    auto iter = Stocks.find("2330");
    if (iter != Stocks.end())
        Subscribe(iter->second.Exchange.c_str(), "2330");
    iter = Futures.find("MXFE4");
    if (iter != Futures.end())
        Subscribe(iter->second.Exchange.c_str(), "MXFE4");
    iter = Futures.find("TXFE4");
    if (iter != Futures.end())
        Subscribe(iter->second.Exchange.c_str(), "TXFE4");
}  
main.cpp
#include <iostream>
#include "testSpdQuoteAPI.h"
int main()
{
testSpdQuoteAPI program;
program.MainLoop();
return 0;
}