Description
Example Martingale Strategy :
1. Starting the Trade
Begin trading by opening a random position (Buy or Sell).
2. Closing Current Positions
- At each new bar, the strategy will close all open positions.
- After closing a position, it will check the profit or loss of that position. If there is a profit, continue trading in the same direction. If there is a loss, reverse the trading direction and apply the Martingale strategy.
3. Adjusting Lot Size
Case 1: If the closed position is profitable
- Reset the lot size back to the initial lot size.
- Reset the consecutive loss count.
Case 2: If the closed position is at a loss
- Increase the consecutive loss count.
- If the consecutive loss count exceeds a predefined limit, apply the Martingale strategy by increasing the lot size with the Martingale multiplier.
4. Opening a New Position
Case 1: If the closed position is profitable
- Open a new position in the same direction as the previous position.
Case 2: If the closed position is at a loss
- Open a new position in the opposite direction of the previous position.
5. Randomly Determine the Direction of the Initial Position
For the initial position or if there are no open positions, randomly determine the direction of the new position (Buy or Sell).
After closing a position, it will check the profit or loss of that position. If there is a profit, continue trading in the same direction. If there is a loss, reverse the trading direction and apply the Martingale strategy
Summary
- This strategy uses the Martingale principle to increase the lot size after a loss by doubling the lot size each time a loss occurs.
- When there is a profit, it resets the lot size back to the initial lot size.
- It opens a new position every time after closing the previous position.
- For the initial position or when there are no open positions, it randomly determines the direction of the new position.
Warning: This is just sample code. It's not a ready-made strategy. you need to study other details more
**************************************** Best Broker : Fusion Markets ****************************************
using System;
using System.Threading.Tasks;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class OpenCloseMartingaleStrategy : Robot
{
[Parameter("Lot Size", DefaultValue = 0.01, MinValue = 0.01)]
public double InitialVolume { get; set; }
[Parameter("Martingale", DefaultValue = 2.0)]
public double MartingaleMultiplier { get; set; }
private double _currentVolume;
private int _consecutiveLosses = 0;
private double _initialCapital;
private double _currentCapital;
private double _lastProfitIncreaseCapital;
private TradeType _lastTradeType;
private double _lastTradeProfit;
private bool _isFirstRun = true;
private Random _random;
protected override void OnStart()
{
Print("OpenCloseMartingaleStrategy started.");
_currentVolume = InitialVolume;
// Initialize capital values
_initialCapital = Account.Balance;
_currentCapital = _initialCapital;
_lastProfitIncreaseCapital = _initialCapital;
// Initialize random
_random = new Random();
}
protected override void OnBar()
{
Print("OnBar called.");
// Update current capital
_currentCapital = Account.Balance;
Print($"Current capital: {_currentCapital}");
// Close all positions and open new one asynchronously
foreach (var position in Positions)
{
Print($"Processing position: {position.TradeType} at {position.EntryPrice}");
CloseAndOpenNewPositionAsync(position);
}
// If no positions and first run, open a new position with random direction
if (Positions.Count == 0 && _isFirstRun)
{
if (_random.Next(2) == 0)
{
Print("No open positions, opening new Buy position (random).");
OpenBuyPosition();
}
else
{
Print("No open positions, opening new Sell position (random).");
OpenSellPosition();
}
_isFirstRun = false;
return;
}
// If no positions and not first run, open a new position with random direction
if (Positions.Count == 0)
{
if (_random.Next(2) == 0)
{
Print("No open positions, opening new Buy position (random).");
OpenBuyPosition();
}
else
{
Print("No open positions, opening new Sell position (random).");
OpenSellPosition();
}
}
}
private async void CloseAndOpenNewPositionAsync(Position position)
{
Print($"Attempting to close position: {position.TradeType} at {position.EntryPrice} with profit: {position.GrossProfit}");
var closeResult = await ClosePositionAsync(position);
if (closeResult.IsSuccessful)
{
Print($"Position closed successfully: {position.TradeType} at {position.EntryPrice}");
// Check if the last trade was profitable or not
if (position.GrossProfit > 0)
{
_lastTradeType = position.TradeType;
_lastTradeProfit = position.GrossProfit;
_consecutiveLosses = 0; // Reset consecutive losses count
_currentVolume = InitialVolume;
Print("Profit occurred. Resetting volume and consecutive losses.");
}
else
{
_lastTradeType = position.TradeType;
_lastTradeProfit = position.GrossProfit;
_consecutiveLosses++;
if (_consecutiveLosses >= 1) // Fixed value since StartMartingaleAfterLosses is removed
{
// Apply Martingale
_currentVolume = Math.Round(_currentVolume * MartingaleMultiplier, 2);
Print($"Applying Martingale. New Volume: {_currentVolume}");
}
}
// Open new position based on the last trade's result
if (_lastTradeProfit > 0)
{
// Continue in the same direction if the last trade was profitable
if (_lastTradeType == TradeType.Buy)
{
OpenBuyPosition();
}
else
{
OpenSellPosition();
}
}
else
{
// Reverse direction if the last trade was not profitable
if (_lastTradeType == TradeType.Buy)
{
OpenSellPosition();
}
else
{
OpenBuyPosition();
}
}
}
else
{
Print($"Failed to close position: {position.TradeType} at {position.EntryPrice}");
}
}
private async Task<TradeResult> ClosePositionAsync(Position position)
{
var closeResult = ClosePosition(position);
while (!closeResult.IsSuccessful)
{
await Task.Delay(10); // Wait for 10ms before retrying
closeResult = ClosePosition(position);
}
return closeResult;
}
private void OpenSellPosition()
{
Print($"Opening Sell position with volume {_currentVolume}.");
var result = ExecuteMarketOrder(TradeType.Sell, SymbolName, _currentVolume, "OpenCloseMartingaleStrategy");
if (!result.IsSuccessful)
{
Print($"Error opening Sell position: {result.Error}");
}
else
{
Print("Sell position opened successfully.");
}
}
private void OpenBuyPosition()
{
Print($"Opening Buy position with volume {_currentVolume}.");
var result = ExecuteMarketOrder(TradeType.Buy, SymbolName, _currentVolume, "OpenCloseMartingaleStrategy");
if (!result.IsSuccessful)
{
Print($"Error opening Buy position: {result.Error}");
}
else
{
Print("Buy position opened successfully.");
}
}
protected override void OnStop()
{
Print("OpenCloseMartingaleStrategy stopped.");
}
}
}
TS_TRADER
Joined on 15.12.2023
- Distribution: Free
- Language: C#
- Trading platform: cTrader Automate
- File name: Martingale UpDowns Close.algo
- Rating: 3.33
- Installs: 503
- Modified: 25/07/2024 04:36
Comments
Warning: This is just sample code. It's not a ready-made strategy. you need to study other details more
nice ACADEMIC pursuit and nice coding style. It's great to see a solution that does what it says on the tin. however, I would urge folks to never use martingale in any shape or form. the statistical evidence just doesn't support its use. I would urge folks tho' to look at scaled staking based on using balance percentages and/or REDUCING exposure when/where appropriate.
this isn't a criticism on your code, which I've said is pretty neat -just the principle of martingale which i've been a vocal objector to for too many years.
Additional information: This strategy uses closing trade positions at every close of the bar instead of using TP and SL.
The bot does not work in backtest or demo account?
Am I doing something wrong?
Kind regards,
B.B.