Bot Code Example: Difference between revisions

From SharpTrader Arbitrage Software Wiki: A Detailed Overview of High-Speed Trading Technology
Jump to navigation Jump to search
Created page with "==== MACD Bot Example ==== using System; using System.Collections.Generic; using Skender.Stock.Indicators; using System.Linq; using SharpTraderBot; namespace SharpTraderArb.Strategies {     public class MACDBot: Bot     {         //input parameters         [PropertyInfo("EURUSD", "Trading symbol")]                public string Symbol {get;set;} = "EURUSD";         [PropertyInfo(TimeFrame.M30, "Timeframe")]                p..."
 
Formatting cleanup: section headings, parameter definition lists, whitespace
Line 1: Line 1:
==== MACD Bot Example ====
==== MACD Bot Example ====


using System;
using System;
Line 16: Line 15:
{
{


    public class MACDBot: Bot
public class MACDBot: Bot


    {
{


        //input parameters
//input parameters


        [PropertyInfo("EURUSD", "Trading symbol")]       
[PropertyInfo("EURUSD", "Trading symbol")]


        public string Symbol {get;set;} = "EURUSD";
public string Symbol {get;set;} = "EURUSD";


        [PropertyInfo(TimeFrame.M30, "Timeframe")]       
[PropertyInfo(TimeFrame.M30, "Timeframe")]


        public TimeFrame Period {get;set;} =  TimeFrame.M30;
public TimeFrame Period {get;set;} =  TimeFrame.M30;


        [PropertyInfo(50, "Take profit")]       
[PropertyInfo(50, "Take profit")]


        public double TakeProfit {get;set;} = 50;
public double TakeProfit {get;set;} = 50;


        [PropertyInfo(0.1, "Lot size")]               
[PropertyInfo(0.1, "Lot size")]


        public double Lots {get;set;} = 0.1;
public double Lots {get;set;} = 0.1;


        [PropertyInfo(30, "Trailing stop")]               
[PropertyInfo(30, "Trailing stop")]


        public double TrailingStop {get;set;} = 30;
public double TrailingStop {get;set;} = 30;


        [PropertyInfo(3, "MACD open level")]                       
[PropertyInfo(3, "MACD open level")]


        public double MACDOpenLevel {get;set;} = 3;
public double MACDOpenLevel {get;set;} = 3;


        [PropertyInfo(2, "MACD close level")]               
[PropertyInfo(2, "MACD close level")]


        public double MACDCloseLevel {get;set;} = 2;
public double MACDCloseLevel {get;set;} = 2;


        [PropertyInfo(30, "Moving average period")]                       
[PropertyInfo(30, "Moving average period")]


        public int    MATrendPeriod {get;set;} = 26;
public int    MATrendPeriod {get;set;} = 26;


       
//internal variables


        //internal variables
string positionID = "";


        string positionID = "";
double pointValue = 1e-5;


        double pointValue = 1e-5;
double bid,ask;


        double bid,ask;
string clienOrderId = "";


        string clienOrderId = "";  
public override void OnInit()


        public override void OnInit()
{


        {
pointValue = ticker.getPointValue(0, Symbol);


            pointValue = ticker.getPointValue(0, Symbol);
//check for opened position


            //check for opened position
STPosition buyPosition  = getPositionByComment("MACD_buy", 0);


            STPosition buyPosition  = getPositionByComment("MACD_buy", 0);
if (buyPosition != null)


           
positionID = buyPosition.PositionId;


            if (buyPosition != null)
STPosition sellPosition  = getPositionByComment("MACD_sell", 0);


               positionID = buyPosition.PositionId;
if (sellPosition != null)


            STPosition sellPosition  = getPositionByComment("MACD_sell", 0);
positionID = sellPosition.PositionId;


           
}


            if (sellPosition != null)
public override void OnDeinit()


               positionID = sellPosition.PositionId;
{


        }
}


        public override void OnDeinit()
public override void OnTick(NewTickEventArgs args)


        {
{


        }
if (clienOrderId != "") // order is already processing, exit


        public override void OnTick(NewTickEventArgs args)
return;


        {
if (ticker.getSymbolName(0,Symbol) != args.tick.symbol)//tick on another symbol


           if (clienOrderId != "") // order is already processing, exit
return;


              return;
double MacdCurrent,MacdPrevious;


           if (ticker.getSymbolName(0,Symbol) != args.tick.symbol)//tick on another symbol
double SignalCurrent,SignalPrevious;


              return;
double MaCurrent,MaPrevious;


           double MacdCurrent,MacdPrevious;
var MACDmain  = indicators.iMACD(0, Symbol,Period,PriceUsed.Close,MACDMode.Main);


           double SignalCurrent,SignalPrevious;
if (MACDmain == null)


           double MaCurrent,MaPrevious;
{


           var MACDmain  = indicators.iMACD(0, Symbol,Period,PriceUsed.Close,MACDMode.Main);
stopBot();


            if (MACDmain == null)
return;


            {  
}


                stopBot();
MacdCurrent = (double)MACDmain[0];


                return;
MacdPrevious = (double)MACDmain[1];


            }
var MACDsignal  = indicators.iMACD(0, Symbol,Period,PriceUsed.Close,MACDMode.Signal);


            MacdCurrent = (double)MACDmain[0];
if (MACDsignal == null)


            MacdPrevious = (double)MACDmain[1];
{


            var MACDsignal  = indicators.iMACD(0, Symbol,Period,PriceUsed.Close,MACDMode.Signal);           
stopBot();


           
return;


            if (MACDsignal == null)   
}


            {  
SignalCurrent = (double)MACDsignal[0];


                stopBot();
SignalPrevious = (double)MACDsignal[1];


                return;
var MA = indicators.iEMA(0,Symbol,Period,PriceUsed.Close,MATrendPeriod);


            }
if (MA == null)


            SignalCurrent = (double)MACDsignal[0];
{


            SignalPrevious = (double)MACDsignal[1];
stopBot();


           
return;


            var MA = indicators.iEMA(0,Symbol,Period,PriceUsed.Close,MATrendPeriod);
}


           
MaCurrent = (double)MA[0];


            if (MA == null)   
MaPrevious = (double)MA[1];


            {  
bid = ticker.getBid(0, Symbol);


                stopBot();
ask = ticker.getAsk(0, Symbol);


                return;
//writeLog(bid.ToString());


            }
if(positionID == "")// no opened positions - check for entry condition


            MaCurrent = (double)MA[0];
{


            MaPrevious = (double)MA[1];
writeLog("Time to buy!");


           bid = ticker.getBid(0, Symbol);
clienOrderId = sendOrder(0,Symbol,Lots, OrderSide.BUY,OrderType.MARKET, ask,"MACD_buy");


           ask = ticker.getAsk(0, Symbol);
return;


         
}


        //writeLog(bid.ToString());
else // we have opened position


       if(positionID == "")// no opened positions - check for entry condition
{


       {
STPosition position = getPositionByID(positionID);


             writeLog("Time to buy!");   
if (position == null)// this position is already closed


             clienOrderId = sendOrder(0,Symbol,Lots, OrderSide.BUY,OrderType.MARKET, ask,"MACD_buy");
{


             return;
positionID = "";


       }
return;


        else // we have opened position
}


        {
if(position.side == OrderSide.BUY)//we have buy position opened


           STPosition position = getPositionByID(positionID);
{


           if (position == null)// this position is already closed
//setting position take profit value (if not set)


            {
if (position.takeProfit == 0)


                positionID = "";             
modifyPositionByID(positionID, position.stopLoss, position.openPrice + TakeProfit * pointValue);


                return;
//--- checking closing conditions


            }
if(MacdCurrent > 0 && MacdCurrent < SignalCurrent && MacdPrevious > SignalPrevious && MacdCurrent>(MACDCloseLevel * pointValue))


 
{


           if(position.side == OrderSide.BUY)//we have buy position opened
clienOrderId = closePositionByID(positionID);


           {
return;


            //setting position take profit value (if not set)
}


            if (position.takeProfit == 0)
//--- perform trailing


                modifyPositionByID(positionID, position.stopLoss, position.openPrice + TakeProfit * pointValue);
if(TrailingStop > 0)


            //--- checking closing conditions
{


            if(MacdCurrent > 0 && MacdCurrent < SignalCurrent && MacdPrevious > SignalPrevious && MacdCurrent>(MACDCloseLevel * pointValue))
if(bid - position.openPrice > pointValue * TrailingStop)


              {
{


                clienOrderId = closePositionByID(positionID);
if(position.stopLoss < bid-pointValue * TrailingStop)


                return;   
{


              }
modifyPositionByID(positionID, bid-pointValue * TrailingStop, position.takeProfit);


            //--- perform trailing
return;


            if(TrailingStop > 0)
}


              {
}


               if(bid - position.openPrice > pointValue * TrailingStop)
}


                 {
}


                  if(position.stopLoss < bid-pointValue * TrailingStop)
else //we have sell position opened


                    {
{


                     modifyPositionByID(positionID, bid-pointValue * TrailingStop, position.takeProfit);
if (position.takeProfit == 0)


                     return;
modifyPositionByID(positionID, position.stopLoss, position.openPrice - TakeProfit * pointValue);


                    }
//--- checking closing conditions


                 }
if(MacdCurrent < 0 && MacdCurrent > SignalCurrent && MacdPrevious < SignalPrevious && Math.Abs(MacdCurrent) > (MACDCloseLevel * pointValue))


              }
{


           }
return;


         else //we have sell position opened
}


           {
//--- check for trailing stop


            //setting position take profit value (if not set)
if(TrailingStop > 0)


            if (position.takeProfit == 0)
{


                modifyPositionByID(positionID, position.stopLoss, position.openPrice - TakeProfit * pointValue);
if((position.openPrice - ask) > (pointValue * TrailingStop))


            //--- checking closing conditions
{


            if(MacdCurrent < 0 && MacdCurrent > SignalCurrent && MacdPrevious < SignalPrevious && Math.Abs(MacdCurrent) > (MACDCloseLevel * pointValue))
if((position.stopLoss > (ask + pointValue * TrailingStop)) || (position.stopLoss == 0))


              {
{


               clienOrderId = closePositionByID(positionID);
modifyPositionByID(positionID, ask + pointValue * TrailingStop, position.takeProfit);


               return;
return;


              }
}


            //--- check for trailing stop
}


            if(TrailingStop > 0)
}


              {
}


               if((position.openPrice - ask) > (pointValue * TrailingStop))
}


                 {
}


                  if((position.stopLoss > (ask + pointValue * TrailingStop)) || (position.stopLoss == 0))
public override void OnPositionOpened(PositionOpenedEventArgs args)


                    {
{


                      modifyPositionByID(positionID, ask + pointValue * TrailingStop, position.takeProfit);
writeLog($"Position {args.position.PositionId} was opened");


                      return;
clienOrderId = "";


                    }
positionID = args.position.PositionId;


                 }
}


              }
public override void OnPositionClosed(PositionClosedEventArgs args)


           }
{


        }
writeLog($"Position {args.position.PositionId} was closed");


        }
positionID = "";


        public override void OnPositionOpened(PositionOpenedEventArgs args)
clienOrderId = "";


        {
}


                writeLog($"Position {args.position.PositionId} was opened");
public virtual void OnOrderStatusUpdate(STOrder order)


                clienOrderId = "";
{


                positionID = args.position.PositionId;
if (order.clientOrderId == clienOrderId && (order.status == OrderStatus.CANCELED || order.status == OrderStatus.REJECTED))


        }
{
 
        public override void OnPositionClosed(PositionClosedEventArgs args)
 
        {
 
                writeLog($"Position {args.position.PositionId} was closed");
 
                positionID = "";
 
                clienOrderId = "";
 
        }
 
        public virtual void OnOrderStatusUpdate(STOrder order)
 
        {
 
            if (order.clientOrderId == clienOrderId && (order.status == OrderStatus.CANCELED || order.status == OrderStatus.REJECTED))
 
            {


               writeLog($"Order {clienOrderId} was rejected with reason {order.comment}");
writeLog($"Order {clienOrderId} was rejected with reason {order.comment}");


               clienOrderId = "";
clienOrderId = "";


            }
}


        }
}


    }
}


}
}

