Login Page - Create Account

Support Board


Date/Time: Sat, 23 Nov 2024 20:51:27 +0000



Post From: ACSIL Custom Autotrading System assistance

[2024-08-06 13:38:11]
User357489 - Posts: 72
ok so this:
#include "sierrachart.h"
#include <unordered_map>
#include <chrono>

SCDLLName("Sweep Genie")

struct TradeInfo
{
std::chrono::time_point<std::chrono::steady_clock> startTime;
double startPrice;
bool tradeEntered;
int positionType; // 1 for buy, -1 for sell
bool stopMovedToBreakeven;
bool trailingStopActivated;
int stopOrderID;
};

std::unordered_map<int, TradeInfo> g_TradeInfo;

void PlaceBracketOrder(SCStudyInterfaceRef& sc, TradeInfo& tradeInfo, int positionType, int orderQuantity, double price, int stopLossTicks, int takeProfitTicks)
{
s_SCNewOrder order;
order.OrderType = SCT_ORDERTYPE_MARKET;
order.OrderQuantity = orderQuantity;
order.TimeInForce = SCT_TIF_GTC;

// Define the attached orders
order.Target1Offset = takeProfitTicks * sc.TickSize;
order.Stop1Offset = stopLossTicks * sc.TickSize;

// Set attached order types
order.AttachedOrderTarget1Type = SCT_ORDERTYPE_LIMIT;
order.AttachedOrderStop1Type = SCT_ORDERTYPE_STOP;

int result = (positionType == 1) ? sc.BuyEntry(order) : sc.SellEntry(order);
if (result > 0)
{
tradeInfo.startTime = std::chrono::steady_clock::now();
tradeInfo.startPrice = price;
tradeInfo.tradeEntered = true;
tradeInfo.positionType = positionType;
tradeInfo.stopMovedToBreakeven = false;
tradeInfo.trailingStopActivated = false;

tradeInfo.stopOrderID = order.Stop1InternalOrderID;
}
}

SCSFExport scsf_SweepGenie(SCStudyInterfaceRef sc)
{
if (sc.SetDefaults)
{
sc.GraphName = "Sweep Genie";
sc.AutoLoop = 1;

sc.Input[0].Name = "Volume Threshold";
sc.Input[0].SetInt(1000);

sc.Input[1].Name = "Order Quantity";
sc.Input[1].SetInt(1);

sc.Input[2].Name = "Stop Loss Ticks";
sc.Input[2].SetInt(10);

sc.Input[3].Name = "Take Profit Ticks";
sc.Input[3].SetInt(20);

sc.Input[4].Name = "Trailing Stop Offset Ticks";
sc.Input[4].SetInt(5);

return;
}

int volumeThreshold = sc.Input[0].GetInt();
int orderQuantity = sc.Input[1].GetInt();
int stopLossTicks = sc.Input[2].GetInt();
int takeProfitTicks = sc.Input[3].GetInt();
int trailingStopOffsetTicks = sc.Input[4].GetInt();

SCDateTime currentTime = sc.CurrentSystemDateTime;

auto& tradeInfo = g_TradeInfo[sc.ChartNumber];

s_SCPositionData positionData;
sc.GetTradePosition(positionData);
int currentPosition = positionData.PositionQuantity;

double currentPrice = sc.Close[sc.ArraySize - 1];

bool buyConditionMet = false;
bool sellConditionMet = false;

double bidMboOrderSum = 0;
double askMboOrderSum = 0;

// Check top 5 bid levels
for (int level = 0; level < 5; ++level)
{
s_MarketDepthEntry bidDepthEntry; // Default initialization

if (sc.GetBidMarketDepthEntryAtLevel(bidDepthEntry, level))
{
const s_VolumeAtPriceV2* volumeAtPrice = nullptr;
int priceInTicks = sc.PriceValueToTicks(bidDepthEntry.Price);
unsigned int unusedVar; // An unused variable to meet the function signature

if (sc.VolumeAtPriceForBars->GetVAPElementForPriceIfExists(sc.ArraySize - 1, priceInTicks, &volumeAtPrice, unusedVar))
{
double bidPullingStacking = sc.GetBidMarketDepthStackPullValueAtPrice(bidDepthEntry.Price);
if (bidPullingStacking >= volumeThreshold && volumeAtPrice->AskVolume > volumeAtPrice->BidVolume)
{
buyConditionMet = true;
}
}
}
}

// Check top 5 ask levels
for (int level = 0; level < 5; ++level)
{
s_MarketDepthEntry askDepthEntry; // Default initialization

if (sc.GetAskMarketDepthEntryAtLevel(askDepthEntry, level))
{
const s_VolumeAtPriceV2* volumeAtPrice = nullptr;
int priceInTicks = sc.PriceValueToTicks(askDepthEntry.Price);
unsigned int unusedVar; // An unused variable to meet the function signature

if (sc.VolumeAtPriceForBars->GetVAPElementForPriceIfExists(sc.ArraySize - 1, priceInTicks, &volumeAtPrice, unusedVar))
{
double askPullingStacking = sc.GetAskMarketDepthStackPullValueAtPrice(askDepthEntry.Price);
if (askPullingStacking >= volumeThreshold && volumeAtPrice->BidVolume > volumeAtPrice->AskVolume)
{
sellConditionMet = true;
}
}
}
}

// Final conditions: Only enter a trade if MBO conditions are also met
if (buyConditionMet && bidMboOrderSum > askMboOrderSum)
{
PlaceBracketOrder(sc, tradeInfo, 1, orderQuantity, currentPrice, stopLossTicks, takeProfitTicks);
}
else if (sellConditionMet && askMboOrderSum > bidMboOrderSum)
{
PlaceBracketOrder(sc, tradeInfo, -1, orderQuantity, currentPrice, stopLossTicks, takeProfitTicks);
}

// Exit conditions and trailing stop management
if (tradeInfo.tradeEntered)
{
double stopLossPrice = tradeInfo.startPrice - (tradeInfo.positionType * stopLossTicks * sc.TickSize);
double takeProfitPrice = tradeInfo.startPrice + (tradeInfo.positionType * takeProfitTicks * sc.TickSize);
double trailingStopTriggerPrice = tradeInfo.startPrice + (tradeInfo.positionType * takeProfitTicks * 0.7 * sc.TickSize);

if ((tradeInfo.positionType == 1 && (currentPrice <= stopLossPrice || currentPrice >= takeProfitPrice)) ||
(tradeInfo.positionType == -1 && (currentPrice >= stopLossPrice || currentPrice <= takeProfitPrice)))
{
sc.FlattenAndCancelAllOrders();
tradeInfo.tradeEntered = false;
tradeInfo.positionType = 0;
}
else if (!tradeInfo.trailingStopActivated && tradeInfo.stopOrderID > 0 &&
((tradeInfo.positionType == 1 && currentPrice >= trailingStopTriggerPrice) ||
(tradeInfo.positionType == -1 && currentPrice <= trailingStopTriggerPrice)))
{
tradeInfo.trailingStopActivated = true;

s_SCNewOrder modifyOrder;
modifyOrder.InternalOrderID = tradeInfo.stopOrderID;
modifyOrder.Price1 = tradeInfo.startPrice + (tradeInfo.positionType * trailingStopOffsetTicks * sc.TickSize);

int modifyResult = sc.ModifyOrder(modifyOrder);
if (modifyResult == 1)
{
SCString message;
message.Format("Trailing stop activated at price: %f", modifyOrder.Price1);
sc.AddMessageToLog(message, 0);
}
else
{
SCString message;
message.Format("Failed to modify stop order for trailing stop. Error: %d", modifyResult);
sc.AddMessageToLog(message, 1);
}
}

// Manage Breakeven Stop Logic
if (!tradeInfo.stopMovedToBreakeven && tradeInfo.positionType != 0)
{
double breakevenPrice = tradeInfo.startPrice;
if ((tradeInfo.positionType == 1 && currentPrice >= breakevenPrice) ||
(tradeInfo.positionType == -1 && currentPrice <= breakevenPrice))
{
s_SCNewOrder modifyOrder;
modifyOrder.InternalOrderID = tradeInfo.stopOrderID;
modifyOrder.Price1 = breakevenPrice;

int modifyResult = sc.ModifyOrder(modifyOrder);
if (modifyResult == 1)
{
tradeInfo.stopMovedToBreakeven = true;
SCString message;
message.Format("Stop moved to breakeven at price: %f", modifyOrder.Price1);
sc.AddMessageToLog(message, 0);
}
else
{
SCString message;
message.Format("Failed to modify stop order to breakeven. Error: %d", modifyResult);
sc.AddMessageToLog(message, 1);
}
}
}

} // End of trade management logic

return;
}
, now only seems to return issues with VAP, so i think Market depth may have been solved (THANKYOU SO FAR! lifesaver)

