414 lines
15 KiB
MQL5
414 lines
15 KiB
MQL5
|
//+------------------------------------------------------------------+
|
|||
|
//| MarketBook.mqh |
|
|||
|
//| Copyright 2015, MetaQuotes Software Corp. |
|
|||
|
//| http://www.mql5.com |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
#property copyright "Copyright 2015, MetaQuotes Software Corp."
|
|||
|
#property link "http://www.mql5.com"
|
|||
|
|
|||
|
#define LAST_ASK_INDEX 0
|
|||
|
#define LAST_BID_INDEX m_depth_total-1
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Side of MarketBook. |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
enum ENUM_MBOOK_SIDE
|
|||
|
{
|
|||
|
MBOOK_ASK, // Ask side
|
|||
|
MBOOK_BID // Bid (offer) side
|
|||
|
};
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Market Book info integer properties. |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
enum ENUM_MBOOK_INFO_INTEGER
|
|||
|
{
|
|||
|
MBOOK_BEST_ASK_INDEX, // Best ask index
|
|||
|
MBOOK_BEST_BID_INDEX, // Best bid index
|
|||
|
MBOOK_LAST_ASK_INDEX, // Last (worst) ask index
|
|||
|
MBOOK_LAST_BID_INDEX, // Last (worst) bid index
|
|||
|
MBOOK_DEPTH_ASK, // Depth of ask side
|
|||
|
MBOOK_DEPTH_BID, // Depth of bid side
|
|||
|
MBOOK_DEPTH_TOTAL, // Total depth
|
|||
|
MBOOK_MAX_ASK_VOLUME, // Max ask volume
|
|||
|
MBOOK_MAX_ASK_VOLUME_INDEX, // Max ask volume index
|
|||
|
MBOOK_MAX_BID_VOLUME, // Max bid volume
|
|||
|
MBOOK_MAX_BID_VOLUME_INDEX, // Max bid volume index
|
|||
|
MBOOK_ASK_VOLUME_TOTAL, // Total volume on Ask side of MarketBook
|
|||
|
MBOOK_BID_VOLUME_TOTAL, // Total volume on Bid side of MarketBook
|
|||
|
MBOOK_BUY_ORDERS, // Total orders on sell
|
|||
|
MBOOK_SELL_ORDERS, // Total orders on buy
|
|||
|
|
|||
|
};
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Market Book info double properties. |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
enum ENUM_MBOOK_INFO_DOUBLE
|
|||
|
{
|
|||
|
MBOOK_BEST_ASK_PRICE, // Best ask price,
|
|||
|
MBOOK_BEST_BID_PRICE, // Best bid price,
|
|||
|
MBOOK_LAST_ASK_PRICE, // Last (worst) ask price,
|
|||
|
MBOOK_LAST_BID_PRICE, // Last (worst) bid price,
|
|||
|
MBOOK_AVERAGE_SPREAD, // Average spread for work time
|
|||
|
MBOOK_OPEN_INTEREST, // Current Open Interest of Market
|
|||
|
MBOOK_BUY_ORDERS_VOLUME, // Total volume of sell orders
|
|||
|
MBOOK_SELL_ORDERS_VOLUME, // Total volume of buy orders
|
|||
|
};
|
|||
|
|
|||
|
class CMarketBook;
|
|||
|
|
|||
|
class CBookCalculation
|
|||
|
{
|
|||
|
private:
|
|||
|
int m_max_ask_index; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
long m_max_ask_volume; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
int m_max_bid_index; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
long m_max_bid_volume; // <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
long m_sum_ask_volume; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
long m_sum_bid_volume; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|||
|
|
|||
|
bool m_calculation; // <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
CMarketBook* m_book; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
|
|||
|
|
|||
|
void Calculation(void)
|
|||
|
{
|
|||
|
// FOR ASK SIDE
|
|||
|
int begin = (int)m_book.InfoGetInteger(MBOOK_LAST_ASK_INDEX);
|
|||
|
int end = (int)m_book.InfoGetInteger(MBOOK_BEST_ASK_INDEX);
|
|||
|
for(int i = begin; i < end; i++)
|
|||
|
{
|
|||
|
if(m_book.MarketBook[i].volume > m_max_ask_volume)
|
|||
|
{
|
|||
|
m_max_ask_index = i;
|
|||
|
m_max_ask_volume = m_book.MarketBook[i].volume;
|
|||
|
}
|
|||
|
m_sum_ask_volume += m_book.MarketBook[i].volume;
|
|||
|
}
|
|||
|
// FOR BID SIDE
|
|||
|
begin = (int)m_book.InfoGetInteger(MBOOK_BEST_BID_INDEX);
|
|||
|
end = (int)m_book.InfoGetInteger(MBOOK_LAST_BID_INDEX);
|
|||
|
for(int i = begin; i < end; i++)
|
|||
|
{
|
|||
|
if(m_book.MarketBook[i].volume > m_max_bid_volume)
|
|||
|
{
|
|||
|
m_max_bid_index = i;
|
|||
|
m_max_bid_volume = m_book.MarketBook[i].volume;
|
|||
|
}
|
|||
|
m_sum_bid_volume += m_book.MarketBook[i].volume;
|
|||
|
}
|
|||
|
m_calculation = true;
|
|||
|
}
|
|||
|
|
|||
|
public:
|
|||
|
CBookCalculation(CMarketBook* book)
|
|||
|
{
|
|||
|
Reset();
|
|||
|
m_book = book;
|
|||
|
}
|
|||
|
|
|||
|
void Reset()
|
|||
|
{
|
|||
|
m_max_ask_volume = 0.0;
|
|||
|
m_max_bid_volume = 0.0;
|
|||
|
m_max_ask_index = -1;
|
|||
|
m_max_bid_index = -1;
|
|||
|
m_sum_ask_volume = 0;
|
|||
|
m_sum_bid_volume = 0;
|
|||
|
m_calculation = false;
|
|||
|
}
|
|||
|
int GetMaxVolAskIndex()
|
|||
|
{
|
|||
|
if(!m_calculation)
|
|||
|
Calculation();
|
|||
|
return m_max_ask_index;
|
|||
|
}
|
|||
|
|
|||
|
long GetMaxVolAsk()
|
|||
|
{
|
|||
|
if(!m_calculation)
|
|||
|
Calculation();
|
|||
|
return m_max_ask_volume;
|
|||
|
}
|
|||
|
int GetMaxVolBidIndex()
|
|||
|
{
|
|||
|
if(!m_calculation)
|
|||
|
Calculation();
|
|||
|
return m_max_bid_index;
|
|||
|
}
|
|||
|
|
|||
|
long GetMaxVolBid()
|
|||
|
{
|
|||
|
if(!m_calculation)
|
|||
|
Calculation();
|
|||
|
return m_max_bid_volume;
|
|||
|
}
|
|||
|
long GetAskVolTotal()
|
|||
|
{
|
|||
|
if(!m_calculation)
|
|||
|
Calculation();
|
|||
|
return m_sum_ask_volume;
|
|||
|
}
|
|||
|
long GetBidVolTotal()
|
|||
|
{
|
|||
|
if(!m_calculation)
|
|||
|
Calculation();
|
|||
|
return m_sum_bid_volume;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
class CMarketBook
|
|||
|
{
|
|||
|
private:
|
|||
|
string m_symbol; // Market Book symbol
|
|||
|
int m_depth_total; // Market depth total
|
|||
|
bool m_available; // True if market book available, otherwise false
|
|||
|
double m_spread_sum; // Accumulation spread;
|
|||
|
int m_count_refresh; // Count call CMarketBook::Refresh()
|
|||
|
/* Indexes fields*/
|
|||
|
int m_best_ask_index; // Best ask index
|
|||
|
int m_best_bid_index; // Best bid index
|
|||
|
|
|||
|
void SetBestAskAndBidIndex(void);
|
|||
|
bool FindBestBid(void);
|
|||
|
CBookCalculation Calculation;
|
|||
|
public:
|
|||
|
MqlBookInfo MarketBook[]; // Array of market book
|
|||
|
CMarketBook();
|
|||
|
CMarketBook(string symbol);
|
|||
|
long InfoGetInteger(ENUM_MBOOK_INFO_INTEGER property);
|
|||
|
double InfoGetDouble(ENUM_MBOOK_INFO_DOUBLE property);
|
|||
|
void Refresh(void);
|
|||
|
bool IsAvailable(void);
|
|||
|
bool SetMarketBookSymbol(string symbol);
|
|||
|
string GetMarketBookSymbol(void);
|
|||
|
double GetDeviationByVol(long vol, ENUM_MBOOK_SIDE side);
|
|||
|
long GetVolByDeviation(double deviation, ENUM_MBOOK_SIDE side);
|
|||
|
};
|
|||
|
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Default constructor. |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
CMarketBook::CMarketBook(void) : Calculation(GetPointer(this))
|
|||
|
{
|
|||
|
SetMarketBookSymbol(Symbol());
|
|||
|
}
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Create Market Book and set symbol for it. |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
CMarketBook::CMarketBook(string symbol) : Calculation(GetPointer(this))
|
|||
|
{
|
|||
|
SetMarketBookSymbol(symbol);
|
|||
|
}
|
|||
|
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Get symbol for market book. |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
string CMarketBook::GetMarketBookSymbol(void)
|
|||
|
{
|
|||
|
return m_symbol;
|
|||
|
}
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Set symbol for market book. |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
bool CMarketBook::SetMarketBookSymbol(string symbol)
|
|||
|
{
|
|||
|
bool isSelect = SymbolSelect(symbol, true);
|
|||
|
if(isSelect)
|
|||
|
m_symbol = symbol;
|
|||
|
else
|
|||
|
{
|
|||
|
if(!SymbolSelect(m_symbol, true) && SymbolSelect(Symbol(), true))
|
|||
|
m_symbol = Symbol();
|
|||
|
}
|
|||
|
if(isSelect)
|
|||
|
MarketBookAdd(m_symbol);
|
|||
|
return isSelect;
|
|||
|
}
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Refresh Market Book. |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
void CMarketBook::Refresh(void)
|
|||
|
{
|
|||
|
m_available = MarketBookGet(m_symbol, MarketBook);
|
|||
|
m_depth_total = ArraySize(MarketBook);
|
|||
|
if(m_depth_total == 0)return;
|
|||
|
SetBestAskAndBidIndex();
|
|||
|
m_count_refresh++;
|
|||
|
if(m_depth_total > 1)
|
|||
|
m_spread_sum += MarketBook[m_best_ask_index].price-MarketBook[m_best_bid_index].price;
|
|||
|
Calculation.Reset();
|
|||
|
}
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Return true if market book is available, otherwise return false |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
bool CMarketBook::IsAvailable(void)
|
|||
|
{
|
|||
|
return m_available;
|
|||
|
}
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Find best ask and bid indexes and set this indexes for |
|
|||
|
//| m_best_ask_index and m_best_bid field |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
void CMarketBook::SetBestAskAndBidIndex(void)
|
|||
|
{
|
|||
|
if(!FindBestBid())
|
|||
|
{
|
|||
|
//Find best ask by slow full search
|
|||
|
int bookSize = ArraySize(MarketBook);
|
|||
|
for(int i = 0; i < bookSize; i++)
|
|||
|
{
|
|||
|
if((MarketBook[i].type == BOOK_TYPE_BUY) || (MarketBook[i].type == BOOK_TYPE_BUY_MARKET))
|
|||
|
{
|
|||
|
m_best_ask_index = i-1;
|
|||
|
FindBestBid();
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Fast find best bid by best ask |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
bool CMarketBook::FindBestBid(void)
|
|||
|
{
|
|||
|
m_best_bid_index = -1;
|
|||
|
bool isBestAsk = m_best_ask_index >= 0 && m_best_ask_index < m_depth_total &&
|
|||
|
(MarketBook[m_best_ask_index].type == BOOK_TYPE_SELL ||
|
|||
|
MarketBook[m_best_ask_index].type == BOOK_TYPE_SELL_MARKET);
|
|||
|
if(!isBestAsk)return false;
|
|||
|
int bestBid = m_best_ask_index+1;
|
|||
|
bool isBestBid = bestBid >= 0 && bestBid < m_depth_total &&
|
|||
|
(MarketBook[bestBid].type == BOOK_TYPE_BUY ||
|
|||
|
MarketBook[bestBid].type == BOOK_TYPE_BUY_MARKET);
|
|||
|
if(isBestBid)
|
|||
|
{
|
|||
|
m_best_bid_index = bestBid;
|
|||
|
return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Get integer property by ENUM_MBOOK_INFO_INTEGER modifier |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
long CMarketBook::InfoGetInteger(ENUM_MBOOK_INFO_INTEGER property)
|
|||
|
{
|
|||
|
switch(property)
|
|||
|
{
|
|||
|
case MBOOK_BEST_ASK_INDEX:
|
|||
|
return m_best_ask_index;
|
|||
|
case MBOOK_BEST_BID_INDEX:
|
|||
|
return m_best_bid_index;
|
|||
|
case MBOOK_LAST_ASK_INDEX:
|
|||
|
return LAST_ASK_INDEX;
|
|||
|
case MBOOK_LAST_BID_INDEX:
|
|||
|
return LAST_BID_INDEX;
|
|||
|
case MBOOK_DEPTH_TOTAL:
|
|||
|
return m_depth_total;
|
|||
|
case MBOOK_DEPTH_BID:
|
|||
|
return (m_depth_total - m_best_bid_index);
|
|||
|
case MBOOK_DEPTH_ASK:
|
|||
|
return m_best_bid_index;
|
|||
|
case MBOOK_MAX_ASK_VOLUME:
|
|||
|
return Calculation.GetMaxVolAsk();
|
|||
|
case MBOOK_MAX_ASK_VOLUME_INDEX:
|
|||
|
return Calculation.GetMaxVolAskIndex();
|
|||
|
case MBOOK_MAX_BID_VOLUME:
|
|||
|
return Calculation.GetMaxVolBid();
|
|||
|
case MBOOK_MAX_BID_VOLUME_INDEX:
|
|||
|
return Calculation.GetMaxVolBidIndex();
|
|||
|
case MBOOK_BUY_ORDERS:
|
|||
|
return SymbolInfoInteger(m_symbol, SYMBOL_SESSION_BUY_ORDERS);
|
|||
|
case MBOOK_SELL_ORDERS:
|
|||
|
return SymbolInfoInteger(m_symbol, SYMBOL_SESSION_SELL_ORDERS);
|
|||
|
case MBOOK_ASK_VOLUME_TOTAL:
|
|||
|
Calculation.GetAskVolTotal();
|
|||
|
case MBOOK_BID_VOLUME_TOTAL:
|
|||
|
Calculation.GetBidVolTotal();
|
|||
|
}
|
|||
|
return 0;
|
|||
|
}
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Get double property by ENUM_MBOOK_INFO_DOUBLE modifier |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
double CMarketBook::InfoGetDouble(ENUM_MBOOK_INFO_DOUBLE property)
|
|||
|
{
|
|||
|
switch(property)
|
|||
|
{
|
|||
|
case MBOOK_BEST_ASK_PRICE:
|
|||
|
return MarketBook[m_best_ask_index].price;
|
|||
|
case MBOOK_BEST_BID_PRICE:
|
|||
|
return MarketBook[m_best_bid_index].price;
|
|||
|
case MBOOK_LAST_ASK_PRICE:
|
|||
|
return MarketBook[LAST_ASK_INDEX].price;
|
|||
|
case MBOOK_LAST_BID_PRICE:
|
|||
|
return MarketBook[LAST_BID_INDEX].price;
|
|||
|
case MBOOK_AVERAGE_SPREAD:
|
|||
|
return (m_spread_sum/m_count_refresh);
|
|||
|
case MBOOK_BUY_ORDERS_VOLUME:
|
|||
|
return SymbolInfoDouble(m_symbol, SYMBOL_SESSION_BUY_ORDERS_VOLUME);
|
|||
|
case MBOOK_SELL_ORDERS_VOLUME:
|
|||
|
return SymbolInfoDouble(m_symbol, SYMBOL_SESSION_SELL_ORDERS_VOLUME);
|
|||
|
case MBOOK_OPEN_INTEREST:
|
|||
|
return SymbolInfoDouble(m_symbol, SYMBOL_SESSION_INTEREST);
|
|||
|
}
|
|||
|
return 0.0;
|
|||
|
}
|
|||
|
//#define DEBUG
|
|||
|
bool print_book = true;
|
|||
|
#ifdef DEBUG
|
|||
|
int total = InfoGetInteger(MBOOK_DEPTH_ASK);
|
|||
|
for(int i = 0; i < total; i++)
|
|||
|
{
|
|||
|
string p = DoubleToString(MarketBook[i].price, 0);
|
|||
|
string v = (string)MarketBook[i].volume;
|
|||
|
printf((string)i+ " " + p + " " + v + " " + EnumToString(MarketBook[i].type));
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
//| Get deviation value by volume. Return 0.0 if deviation is |
|
|||
|
//| infinity (insufficient liquidity) |
|
|||
|
//+------------------------------------------------------------------+
|
|||
|
double CMarketBook::GetDeviationByVol(long vol, ENUM_MBOOK_SIDE side)
|
|||
|
{
|
|||
|
if(ArraySize(MarketBook) == 0)return 0.0;
|
|||
|
int best_ask = (int)InfoGetInteger(MBOOK_BEST_ASK_INDEX);
|
|||
|
int last_ask = (int)InfoGetInteger(MBOOK_LAST_ASK_INDEX);
|
|||
|
int best_bid = (int)InfoGetInteger(MBOOK_BEST_BID_INDEX);
|
|||
|
int last_bid = (int)InfoGetInteger(MBOOK_LAST_BID_INDEX);
|
|||
|
double avrg_price = 0.0;
|
|||
|
long volume_exe = vol;
|
|||
|
if(side == MBOOK_ASK)
|
|||
|
{
|
|||
|
for(int i = best_ask; i >= last_ask; i--)
|
|||
|
{
|
|||
|
long currVol = MarketBook[i].volume < volume_exe ?
|
|||
|
MarketBook[i].volume : volume_exe ;
|
|||
|
avrg_price += currVol * MarketBook[i].price;
|
|||
|
volume_exe -= MarketBook[i].volume;
|
|||
|
if(volume_exe <= 0)break;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
for(int i = best_bid; i <= last_bid; i++)
|
|||
|
{
|
|||
|
long currVol = MarketBook[i].volume < volume_exe ?
|
|||
|
MarketBook[i].volume : volume_exe ;
|
|||
|
avrg_price += currVol * MarketBook[i].price;
|
|||
|
volume_exe -= MarketBook[i].volume;
|
|||
|
if(volume_exe <= 0)break;
|
|||
|
}
|
|||
|
}
|
|||
|
if(volume_exe > 0)
|
|||
|
return 0.0;
|
|||
|
avrg_price/= (double)vol;
|
|||
|
double deviation = 0.0;
|
|||
|
if(side == MBOOK_ASK)
|
|||
|
deviation = avrg_price - MarketBook[best_ask].price;
|
|||
|
else
|
|||
|
deviation = MarketBook[best_bid].price - avrg_price;
|
|||
|
return deviation;
|
|||
|
}
|