step by step开发一个简易股票交易系统(四)---支持多股票

Step4:使用gen_server改写stock,增加stock_server,支持多只股票买卖,支持股票开牌/停牌,可以显示交易挂单
stock.erl

-module(stock).
-behaviour(gen_server).
-export([start/0,stop/0]).

-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-record(state, {}).

start()->gen_server:start_link({local,?MODULE},?MODULE,[],[]).
stop()->gen_server:call(?MODULE,stop).
init([]) ->
{ok, {[],[],1}}.

handle_call(stop,_From,L) ->
{stop,normal,stopped,L}.

handle_cast({sell,{Price,Number,Name}}, {BuyL,SellL,TradeId}) ->
case lookup(buy,{Price,none},BuyL) of
{_,Price,0,none}->
L2=add(sell,{TradeId,Price,Number,Name},SellL),
gen_server:cast(stock_server,{ok,hangup}),
{noreply,{BuyL,L2,TradeId+1}};
{TradeId1,Price1,Number1,Buy}->
if Number1=:=Number->
L2=remove({TradeId1,Price1,Number1,Buy},BuyL),
gen_server:cast(stock_server,{ok,Buy}),
{noreply,{L2,SellL,TradeId}};
Number1<Number->
L2=remove({TradeId1,Price1,Number1,Buy},BuyL),
gen_server:cast(stock_server,{ok,Buy}),
handle_cast({sell,{Price,Number-Number1,Name}},{L2,SellL,TradeId});
Number1>Number->
L2=[replace(X,{TradeId1,Price1,Number1,Buy},Number1-Number)||X<-BuyL],
gen_server:cast(stock_server,{ok,Buy}),
{noreply,{L2,SellL,TradeId}}
end

end;


handle_cast({buy,{Price,Number,Name}}, {BuyL,SellL,TradeId}) ->
case lookup(sell,{Price,none},SellL) of
{_,Price,0,none}->
L2=add(buy,{TradeId,Price,Number,Name},BuyL),
gen_server:cast(stock_server,{ok,hangup}),
{noreply,{L2,SellL,TradeId+1}};
{TradeId1,Price1,Number1,Sell}->
if Number1=:=Number->
L2=remove({TradeId1,Price1,Number1,Sell},SellL),
gen_server:cast(stock_server,{ok,Sell}),
{noreply,{BuyL,L2,TradeId}};
Number1<Number->
L2=remove({TradeId1,Price1,Number1,Sell},SellL),
gen_server:cast(stock_server,{ok,Sell}),
handle_cast({buy,{Price,Number-Number1,Name}},{BuyL,L2,TradeId});
Number1>Number->
L2=[replace(X,{TradeId1,Price1,Number1,Sell},Number1-Number)||X<-SellL],
gen_server:cast(stock_server,{ok,Sell}),
{noreply,{BuyL,L2,TradeId}}
end

end;

handle_cast({list,Count}, {BuyL,SellL,TradeId}) ->
X = getList(Count,BuyL),
gen_server:cast(stock_server,{ok,{buy_list,X}}),
Y = getList(Count,SellL),
gen_server:cast(stock_server,{ok,{sell_list,Y}}),
{noreply,{BuyL,SellL,TradeId}};

handle_cast(stop,State) ->
{stop,normal,State};

handle_cast(_Msg, State) ->
{noreply, State}.

handle_info(Info, State) ->
{noreply, State}.

terminate(Reason, State) ->
ok.

code_change(OldVsn, State, Extra) ->
{ok, State}.

lookup(sell,{Price,Buy},[{TradeId,Price1,Number,Name}|_T]) ->
if
Price>=Price1 -> {TradeId,Price1,Number,Name};
true->{0,Price,0,Buy}
end;

lookup(buy,{Price,Sell},[{TradeId,Price1,Number,Name}|_T]) ->
if
Price=<Price1 -> {TradeId,Price1,Number,Name};
true->{0,Price,0,Sell}
end;
lookup(_,{Price,Name},[])->{0,Price,0,Name}.

