#include <iostream>
#include <thread>
#include <chrono>
#include <fstream>
#include "testSpdOrderAPI.h"

void testSpdOrderAPI::OnSpeedyConnected()
{
	std::cout << "----------OnSpeedyConnected--------------" << std::endl;	
	 /*
        登入證券
        LogonSpeedy('身分證字號(大寫字母)', '電子登入密碼', '證券帳號七位數如:[0023456]')

        登入期貨
        LogonSpeedy('身分證字號(大寫字母)', '電子登入密碼', '期貨帳號七位數如:[0123457]')

        登入證期市場逗號分隔
        LogonSpeedy('身分證字號(大寫字母)', '電子登入密碼', '證券帳號七位數如:[0023456],期貨帳號七位數如:[0123457]')
		
		登入複委託
        LogonSpeedy('身分證字號(大寫字母)', '電子登入密碼', '期貨帳號六位數如:[012345]')
        */
	if (!LogonSpeedy("A123456789", "1234", "1234567"))
	{
		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", "1234567");
		//複委託設定下單帳號
        //SetAccount( 'US', '分公司別四位數', '證券帳號六位數')
		SetAccount("US", "7000", "012345");
		

        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 us:) ->";
	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 << "SendCancelOrder 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::cmdGetKChartData(int index)
{
	std::cout << "[symbol] -> ";
	std::string symbol = ReadLine();

	std::string s_json;
	if (0 == index)
		s_json = GetMKChartData(symbol.c_str());
	else if (1 == index)
		s_json = GetWKChartData(symbol.c_str());
	else if (2 == index)
		s_json = GetDKChartData(symbol.c_str());
	else if (3 == index)
		s_json = GetAdjustedMKChartData(symbol.c_str());
	else if (4 == index)
		s_json = GetAdjustedWKChartData(symbol.c_str());
	else if (5 == index)
		s_json = GetAdjustedDKChartData(symbol.c_str());

	std::cout << s_json << std::endl;
}

void testSpdOrderAPI::MainLoop()
{
	//EnableMEGACA("憑證檔路徑","身分證字號(大寫字母)","憑證密碼")
	if (!EnableMegaCA("A123456789.pfx","A123456789", "A123456789"))
    {
        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 << "20: GetMKChartData" << std::endl;
		std::cout << "21: GetWKChartData" << std::endl;
		std::cout << "22: GetDKChartData" << std::endl;
		std::cout << "23: GetAdjustedMKChartData" << std::endl;
		std::cout << "24: GetAdjustedWKChartData" << std::endl;
		std::cout << "25: GetAdjustedDKChartData" << 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();
		else if (20 == n)
			cmdGetKChartData(0);
		else if (21 == n)
			cmdGetKChartData(1);
		else if (22 == n)
			cmdGetKChartData(2);
		else if (23 == n)
			cmdGetKChartData(3);
		else if (24 == n)
			cmdGetKChartData(4);
		else if (25 == n)
			cmdGetKChartData(5);
	}
}