-- Starting remote build of Custom Studies Source files: sweepgeniehelp1.cpp. 64-bit -- 14:37:12

Allow time for the server to compile the files and build the DLL.

Server: https://build2.sierrachart.com
The remote build is complete.
The build failed.
sweepgeniehelp1.cpp: In function 'void scsf_SweepGenie(SCStudyInterfaceRef)':
sweepgeniehelp1.cpp:107:104: error: invalid conversion from 'const s_VolumeAtPriceV2**' to 's_VolumeAtPriceV2**' [-fpermissive]
107 | if (sc.VolumeAtPriceForBars->GetVAPElementForPriceIfExists(sc.ArraySize - 1, priceInTicks, &volumeAtPrice, unusedVar))
| ^~~~~~~~~~~~~~
| |
| const s_VolumeAtPriceV2**
In file included from scstructures.h:108,
from sierrachart.h:22,
from sweepgeniehelp1.cpp:1:
VAPContainer.h:633:21: note: initializing argument 3 of 'bool c_VAPContainerBase<t_VolumeAtPrice>::GetVAPElementForPriceIfExists(unsigned int, int, t_VolumeAtPrice**, unsigned int&) [with t_VolumeAtPrice = s_VolumeAtPriceV2]'
633 | , t_VolumeAtPrice** p_VAP
| ~~~~~~~~~~~~~~~~~~^~~~~
sweepgeniehelp1.cpp:129:104: error: invalid conversion from 'const s_VolumeAtPriceV2**' to 's_VolumeAtPriceV2**' [-fpermissive]
129 | if (sc.VolumeAtPriceForBars->GetVAPElementForPriceIfExists(sc.ArraySize - 1, priceInTicks, &volumeAtPrice, unusedVar))
| ^~~~~~~~~~~~~~
| |
| const s_VolumeAtPriceV2**
In file included from scstructures.h:108,
from sierrachart.h:22,
from sweepgeniehelp1.cpp:1:
VAPContainer.h:633:21: note: initializing argument 3 of 'bool c_VAPContainerBase<t_VolumeAtPrice>::GetVAPElementForPriceIfExists(unsigned int, int, t_VolumeAtPrice**, unsigned int&) [with t_VolumeAtPrice = s_VolumeAtPriceV2]'
633 | , t_VolumeAtPrice** p_VAP
| ~~~~~~~~~~~~~~~~~~^~~~~


-- End of Build -- 14:37:16