Revision as of 19:46, 21 October 2026

MACD Bot Example

using System;

using System.Collections.Generic;

using Skender.Stock.Indicators;

using System.Linq;

using SharpTraderBot;

namespace SharpTraderArb.Strategies

{

public class MACDBot: Bot

{

//input parameters

[PropertyInfo("EURUSD", "Trading symbol")]

public string Symbol {get;set;} = "EURUSD";

[PropertyInfo(TimeFrame.M30, "Timeframe")]

public TimeFrame Period {get;set;} =  TimeFrame.M30;

[PropertyInfo(50, "Take profit")]

public double TakeProfit {get;set;} = 50;

[PropertyInfo(0.1, "Lot size")]

public double Lots {get;set;} = 0.1;

[PropertyInfo(30, "Trailing stop")]

public double TrailingStop {get;set;} = 30;

[PropertyInfo(3, "MACD open level")]

public double MACDOpenLevel {get;set;} = 3;

[PropertyInfo(2, "MACD close level")]

public double MACDCloseLevel {get;set;} = 2;

[PropertyInfo(30, "Moving average period")]

public int    MATrendPeriod {get;set;} = 26;

//internal variables

string positionID = "";

double pointValue = 1e-5;

double bid,ask;

string clienOrderId = "";

public override void OnInit()

{

pointValue = ticker.getPointValue(0, Symbol);

//check for opened position

STPosition buyPosition  = getPositionByComment("MACD_buy", 0);

if (buyPosition != null)

positionID = buyPosition.PositionId;

STPosition sellPosition  = getPositionByComment("MACD_sell", 0);

if (sellPosition != null)

positionID = sellPosition.PositionId;

}

public override void OnDeinit()

{

}

public override void OnTick(NewTickEventArgs args)

{

if (clienOrderId != "") // order is already processing, exit

return;

if (ticker.getSymbolName(0,Symbol) != args.tick.symbol)//tick on another symbol

return;

double MacdCurrent,MacdPrevious;

double SignalCurrent,SignalPrevious;

double MaCurrent,MaPrevious;

var MACDmain  = indicators.iMACD(0, Symbol,Period,PriceUsed.Close,MACDMode.Main);

if (MACDmain == null)

{

stopBot();

return;

}

MacdCurrent = (double)MACDmain[0];

MacdPrevious = (double)MACDmain[1];

var MACDsignal  = indicators.iMACD(0, Symbol,Period,PriceUsed.Close,MACDMode.Signal);

if (MACDsignal == null)

{

stopBot();

return;

}

SignalCurrent = (double)MACDsignal[0];

SignalPrevious = (double)MACDsignal[1];

var MA = indicators.iEMA(0,Symbol,Period,PriceUsed.Close,MATrendPeriod);

if (MA == null)

{

stopBot();

return;

}

MaCurrent = (double)MA[0];

MaPrevious = (double)MA[1];

bid = ticker.getBid(0, Symbol);

ask = ticker.getAsk(0, Symbol);

//writeLog(bid.ToString());

if(positionID == "")// no opened positions - check for entry condition

{

writeLog("Time to buy!");

clienOrderId = sendOrder(0,Symbol,Lots, OrderSide.BUY,OrderType.MARKET, ask,"MACD_buy");

return;

}

else // we have opened position

{

STPosition position = getPositionByID(positionID);

if (position == null)// this position is already closed

{

positionID = "";

return;

}

if(position.side == OrderSide.BUY)//we have buy position opened

{

//setting position take profit value (if not set)

if (position.takeProfit == 0)

modifyPositionByID(positionID, position.stopLoss, position.openPrice + TakeProfit * pointValue);

//--- checking closing conditions

if(MacdCurrent > 0 && MacdCurrent < SignalCurrent && MacdPrevious > SignalPrevious && MacdCurrent>(MACDCloseLevel * pointValue))

{

clienOrderId = closePositionByID(positionID);

return;

}

//--- perform trailing

if(TrailingStop > 0)

{

if(bid - position.openPrice > pointValue * TrailingStop)

{

if(position.stopLoss < bid-pointValue * TrailingStop)

{

modifyPositionByID(positionID, bid-pointValue * TrailingStop, position.takeProfit);

return;

}

}

}

}

else //we have sell position opened

{

if (position.takeProfit == 0)

modifyPositionByID(positionID, position.stopLoss, position.openPrice - TakeProfit * pointValue);

//--- checking closing conditions

if(MacdCurrent < 0 && MacdCurrent > SignalCurrent && MacdPrevious < SignalPrevious && Math.Abs(MacdCurrent) > (MACDCloseLevel * pointValue))

{

return;

}

//--- check for trailing stop

if(TrailingStop > 0)

{

if((position.openPrice - ask) > (pointValue * TrailingStop))

{

if((position.stopLoss > (ask + pointValue * TrailingStop)) || (position.stopLoss == 0))

{

modifyPositionByID(positionID, ask + pointValue * TrailingStop, position.takeProfit);

return;

}

}

}

}

}

}

public override void OnPositionOpened(PositionOpenedEventArgs args)

{

writeLog($"Position {args.position.PositionId} was opened");

clienOrderId = "";

positionID = args.position.PositionId;

}

public override void OnPositionClosed(PositionClosedEventArgs args)

{

writeLog($"Position {args.position.PositionId} was closed");

positionID = "";

clienOrderId = "";

}

public virtual void OnOrderStatusUpdate(STOrder order)

{

if (order.clientOrderId == clienOrderId && (order.status == OrderStatus.CANCELED || order.status == OrderStatus.REJECTED))

{

writeLog($"Order {clienOrderId} was rejected with reason {order.comment}");

clienOrderId = "";

}

}

}

}