add(sell,{TradeId,Price,Number,Name},[{TradeId1,Price1,Number1,Name1}|T]) ->
if
Price>=Price1 -> [{TradeId1,Price1,Number1,Name1}|add(sell,{TradeId,Price,Number,Name},T)];
true->[{TradeId,Price,Number,Name}|[{TradeId1,Price1,Number1,Name1}|T]]
end;

add(buy,{TradeId,Price,Number,Name},[{TradeId1,Price1,Number1,Name1}|T]) ->
if
Price=<Price1 -> [{TradeId1,Price1,Number1,Name1}|add(buy,{TradeId,Price,Number,Name},T)];
true->[{TradeId,Price,Number,Name}|[{TradeId1,Price1,Number1,Name1}|T]]
end;
add(_,{TradeId,Price,Number,Name},[])->[{TradeId,Price,Number,Name}].

remove(Trade,L)-> [X||X<-L,X/=Trade].

replace({TradeId,Price,Number,Name},{TradeId1,Price1,Number1,Name1},Number2)->
if
{TradeId1,Price1,Number1,Name1}=:={TradeId,Price,Number,Name}->
{TradeId,Price,Number2,Name};
true->{TradeId,Price,Number,Name}
end.

getList(_,[])->[];
getList(0,_)->[];
getList(Count,[{_,Price,Number,Name}|T])->
[{Price,Number,Name}|getList(Count-1,T)].

stock_server.erl

-module(stock_server).

-behaviour(gen_server).
-export([list/1, sell/2, buy/2, start/0,stop/0,start_trade/1,stop_trade/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-record(state, {}).

-import(stock,[start/1,stop/1]).
start()->gen_server:start_link({local,stock_server},stock_server,[],[]).
stop()->gen_server:cast(?MODULE,stop).
sell(Id,Trade)->gen_server:cast(?MODULE,{sell,Id,Trade}).
buy(Id,Trade)->gen_server:cast(?MODULE,{buy,Id,Trade}).
list(Id)->gen_server:cast(?MODULE,{list,Id}).
start_trade(Id)->gen_server:cast(?MODULE,{start_trade,Id}).
stop_trade(Id)->gen_server:cast(?MODULE,{stop_trade,Id}).

init([]) ->
{ok, []}.

handle_call(Request, From, State) ->
Reply = ok,
{reply, Reply, State}.

handle_cast(stop,State) ->
{stop,stopped,State};

handle_cast({start_trade,Id},State) ->
case gen_server:start(stock,[],[]) of
{ok,Pid}->put(Id,Pid);
Any->
io:format("start_trade error:~w~n",[Any])
end,
{noreply, State};
handle_cast({stop_trade,Id},State) ->
case get(Id) of
undefined->
io:format("stock Id=~w have not start trade~n",[Id]);
Pid->
gen_server:call(Pid,stop),
erase(Id)

end,
{noreply, State};

handle_cast({list,Id}, State) ->
case get(Id) of
undefined->
io:format("stock Id=~w have not start trade~n",[Id]);
Pid->
gen_server:cast(Pid,{list,5})
end,
{noreply, State};

handle_cast({buy,Id,Trade}, State) ->
case get(Id) of
undefined->
io:format("stock Id=~w have not start trade~n",[Id]);
Pid->

gen_server:cast(Pid,{buy,Trade})
end,
{noreply, State};

handle_cast({sell,Id,Trade}, State) ->
case get(Id) of
undefined->
io:format("stock Id=~w have not start trade~n",[Id]);
Pid->

gen_server:cast(Pid,{sell,Trade})
end,
{noreply, State};

handle_cast({ok,Msg}, State) ->
io:format("ok: ~w~n",[Msg]),
{noreply, State};

handle_cast(_Msg, State) ->
{noreply, State}.

handle_info(Info, State) ->
{noreply, State}.

terminate(Reason, State) ->
ok.
code_change(OldVsn, State, Extra) ->
{ok, State}.
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值