c++实现简单股票买入和撤销功能
需求:
For example:
A,16113575,B,18,585
It decoded as:
A = add new order
16113575 = order id
B = buy order
18 = number of shares to buy
585 = price
Example of input file:
A,100000,S,90,2
A,100001,S,107,2
A,100002,B,110,5
A,100002,B,110,10
输出:
ASK
110: 5 10
107: 2
90: 2
BID
#include<iostream>
#include<string>
#include<string.h>
#include<map>
#include<vector>
#include<fstream>
#include<sstream>
using namespace std;
// 委托信息
class orderMessage{
public:
orderMessage(){
clear();
}
// 信息初始化
void clear() {
m_cAction = ' ';
m_noperionId= 0;
m_cbsflag = ' ';
m_nbsqty = 0;
m_dbAmt = 0;
}
// 打印订单信息
void printAll() {
cout<<m_cAction<<","<<m_noperionId<<","<<m_cbsflag<<","<<m_nbsqty<<","<<m_dbAmt<<endl;
}
public:
// 数据结构:A,16113575,B,18,585
char m_cAction; // 操作类型 A 添加 X 撤销
int m_noperionId; // 委托编号
char m_cbsflag; // 买卖标志 B 买入 S 卖出
int m_nbsqty; // 买卖数量
double m_dbAmt; // 买卖金额
};
// 检查int
bool checkStringisInt(const string str){
for (auto chr:str)
{
if(!isdigit(chr)) return false;
}
return true;
}
// 检查double
bool checkStringisDouble(const string str){
for (auto chr:str)
{
if(chr != '.' && !isdigit(chr)) return false;
}
return true;
}
// 正确读取数据成功
bool getData(const string keep, orderMessage &objorderMessage) {
int index = 0;
string tmp = "";
for (auto chr : keep) {
if(chr == ',') {
if(tmp == "" && index < 5) return false;
// 获取参数
if(index == 0)
{
if(tmp.size() != 1 && strstr("AX", tmp.c_str())) return false; // 添加/撤销
objorderMessage.m_cAction = tmp[0];
}else if(index == 1)
{
if(checkStringisInt(tmp) == false) return false; // 数字
objorderMessage.m_noperionId = stoi(tmp);
}else if(index == 2)
{
if(tmp.size() != 1 && strstr("BS", tmp.c_str())) return false; // 买卖BS
objorderMessage.m_cbsflag = tmp[0];
}else if(index == 3)
{
if(checkStringisInt(tmp) == false) return false; // 数字
objorderMessage.m_nbsqty = stoi(tmp);
}else if(index == 4)
{
if(checkStringisDouble(tmp) == false) return false; // 检查是否为double
objorderMessage.m_dbAmt = stof(tmp);
}
index++;
tmp = "";
}else{
tmp += chr;
}
}
if(index < 5) return false; // 列数不够,无效数据
return true;
}
// 处理新增数据
void dealAddData(map<double, map<int, orderMessage>> &mpBug, map<double, map<int, orderMessage>> &mpSale, orderMessage &objorderMessage, bool isBuy) {
map<double, map<int, orderMessage>>::iterator it;
map<int, orderMessage>::iterator it2;
bool isdelete = false; // 是否删除元素
int nIndex = 0; // 记录订单号
// double dbamt = objorderMessage.m_dbAmt;
if(isBuy)
{
if(mpSale.size() > 0) // 判断卖map是否合适的卖单,可以处理
{
it = mpSale.begin();
double dbamt = it->first;
if(dbamt <= objorderMessage.m_dbAmt) // 有低于买单的卖单
{
bool check = false;
vector<double> vecDeleteAmt;
for(;it != mpSale.end(); it++) {
if(check) break; // 买单全部成交完成
if(it->first > objorderMessage.m_dbAmt) break; // 卖单高于买单价格 不能成交
vector<int> vecDeleteOrderid;
for(it2 = it->second.begin(); it2 != it->second.end(); it2++) {
if(it2->second.m_nbsqty > objorderMessage.m_nbsqty) {
it2->second.m_nbsqty -= objorderMessage.m_nbsqty;
objorderMessage.m_nbsqty = 0;
check = true;
}else{
objorderMessage.m_nbsqty -= it2->second.m_nbsqty;
vecDeleteOrderid.push_back(it2->second.m_noperionId);
}
}
for (auto elem: vecDeleteOrderid){
it->second.erase(elem);
}
if(it->second.size() <= 0) vecDeleteAmt.push_back(it->first);
}
for (auto elem: vecDeleteAmt){
mpSale.erase(elem);
}
}
}
if(objorderMessage.m_nbsqty > 0) {
mpBug[-objorderMessage.m_dbAmt][objorderMessage.m_noperionId] = objorderMessage;
}
}else
{
if(mpBug.size() > 0) {
it = mpBug.begin();
double dbamt = -it->first;
if(dbamt >= objorderMessage.m_dbAmt) // 有高于卖单的买单
{
bool check = false;
vector<double> vecDeleteAmt;
for(;it != mpSale.end(); it++) {
if(check) break; // 买单全部成交完成
if(-it->first < objorderMessage.m_dbAmt) break; // 买单高于卖单价格 不能成交
vector<int> vecDeleteOrderid;
for(it2 = it->second.begin(); it2 != it->second.end(); it2++) {
if(it2->second.m_nbsqty > objorderMessage.m_nbsqty) {
it2->second.m_nbsqty -= objorderMessage.m_nbsqty;
objorderMessage.m_nbsqty = 0;
check = true;
}else{
objorderMessage.m_nbsqty -= it2->second.m_nbsqty;
vecDeleteOrderid.push_back(it2->second.m_noperionId);
}
}
for (auto elem: vecDeleteOrderid){
it->second.erase(elem);
}
if(it->second.size() <= 0) vecDeleteAmt.push_back(it->first);
}
for (auto elem: vecDeleteAmt){
mpBug.erase(elem);
}
}
}
if(objorderMessage.m_nbsqty > 0) {
mpSale[objorderMessage.m_dbAmt][objorderMessage.m_noperionId] = objorderMessage;
}
}
}
// 处理撤销数据
void dealDeleteData(map<double, map<int, orderMessage>> &mpBug, orderMessage &objorderMessage, bool isBuy) {
map<double, map<int, orderMessage>>::iterator it;
map<int, orderMessage>::iterator it2;
bool isdelete = false; // 是否删除元素
int nIndex = 0; // 记录订单号
double dbamt = objorderMessage.m_dbAmt;
if(isBuy) dbamt = -dbamt;
// 根据金额查询订单
it = mpBug.find(dbamt);
if(it != mpBug.end())
{
// 根据订单号 查询订单信息
it2 = it->second.find(objorderMessage.m_noperionId);
if(it2 != it->second.end()) {
// 减掉撤销的数量
it2->second.m_nbsqty -= objorderMessage.m_nbsqty;
if(it2->second.m_nbsqty <= 0) {
nIndex = it2->first;
isdelete = true;
}
}
if(isdelete == true) it->second.erase(nIndex);
}
if(it->second.size() <= 0) mpBug.erase(dbamt);
}
// 打印数据
void printMapOrderMessage(map<double, map<int, orderMessage>> &mp, bool isBuy) {
if(isBuy == true)
{
map<double, map<int, orderMessage>>::iterator it;
map<int, orderMessage>::iterator it2;
for (it = mp.begin(); it != mp.end(); it++)
{
// if(it->second.size() <= 0) continue;
double index = abs(it->first);
map<int, orderMessage> mp2 = it->second;
cout<<index<<": ";
for (it2 = mp2.begin(); it2 != mp2.end(); it2++)
{
cout<<it2->second.m_nbsqty<<" ";
}
cout<<endl;
}
}else{
map<double, map<int, orderMessage>>::reverse_iterator it;
map<int, orderMessage>::iterator it2;
for (it = mp.rbegin(); it != mp.rend(); it++)
{
// if(it->second.size() <= 0) continue;
double index = abs(it->first);
map<int, orderMessage> mp2 = it->second;
cout<<index<<": ";
for (it2 = mp2.begin(); it2 != mp2.end(); it2++)
{
cout<<it2->second.m_nbsqty<<" ";
}
cout<<endl;
}
}
}
orderMessage objorderMessage;
map<double, map<int, orderMessage>> mpBug; // 买入订单 mpBug.first 为买入金额 mpBug.second.first 为委托编号,mpBug.second.second 为订单信息
map<double, map<int, orderMessage>> mpSale; // 卖出订单 与mpBug类似
map<double, map<int, orderMessage>>::iterator it;
map<int, orderMessage>::iterator it2;
int main(){
// 读取测试数据
std::ifstream f{"C:/Users/Desktop/coding_test.txt", std::ios::binary};
std::stringstream ss;
ss << f.rdbuf();
// string data = ss.str();
// string data = "A,100000,S,1,1075\nA,100001,B,9,1000\nA,100002,B,30,975\nA,100003,S,10,1050\nA,100004,B,10,950\nA,100005,S,2,1025\nA,100006,B,1,1000\nX,100004,B,10,950\nA,100007,S,5,1025\nA,100008,B,3,1050\nX,100008,B,3,1050\nX,100005,S,2,1025\n";
string data = "A,100000,S,1,1075\nA,100001,B,9,1000\nA,100002,B,30,975\nA,100003,S,10,975\n";
string keep = "";
cout<<"Example of input file:"<<endl;
for (auto chr : data) {
// 处理订单信息
if(chr == '\n')
{
keep.push_back(','); // 增加',', 便于数据处理:A,100000,S,1,1075,
objorderMessage.clear();
if(getData(keep, objorderMessage)) // 取数据成功
{
objorderMessage.printAll();
bool isBug = true; // 是否买入 true 买入 false 卖出
if(objorderMessage.m_cbsflag == 'S') isBug = false;
// <-------------------------------------代码核心数据处理部分------------------------------------>
if(objorderMessage.m_cAction == 'A') // 新增的订单
{
dealAddData(mpBug, mpSale, objorderMessage, isBug);
}
else if(objorderMessage.m_cAction == 'X') // 撤销的订单
{ if(objorderMessage.m_cbsflag == 'B')
{
dealDeleteData(mpBug, objorderMessage, isBug);
}else{
dealDeleteData(mpSale, objorderMessage, isBug);
}
}
}
keep = "";
}else
{
keep += chr;
}
}
// 结果打印
cout<<endl<<endl;
cout<<"my result:"<<endl;
cout<<"================="<<endl;
cout<<"ASK"<<endl;
printMapOrderMessage(mpBug, true); // 输出买入信息
cout<<"------------"<<endl<<endl;
printMapOrderMessage(mpSale, false); // 输出卖出信息
cout<<"BID"<<endl;
cout<<"================="<<endl;
system("pause");
return 0;
}