Skip to content

Instantly share code, notes, and snippets.

@botany02
Last active November 21, 2024 02:12
Show Gist options
  • Save botany02/c74a7b8b45a0b998671f11c7491a4737 to your computer and use it in GitHub Desktop.
Save botany02/c74a7b8b45a0b998671f11c7491a4737 to your computer and use it in GitHub Desktop.
Backtest Template for AmiBroker
/*
Backtest Template for Stocks AND Futures
Coded by ChokS
https://howutrade.in
Platform: AmiBroker/AFL
Features:
Commission Calculation (close to real brokerage)
Support for Stocks and Futures
Note:
Your AFL code should generate valid signals for correct backtest
Make sure you correctly assigned BuyPrice/SellPrice/ShortPrice/CoverPrice
Always do Simple backtest to assess the trading system and to see the true value of the strategy
*/
_SECTION_BEGIN("Common_Params");
GfxSetBkMode(0);
GfxSelectFont("Cambria", 12, 700, False);
GfxSetTextColor(colorWhite);
IsFutureMode = ParamToggle("Backtest Mode", "Stocks|Futures", 0);
IsCompound = ParamToggle("Backtest Type", "Simple|Compound", 0);
Capital = Param("Capital", 500000, 10000, 5000000, 100);
TkSize = Param("Tick Size", 0.05, 0.01, 500, 0.01);
IsApplyBrokerage = ParamToggle("Apply Brokerage?", "No|Yes", 1);
_SECTION_END();
_SECTION_BEGIN("Stock_Params");
Leverage = Param("Leverage", 10, 1, 50, 1); //1 = No Leverage
MaxPositions = Param("Max Open Positions", 1, 1, 500, 1);
_SECTION_END();
_SECTION_BEGIN("Future_Params");
LtSize = Param("Lot Size", 75, 1, 50000, 1);
MarginPerLot = Param("Margin Per Lot", 65000, 0, 5000000, 1);
_SECTION_END();
_SECTION_BEGIN("Backtest_Module");
DayOpen = TimeFrameGetPrice("O", inDaily, 0, expandFirst);//To workout Quantity for Stocks
PositionValue = (Capital * Leverage)/MaxPositions; //Workout Position Value
TradeQty = floor(PositionValue/DayOpen); //For Stocks
//If FutureMode
if(IsFutureMode){
MaxPositions = 1; //For Future, we will be doing single backtest
Leverage = 1; //Remove Leverage
TradeQty = floor(Capital/MarginPerLot); //Workout Lots
} else {
LtSize = 1; //Reset LotSize to 1
}
//Charges
SttPct = 0.00025;ExchPct = 0.0000325;StampPct = 0.00003;if(IsFutureMode){SttPct = 0.0001;ExchPct = 0.000019;StampPct = 0.00002;}SamplePrice = 500;SampleQty = 1000;
Brkg = 20;GstPct = 0.18;SebiPct = 0.0000005;Turnover = SampleQty * SamplePrice * 2;Revenue = SampleQty * SamplePrice;TotalBrkg = Brkg * 2;TransChgs = Turnover * ExchPct;
SebiChgs = Turnover * SebiPct;TotalChgs = (Revenue * SttPct) + (Revenue * StampPct) + TransChgs + SebiChgs + (TransChgs * GstPct);CommPct = (TotalChgs/Revenue) * 100;CommPct = (ceil((CommPct / 0.001)) * 0.001)/2;
if (!IsApplyBrokerage){CommPct = 0;}
//Defaults
MinShares = 1;
RoundLotSize = LtSize;
TickSize = TkSize;
if(IsFutureMode){MarginDeposit = MarginPerLot/LtSize;PointValue = 1;}
SetOption("InitialEquity", Capital);
SetOption("MaxOpenPositions", MaxPositions);
SetOption("MinShares", MinShares);
SetOption("CommissionMode", 1);
SetOption("CommissionAmount", CommPct);
SetOption("AccountMargin", 100/Leverage);
SetOption("AllowSameBarExit", False);
SetOption("ReverseSignalForcesExit", False);
SetOption("FuturesMode", IsFutureMode);
SetOption("PortfolioReportMode", 0);
SetOption("AllowPositionShrinking", False);
if (IsCompound) {
if(IsFutureMode) {
SetPositionSize(100, spsPercentOfEquity);
} else {
SetPositionSize(1000/MaxPositions, spsPercentOfEquity);
}
} else {
SetPositionSize(TradeQty * LtSize, spsShares);
}
GfxTextOut("Capital: " + NumToStr(Capital,1.0) , 5,180);
GfxTextOut("Comission Percent: " + NumToStr(CommPct/2,1.2) , 5,200);
GfxTextOut("TradeQty: " + NumToStr(TradeQty, 1.0) , 5,220);
GfxTextOut("LotSize: " + NumToStr(LtSize,1.0) , 5,240);
GfxTextOut("Margin Per Lot: " + NumToStr(MarginPerLot,1.0) , 5,260);
_SECTION_END();
@MSurenBabu
Copy link

Thanks for sharing. Appreciate it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment