Swaper_1.1
Download scriptThis script is designed to manage trading positions by balancing the portfolio's "fair value" against current market conditions. It functions as an automated management system that monitors your open trades, calculates your financial standing, and attempts to keep your account balanced between buy and sell positions.
Core Logic Overview
1. Financial Tracking and Portfolio Balancing The script begins by scanning your trading history and current open positions. It calculates a "money" value by looking at previous closed trades (profit or loss) and combining that with the value of your currently active trades. It specifically tracks the total volume of your buys versus your sells to determine your current exposure.
2. Identifying "Fair Value" The system identifies what it considers the "fair value" of your portfolio. It does this by comparing your current financial standing against the total volume of your positions. This calculation helps the script understand if you are currently over-exposed in one direction (too many buys or too many sells) relative to your available capital and previous performance.
3. Automated Trade Adjustment Based on the "fair value" calculation, the script makes real-time decisions to balance the account:
- Closing Positions: If the script detects that a position is contributing to an imbalance, it will attempt to close part of that position (either a buy or a sell) to bring the account back toward its target state.
- Opening New Positions: If the account is imbalanced but lacks an opposing position to offset the risk, the script can automatically open new trades in the opposite direction.
4. Safety and Margin Management Before opening any new trades, the script includes a safety check. It calculates how much "free margin" (available cash) you have left. If the capital required for a trade exceeds your available funds, it will automatically adjust the trade size down to the maximum amount your account can safely handle at that moment.
5. Synchronization and Timing To prevent the script from overwhelming the trading server with constant commands, it operates on a timed cycle. It checks the market once per candle (time bar) and incorporates short "sleep" periods between actions. This ensures the execution is orderly and reduces the risk of conflicts during rapid price movements.
Summary of Behavior
Instead of just entering trades based on simple signals, this script acts as a portfolio balancer. It constantly asks: "Is my current balance of buys and sells balanced against my history and available money?" If the answer is no, it automatically trims oversized positions or adds offsetting positions to maintain equilibrium.
//+------------------------------------------------------------------+
//| Swaper_1.1.mq4 |
//| Copyright © 2007, Yury V. Reshetov |
//| http://reshetov.xnet.uz |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, Yury V. Reshetov"
#property link "http://reshetov.xnet.uz"
//---- input parameters
extern double experts = 1;
extern double beginPrice = 1.8014;
extern int magicnumber = 777;
static int prevtime = 0;
static double bl = 1000;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
return(0);
}
//+------------------------------------------------------------------+
//| expert start function |
//+------------------------------------------------------------------+
int start()
{
if(Time[0] == prevtime)
return(0);
prevtime = Time[0];
if(!IsTradeAllowed())
{
prevtime = Time[1];
return(0);
}
//----
int total = OrdersHistoryTotal();
double money = bl * beginPrice;
int i = 0;
for (i = 0; i < total; i++)
{
OrderSelect(i, SELECT_BY_POS, MODE_HISTORY);
if(OrderSymbol() == Symbol() && OrderMagicNumber() == magicnumber)
{
if(OrderType() == OP_BUY)
{
money = money + (OrderClosePrice() -
OrderOpenPrice()) * 10 * OrderLots();
}
else
{
money = money - (OrderClosePrice() -
OrderOpenPrice()) * 10 * OrderLots();
}
}
}
total = OrdersTotal();
double com = bl;
int tickbuy = -1;
double buyvolume = 0;
int ticksell = -1;
double sellvolume = 0;
for(i = 0; i < total; i++)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderMagicNumber() == magicnumber)
{
if(OrderType() == OP_BUY)
{
if(OrderSymbol() == Symbol())
{
money = money - 10 * buyvolume * OrderOpenPrice();
if ((MarketInfo(Symbol(), MODE_SWAPLONG) < 0) || (AccountFreeMargin() < 0 && OrderProfit() < 0)) {
buyvolume = OrderLots();
tickbuy = OrderTicket();
}
}
com = com + 10 * OrderLots();
}
else
{
if(OrderSymbol() == Symbol())
{
money = money + 10 * sellvolume * OrderOpenPrice();
if ((MarketInfo(Symbol(), MODE_SWAPSHORT) < 0) || (AccountFreeMargin() < 0 && OrderProfit() < 0)) {
sellvolume = OrderLots();
ticksell = OrderTicket();
}
}
com = com - 10 * OrderLots();
}
}
}
double fv = money / com;
Comment("Fair value ", fv);
if(! IsTradeAllowed())
{
prevtime = Time[1];
return(0);
}
closeby(ticksell, tickbuy);
if(!IsTradeAllowed())
{
prevtime = Time[1];
return(0);
}
double lots = 0;
double price = 0;
double dt = (money / (MathMax(High[1], High[0]) + MarketInfo(Symbol(), MODE_SPREAD) * Point) - com) * experts / (experts + 1);
if(dt < 0)
{
dt = (com - money / MathMin(Low[1], Low[0])) * experts / (experts + 1);
if(dt < 1)
{
closeby(tickbuy, ticksell);
return(0);
}
lots = MathFloor(dt) / 10;
if(tickbuy >= 0)
{
if(buyvolume > lots)
{
OrderClose(tickbuy, lots, Bid, 3, Blue);
Sleep(30000);
}
else
{
OrderClose(tickbuy, buyvolume, Bid, 3, Blue);
tickbuy = -1;
Sleep(30000);
}
}
else
{
lots = getLots(lots);
if(lots > 0)
{
ticksell = OrderSend(Symbol(), OP_SELL, lots, Bid, 3,
0, 0, "Swaper", magicnumber, 0, Red);
Sleep(30000);
}
}
}
else
{
if(dt < 1)
{
closeby(ticksell, tickbuy);
return(0);
}
lots = MathFloor(dt) / 10;
if(ticksell >= 0)
{
if(sellvolume > lots)
{
OrderClose(ticksell, lots, Ask, 3, Red);
Sleep(30000);
}
else
{
OrderClose(ticksell, sellvolume, Ask, 3, Red);
ticksell = -1;
Sleep(30000);
}
}
else
{
lots = getLots(lots);
if(lots > 0)
{
tickbuy = OrderSend(Symbol(), OP_BUY, lots, Ask, 3, 0,
0, "Swaper", magicnumber, 0, Blue);
Sleep(30000);
}
}
}
//----
if(!IsTradeAllowed())
{
prevtime = Time[1];
return(0);
}
closeby(tickbuy, ticksell);
//----
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void closeby(int sell, int buy)
{
if(sell >= 0 && buy >= 0)
{
OrderCloseBy(buy, sell, Green);
Sleep(30000);
}
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
double getLots(double lt)
{
double marginrequired = MarketInfo(Symbol(), MODE_MARGINREQUIRED);
double freemargin = AccountFreeMargin();
if(freemargin > (marginrequired * lt))
{
return(lt);
}
double result = freemargin / marginrequired;
result = MathFloor(result * 10) / 10;
return(result);
}
//+------------------------------------------------------------------+
Profitability Reports
Expected payoff
Average expected payoff across the available backtests for each symbol.
Comments